* API: add SimpleSAMLphp for SAML/Shibboleth authentication and many more

This commit is contained in:
Ralf Becker 2020-04-14 14:10:33 +02:00
parent 655f1f1f6a
commit e3ede597dc
84 changed files with 6383 additions and 251 deletions

View File

@ -85,6 +85,47 @@ class Auth
return $backend;
}
/**
* Attempt a SSO login
*
* @return string sessionid on successful login or null
* @throws Exception\AssertionFailed
*/
static function login()
{
$backend = self::backend();
return $backend instanceof Auth\BackendSSO ? $backend->login() : null;
}
/**
* Attempt SSO logout
*
* @return null
* @throws Exception\AssertionFailed
*/
static function logout()
{
$backend = self::backend();
return $backend instanceof Auth\BackendSSO ? $backend->logout() : null;
}
/**
* Return (which) parts of session needed by current auth backend
*
* If this returns any key(s), the session is NOT destroyed by Api\Session::destroy,
* just everything but the keys is removed.
*
* @return array of needed keys in session
*/
static function needSession()
{
$backend = self::backend();
return method_exists($backend, 'needSession') ? $backend->needSession() : [];
}
/**
* check if users are supposed to change their password every x sdays, then check if password is of old age
* or the devil-admin reset the users password and forced the user to change his password on next login.

View File

@ -0,0 +1,30 @@
<?php
/**
* EGroupware API - Authentication SSO (single-sign-on) backend interface
*
* @link http://www.egroupware.org
* @author Ralf Becker <rb@egroupware.org>
* @license http://opensource.org/licenses/lgpl-license.php LGPL - GNU Lesser General Public License
* @package api
* @subpackage authentication
*/
namespace EGroupware\Api\Auth;
/**
* Interface for SSO authentication backends
*/
interface BackendSSO extends Backend
{
/**
* Attempt SSO login
*
* @return string sessionid on successful login, null otherwise
*/
function login();
/**
* Logout SSO system
*/
function logout();
}

View File

@ -6,7 +6,6 @@
* @license http://opensource.org/licenses/lgpl-license.php LGPL - GNU Lesser General Public License
* @package api
* @subpackage authentication
* @version $Id$
*/
namespace EGroupware\Api\Auth;
@ -17,10 +16,15 @@ use phpCAS;
/**
* Authentication based on CAS (Central Authetication Service)
*/
class Cas implements Backend
class Cas implements BackendSSO
{
var $previous_login = -1;
function __construct()
{
require_once('CAS/CAS.php');
}
/**
* authentication against CAS
*
@ -70,4 +74,68 @@ class Cas implements Backend
/* Not allowed */
return false;
}
/**
* Attempt SSO login
*
* @return string sessionid on successful login, null otherwise
*/
function login()
{
ob_end_clean();
//phpCAS::setDebug('/var/log/log_phpcas.php');
if($GLOBALS['egw_info']['server']['cas_authentication_mode'] == 'Proxy')
{
phpCAS::proxy(CAS_VERSION_2_0,
$GLOBALS['egw_info']['server']['cas_server_host_name'],
(int) $GLOBALS['egw_info']['server']['cas_server_port'],
$GLOBALS['egw_info']['server']['cas_server_uri'] );
}
else
{
phpCAS::client(CAS_VERSION_2_0,
$GLOBALS['egw_info']['server']['cas_server_host_name'],
(int) $GLOBALS['egw_info']['server']['cas_server_port'],
$GLOBALS['egw_info']['server']['cas_server_uri'] );
}
if($GLOBALS['egw_info']['server']['cas_ssl_validation'] == 'PEMCertificate')
{
// Set the certificate of the CAS server (PEM Certificate)
phpCAS::setCasServerCert($GLOBALS['egw_info']['server']['cas_cert']);
}
elseif($GLOBALS['egw_info']['server']['cas_ssl_validation'] == 'CACertificate')
{
// Set the CA certificate of the CAS server
phpCAS::setCasServerCACert($GLOBALS['egw_info']['server']['cas_cert']);
}
elseif($GLOBALS['egw_info']['server']['cas_ssl_validation'] == 'No')
{
// no SSL validation for the CAS server
phpCAS::setNoCasServerValidation();
}
phpCAS::forceAuthentication();
ob_start();
$login = phpCAS::getUser();
$password = phpCAS::retrievePT("imap://".$GLOBALS['egw_info']['server']['mail_server'],$err_code,$output);
return $GLOBALS['egw']->session->create($login,$password,'text');
}
/**
* Logout SSO system
*/
function logout()
{
phpCAS::client(CAS_VERSION_2_0,
$GLOBALS['egw_info']['server']['cas_server_host_name'],
(int) $GLOBALS['egw_info']['server']['cas_server_port'],
$GLOBALS['egw_info']['server']['cas_server_uri'] );
phpCAS::logout(array('url'=>$GLOBALS['egw_info']['server']['webserver_url'].'/login.php?cd=1&domain='.$GLOBALS['egw_info']['user']['domain']));
}
}

281
api/src/Auth/Saml.php Normal file
View File

@ -0,0 +1,281 @@
<?php
/**
* EGroupware API - Authentication via SAML or everything supported by SimpleSAMLphp
*
* @link https://www.egroupware.org
* @link https://simplesamlphp.org/docs/stable/
* @license http://opensource.org/licenses/lgpl-license.php LGPL - GNU Lesser General Public License
* @package api
* @subpackage authentication
*/
namespace EGroupware\Api\Auth;
use EGroupware\Api;
use SimpleSAML;
use EGroupware\Api\Exception;
/**
* Authentication based on SAML or everything supported by SimpleSAMLphp
*
* SimpleSAMLphp is installed together with EGroupware and a default configuration is created in EGroupware
* files subdirectory "saml", once "Saml" is set as authentication method in setup and eg. the login page is loaded.
*
* It will NOT work, before you configure at least one IdP (Identity Provider) for the default-sp (Service Provider) in saml/authsourcres.php:
*
* // An authentication source which can authenticate against both SAML 2.0
* // and Shibboleth 1.3 IdPs.
* 'default-sp' => [
* 'saml:SP',
*
* // The entity ID of this SP.
* // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.
* 'entityID' => null,
*
* // The entity ID of the IdP this SP should contact.
* // Can be NULL/unset, in which case the user will be shown a list of available IdPs.
* 'idp' => 'https://samltest.id/saml/idp',
*
* And the IdP's metadata in saml/metadata/saml20-idp-remote.php
*
* $metadata['https://samltest.id/saml/idp'] = [
* 'SingleSignOnService' => 'https://samltest.id/idp/profile/SAML2/Redirect/SSO',
* 'SingleLogoutService' => 'https://samltest.id/idp/profile/Logout',
* 'certificate' => 'samltest.id.pem',
* ];
*
* https://samltest.id/ is just a SAML / Shibboleth test side allowing AFTER uploading your metadata to test with a couple of static test-accounts.
*
* The metadata can be downloaded by via https://example.org/egroupware/saml/ under Federation, it also allows to test the authentication.
* The required (random) Admin password can be found in /var/lib/egrouwpare/default/saml/config.php searching for auth.adminpassword.
*
* Alternativly you can also modify the following metadata example by replacing https://example.org/ with your domain:
*
* <?xml version="1.0"?>
* <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://example.org/egroupware/saml/module.php/saml/sp/metadata.php/default-sp">
* <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol">
* <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://example.org/egroupware/saml/module.php/saml/sp/saml2-logout.php/default-sp"/>
* <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://example.org/egroupware/saml/module.php/saml/sp/saml2-acs.php/default-sp" index="0"/>
* <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://example.org/egroupware/saml/module.php/saml/sp/saml1-acs.php/default-sp" index="1"/>
* <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://example.org/egroupware/saml/module.php/saml/sp/saml2-acs.php/default-sp" index="2"/>
* <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://example.org/egroupware/saml/module.php/saml/sp/saml1-acs.php/default-sp/artifact" index="3"/>
* </md:SPSSODescriptor>
* <md:ContactPerson contactType="technical">
* <md:GivenName>Admin</md:GivenName>
* <md:SurName>Name</md:SurName>
* <md:EmailAddress>mailto:admin@example.org</md:EmailAddress>
* </md:ContactPerson>
* </md:EntityDescriptor>
*/
class Saml implements BackendSSO
{
/**
* Constructor
*/
function __construct()
{
// ensure we have (at least) a default configuration
self::checkDefaultConfig();
}
/**
* authentication against SAML
*
* @param string $username username of account to authenticate
* @param string $passwd corresponding password
* @param string $passwd_type ='text' 'text' for cleartext passwords (default)
* @return boolean true if successful authenticated, false otherwise
*/
function authenticate($username, $passwd, $passwd_type='text')
{
// login (redirects to IdP)
$as = new SimpleSAML\Auth\Simple('default-sp');
$as->requireAuth();
return true;
}
/**
* changes password in SAML
*
* @param string $old_passwd must be cleartext or empty to not to be checked
* @param string $new_passwd must be cleartext
* @param int $account_id =0 account id of user whose passwd should be changed
* @return boolean true if password successful changed, false otherwise
*/
function change_password($old_passwd, $new_passwd, $account_id=0)
{
/* Not allowed */
return false;
}
/**
* Attempt SSO login
*
* @return string sessionid on successful login, null otherwise
*/
function login()
{
// login (redirects to IdP)
$as = new SimpleSAML\Auth\Simple('default-sp');
$as->requireAuth();
// cleanup session for EGroupware
$session = SimpleSAML\Session::getSessionFromRequest();
$session->cleanup();
// get attributes for (automatic) account creation
$attrs = $as->getAttributes();
$user = $attrs['urn:oid:0.9.2342.19200300.100.1.1'][0];
$GLOBALS['egw_info']['server']['auto_create_acct'] = true;
$GLOBALS['auto_create_acct'] = [
'firstname' => $attrs['urn:oid:2.5.4.42'][0],
'lastname' => $attrs['urn:oid:2.5.4.4'][0],
'email' => $attrs['urn:oid:0.9.2342.19200300.100.1.3'][0],
];
// return user session
return $GLOBALS['egw']->session->create($user, null, null, false, false);
}
/**
* Logout SSO system
*/
function logout()
{
$as = new SimpleSAML\Auth\Simple('default-sp');
$as->logout();
}
/**
* Return (which) parts of session needed by current auth backend
*
* If this returns any key(s), the session is NOT destroyed by Api\Session::destroy,
* just everything but the keys is removed.
*
* @return array of needed keys in session
*/
function needSession()
{
return ['SimpleSAMLphp_SESSION'];
}
/**
* Create simpleSAMLphp default configuration
*
* @throws Exception
*/
public static function checkDefaultConfig()
{
// use "saml" subdirectory of EGroupware files directory as simpleSAMLphp config-directory
$config_dir = $GLOBALS['egw_info']['server']['files_dir'].'/saml';
if (!file_exists($config_dir) && !mkdir($config_dir))
{
throw new Exception("Can't create SAML config directory '$config_dir'!");
}
SimpleSAML\Configuration::setConfigDir($config_dir);
// create a default configuration
if ((!file_exists($config_dir.'/config.php') || filesize($config_dir.'/config.php') < 1000))
{
foreach(['cert', 'log', 'data', 'metadata'] as $dir)
{
if (!file_exists($config_dir.'/'.$dir) && !mkdir($config_dir.'/'.$dir, 700, true))
{
throw new Exception("Can't create $dir-directory '$config_dir/$dir'!");
}
}
// create a key-pair
$cert_dir = $config_dir.'/cert';
$private_key_path = $cert_dir.'/saml.pem';
$public_key_path = $cert_dir.'/saml.crt';
if (!file_exists($private_key_path) || !file_exists($public_key_path))
{
// Create the private and public key
$res = openssl_pkey_new([
"digest_alg" => "sha512",
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
]);
if ($res === false)
{
throw new Exception('Error generating key-pair!');
}
// Extract the public key from $res to $pubKey
$details = openssl_pkey_get_details($res);
// Extract the private key from $res
$public_key = null;
openssl_pkey_export($res, $public_key); // ToDo: db-password as passphrase
if (!file_put_contents($public_key_path, $details["key"]) ||
!file_put_contents($private_key_path, $public_key.$details["key"]))
{
throw new Exception('Error storing key-pair!');
}
// fix permisions to only allow webserver access
chmod($public_key_path, 0600);
chmod($private_key_path, 0600);
}
$simplesaml_dir = EGW_SERVER_ROOT.'/vendor/simplesamlphp/simplesamlphp';
foreach(glob($simplesaml_dir.'/config-templates/*.php') as $path)
{
switch($file=basename($path))
{
case 'config.php':
$cookie_domain = Api\Session::getCookieDomain($cookie_path, $cookie_secure);
if (!file_put_contents($config_dir.'/'.$file,
$c=strtr($t=file_get_contents($path), [
"'baseurlpath' => 'simplesaml/'," => "'baseurlpath' => '".Api\Framework::getUrl(Api\Egw::link('/saml/'))."',",
"'timezone' => null," => "'timezone' => 'Europe/Berlin',", // ToDo: use default prefs
"'secretsalt' => 'defaultsecretsalt'" => "'secretsalt' => '".Api\Auth::randomstring(32)."',",
"'auth.adminpassword' => '123'," => "'auth.adminpassword' => '".Api\Auth::randomstring(12)."',",
"'admin.protectindexpage' => false," => "'admin.protectindexpage' => true,",
"'certdir' => 'cert/'," => "'certdir' => __DIR__.'/cert/',",
"'loggingdir' => 'log/'," => "'loggingdir' => __DIR__.'/log/',",
"'datadir' => 'data/'," => "'datadir' => __DIR__.'/data/',",
"'tempdir' => '/tmp/simplesaml'," => "'tempdir' => \$GLOBALS['egw_info']['server']['temp_dir'],",
"'metadatadir' => 'metadata'," => "'metadatadir' => __DIR__.'/metadata',",
"'logging.handler' => 'syslog'," => "'logging.handler' => 'errorlog',",
"'metadata.sign.privatekey' => null," => "'metadata.sign.privatekey' => 'saml.pem',",
//"'metadata.sign.privatekey_pass' => null," => "",
"'metadata.sign.certificate' => null," => "'metadata.sign.privatekey' => 'saml.crt',",
//"'metadata.sign.algorithm' => null," => "",
// we have to use EGroupware session/cookie parameters
"'session.cookie.name' => 'SimpleSAMLSessionID'," => "'session.cookie.name' => 'sessionid',",
"'session.cookie.path' => '/'," => "'session.cookie.path' => '$cookie_path',",
"'session.cookie.domain' => null," => "'session.cookie.domain' => '$cookie_domain',",
"'session.cookie.secure' => false," => "'session.cookie.secure' => ".($cookie_secure ? 'true' : 'false').',',
"'session.phpsession.cookiename' => 'SimpleSAML'," => "'session.phpsession.cookiename' => 'sessionid',",
])))
{
header('Content-Type: text/plain');
echo "template:\n$t\n\nconfig:\n$c\n\n";
throw new Exception("Can't write SAML config file '$config_dir/config.php'!");
}
break;
default:
if (!copy($path, $config_dir.'/'.$file))
{
throw new Exception("Can't copy SAML config file '$config_dir/$file'!");
}
break;
}
}
foreach(glob($simplesaml_dir.'/metadata-templates/*.php') as $path)
{
$dest = $config_dir . '/metadata/' . basename($path);
if (!copy($path, $dest))
{
throw new Exception("Can't copy SAML metadata file '$dest'!");
}
}
}
}
}

View File

@ -98,6 +98,7 @@
"pear/pear": "*",
"pear/xml_feed_parser": "^1.0.5",
"pragmarx/google2fa-qrcode": "^1.0",
"simplesamlphp/simplesamlphp": "^1.18",
"tinymce/tinymce": "^5.0"
},
"require-dev": {

3504
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -51,56 +51,10 @@ if(isset($GLOBALS['sitemgr_info']) && $GLOBALS['egw_info']['user']['userid'] ==
}
}
// CAS :
if($GLOBALS['egw_info']['server']['auth_type'] == 'cas')
// SSO login: CAS, SAML, ...
if (($GLOBALS['sessionid'] = Api\Auth::login()))
{
ob_end_clean();
require_once('CAS/CAS.php');
//phpCAS::setDebug('/var/log/log_phpcas.php');
if($GLOBALS['egw_info']['server']['cas_authentication_mode'] == 'Proxy')
{
phpCAS::proxy(CAS_VERSION_2_0,
$GLOBALS['egw_info']['server']['cas_server_host_name'],
(int) $GLOBALS['egw_info']['server']['cas_server_port'],
$GLOBALS['egw_info']['server']['cas_server_uri'] );
}
else
{
phpCAS::client(CAS_VERSION_2_0,
$GLOBALS['egw_info']['server']['cas_server_host_name'],
(int) $GLOBALS['egw_info']['server']['cas_server_port'],
$GLOBALS['egw_info']['server']['cas_server_uri'] );
}
if($GLOBALS['egw_info']['server']['cas_ssl_validation'] == 'PEMCertificate')
{
// Set the certificate of the CAS server (PEM Certificate)
phpCAS::setCasServerCert($GLOBALS['egw_info']['server']['cas_cert']);
}
elseif($GLOBALS['egw_info']['server']['cas_ssl_validation'] == 'CACertificate')
{
// Set the CA certificate of the CAS server
phpCAS::setCasServerCACert($GLOBALS['egw_info']['server']['cas_cert']);
}
elseif($GLOBALS['egw_info']['server']['cas_ssl_validation'] == 'No')
{
// no SSL validation for the CAS server
phpCAS::setNoCasServerValidation();
}
phpCAS::forceAuthentication();
ob_start();
$login = phpCAS::getUser();
$password = phpCAS::retrievePT("imap://".$GLOBALS['egw_info']['server']['mail_server'],$err_code,$output);
$GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($login,$password,'text');
/* set auth_cookie */
$GLOBALS['egw']->redirect_link($forward,$extra_vars);
$GLOBALS['egw']->redirect_link($forward, $extra_vars);
}
else
{

View File

@ -37,7 +37,7 @@ elseif(strpos($redirectTarget, '[?&]cd=') !== false)
$redirectTarget = preg_replace('/([?&])cd=[^&]+/', '$1cd=1', $redirectTarget);
}
if($verified)
if ($verified)
{
// remove remember me cookie on explicit logout, unless it is a second factor
if ($GLOBALS['egw']->session->removeRememberMeTokenOnLogout())
@ -52,16 +52,8 @@ Api\Session::egw_setcookie('sessionid');
Api\Session::egw_setcookie('kp3');
Api\Session::egw_setcookie('domain');
if($GLOBALS['egw_info']['server']['auth_type'] == 'cas')
{
require_once('CAS/CAS.php');
phpCAS::client(CAS_VERSION_2_0,
$GLOBALS['egw_info']['server']['cas_server_host_name'],
(int) $GLOBALS['egw_info']['server']['cas_server_port'],
$GLOBALS['egw_info']['server']['cas_server_uri'] );
phpCAS::logout(array('url'=>$GLOBALS['egw_info']['server']['webserver_url'].'/login.php?cd=1&domain='.$GLOBALS['egw_info']['user']['domain']));
}
// SSO Logout (does not return for SSO systems)
Api\Auth::logout();
// $GLOBALS['egw']->redirect($redirectTarget);
?>

29
saml/_egw_include.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* EGroupware API - Authentication via SAML or everything supported by SimpleSAMLphp
*
* @link https://www.egroupware.org
* @link https://simplesamlphp.org/docs/stable/
* @license http://opensource.org/licenses/lgpl-license.php LGPL - GNU Lesser General Public License
* @package api
* @subpackage authentication
*/
// we have to set session-cookie name used by EGroupware!
ini_set('session.name', 'sessionid');
$GLOBALS['egw_info'] = [
'flags' => [
//'currentapp' => 'login', // db connection, no auth
'noapi' => true, // no db connection, but autoloader, files_dir MUST be set correct!
],
'server' => [
'files_dir' => '/var/lib/egroupware/default/files',
'temp_dir' => '/tmp',
],
];
require_once __DIR__.'/../header.inc.php';
use EGroupware\Api;
Api\Auth\Saml::checkDefaultConfig();

69
saml/_include.php Normal file
View File

@ -0,0 +1,69 @@
<?php
// EGroupware modification start
require_once __DIR__.'/_egw_include.php';
// initialize the autoloader
//require_once(dirname(dirname(__FILE__)) . '/lib/_autoload.php');
// EGroupware modification end
// enable assertion handler for all pages
\SimpleSAML\Error\Assertion::installHandler();
// show error page on unhandled exceptions
function SimpleSAML_exception_handler($exception)
{
\SimpleSAML\Module::callHooks('exception_handler', $exception);
if ($exception instanceof \SimpleSAML\Error\Error) {
$exception->show();
} elseif ($exception instanceof \Exception) {
$e = new \SimpleSAML\Error\Error('UNHANDLEDEXCEPTION', $exception);
$e->show();
} elseif (class_exists('Error') && $exception instanceof \Error) {
$code = $exception->getCode();
$errno = ($code > 0) ? $code : E_ERROR;
$errstr = $exception->getMessage();
$errfile = $exception->getFile();
$errline = $exception->getLine();
SimpleSAML_error_handler($errno, $errstr, $errfile, $errline);
}
}
set_exception_handler('SimpleSAML_exception_handler');
// log full backtrace on errors and warnings
function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0, $errcontext = null)
{
if (\SimpleSAML\Logger::isErrorMasked($errno)) {
// masked error
return false;
}
static $limit = 5;
$limit -= 1;
if ($limit < 0) {
// we have reached the limit in the number of backtraces we will log
return false;
}
// show an error with a full backtrace
$context = (is_null($errfile) ? '' : " at $errfile:$errline");
$e = new \SimpleSAML\Error\Exception('Error ' . $errno . ' - ' . $errstr . $context);
$e->logError();
// resume normal error processing
return false;
}
set_error_handler('SimpleSAML_error_handler');
try {
\SimpleSAML\Configuration::getInstance();
} catch (\Exception $e) {
throw new \SimpleSAML\Error\CriticalConfigurationError(
$e->getMessage()
);
}
// set the timezone
\SimpleSAML\Utils\Time::initTimezone();

35
saml/admin/hostnames.php Normal file
View File

@ -0,0 +1,35 @@
<?php
require_once('../_include.php');
// Load SimpleSAMLphp configuration
$config = \SimpleSAML\Configuration::getInstance();
$session = \SimpleSAML\Session::getSessionFromRequest();
// Check if valid local session exists..
\SimpleSAML\Utils\Auth::requireAdmin();
$attributes = [];
$attributes['HTTP_HOST'] = [$_SERVER['HTTP_HOST']];
$attributes['HTTPS'] = isset($_SERVER['HTTPS']) ? [$_SERVER['HTTPS']] : [];
$attributes['SERVER_PROTOCOL'] = [$_SERVER['SERVER_PROTOCOL']];
$attributes['SERVER_PORT'] = [$_SERVER['SERVER_PORT']];
$attributes['getBaseURL()'] = [\SimpleSAML\Utils\HTTP::getBaseURL()];
$attributes['getSelfHost()'] = [\SimpleSAML\Utils\HTTP::getSelfHost()];
$attributes['getSelfHostWithNonStandardPort()'] = [\SimpleSAML\Utils\HTTP::getSelfHostWithNonStandardPort()];
$attributes['selfURLhost()'] = [\SimpleSAML\Utils\HTTP::getSelfURLHost()];
$attributes['selfURLNoQuery()'] = [\SimpleSAML\Utils\HTTP::getSelfURLNoQuery()];
$attributes['getSelfHostWithPath()'] = [\SimpleSAML\Utils\HTTP::getSelfHostWithPath()];
$attributes['getFirstPathElement()'] = [\SimpleSAML\Utils\HTTP::getFirstPathElement()];
$attributes['selfURL()'] = [\SimpleSAML\Utils\HTTP::getSelfURL()];
$template = new \SimpleSAML\XHTML\Template($config, 'hostnames.php');
$template->data['remaining'] = $session->getAuthData('admin', 'Expire') - time();
$template->data['attributes'] = $attributes;
$template->data['valid'] = 'na';
$template->data['logout'] = null;
$template->show();

31
saml/admin/index.php Normal file
View File

@ -0,0 +1,31 @@
<?php
require_once('../_include.php');
\SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Module::getModuleURL('admin/'));
// Load SimpleSAMLphp configuration
$config = \SimpleSAML\Configuration::getInstance();
$session = \SimpleSAML\Session::getSessionFromRequest();
// Check if valid local session exists..
\SimpleSAML\Utils\Auth::requireAdmin();
$adminpages = [
'hostnames.php' => 'Diagnostics on hostname, port and protocol',
'phpinfo.php' => 'PHP info',
'../module.php/sanitycheck/index.php' => 'Sanity check of your SimpleSAMLphp setup',
'sandbox.php' => 'Sandbox for testing changes to layout and css',
];
$logouturl = \SimpleSAML\Utils\Auth::getAdminLogoutURL();
$template = new \SimpleSAML\XHTML\Template($config, 'index.php');
$template->data['pagetitle'] = 'Admin';
$template->data['adminpages'] = $adminpages;
$template->data['remaining'] = $session->getAuthData('admin', 'Expire') - time();
$template->data['valid'] = 'na';
$template->data['logouturl'] = $logouturl;
$template->show();

View File

@ -0,0 +1,58 @@
<?php
require_once('../_include.php');
// make sure that the user has admin access rights
\SimpleSAML\Utils\Auth::requireAdmin();
$config = \SimpleSAML\Configuration::getInstance();
if (!empty($_FILES['xmlfile']['tmp_name'])) {
$xmldata = trim(file_get_contents($_FILES['xmlfile']['tmp_name']));
} elseif (array_key_exists('xmldata', $_POST)) {
$xmldata = trim($_POST['xmldata']);
}
if (!empty($xmldata)) {
\SimpleSAML\Utils\XML::checkSAMLMessage($xmldata, 'saml-meta');
$entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsString($xmldata);
// get all metadata for the entities
foreach ($entities as &$entity) {
$entity = [
'shib13-sp-remote' => $entity->getMetadata1xSP(),
'shib13-idp-remote' => $entity->getMetadata1xIdP(),
'saml20-sp-remote' => $entity->getMetadata20SP(),
'saml20-idp-remote' => $entity->getMetadata20IdP(),
];
}
// transpose from $entities[entityid][type] to $output[type][entityid]
$output = \SimpleSAML\Utils\Arrays::transpose($entities);
// merge all metadata of each type to a single string which should be added to the corresponding file
foreach ($output as $type => &$entities) {
$text = '';
foreach ($entities as $entityId => $entityMetadata) {
if ($entityMetadata === null) {
continue;
}
// remove the entityDescriptor element because it is unused, and only makes the output harder to read
unset($entityMetadata['entityDescriptor']);
$text .= '$metadata[' . var_export($entityId, true) . '] = ' .
var_export($entityMetadata, true) . ";\n";
}
$entities = $text;
}
} else {
$xmldata = '';
$output = [];
}
$template = new \SimpleSAML\XHTML\Template($config, 'metadata-converter.php', 'admin');
$template->data['clipboard.js'] = true;
$template->data['xmldata'] = $xmldata;
$template->data['output'] = $output;
$template->show();

8
saml/admin/phpinfo.php Normal file
View File

@ -0,0 +1,8 @@
<?php
require_once('../_include.php');
// Make sure that the user has admin access rights
\SimpleSAML\Utils\Auth::requireAdmin();
phpinfo();

20
saml/admin/sandbox.php Normal file
View File

@ -0,0 +1,20 @@
<?php
require_once('../_include.php');
// Load SimpleSAMLphp configuration
$config = \SimpleSAML\Configuration::getInstance()->toArray();
$config['usenewui'] = true;
$config = \SimpleSAML\Configuration::loadFromArray($config, '[ARRAY]', 'simplesaml');
$session = \SimpleSAML\Session::getSessionFromRequest();
$template = new \SimpleSAML\XHTML\Template($config, 'sandbox.php');
$template->data['pagetitle'] = 'Sandbox';
$template->data['sometext'] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus.' .
' Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.' .
' Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. ' .
'Nam tincidunt congue enim, ut porta lorem lacinia consectetur.';
$template->data['remaining'] = $session->getAuthData('admin', 'Expire') - time();
$template->data['logout'] = null;
$template->send();

0
saml/assets/css/.gitkeep Normal file
View File

View File

@ -0,0 +1,174 @@
/* these styles are in the head of this page because this is a unique page */
/* THE BIG GUYS */
html {
direction: rtl;
}
#header{
background: linear-gradient(-141deg, #b8002c 0%, #db0100 51%, #e8410c 75%);
}
#footer{
background: linear-gradient(-141deg, #b8002c 0%, #db0100 51%, #e8410c 75%);
}
/* LISTS */
ul {
margin: .3em 2em 1.5em 0;
}
li {
margin-right: 2em;
}
/* TYPOGRAPHY */
dl dd {
margin-right: 3em;
}
.efieldlist {
border-right: 1px solid #e6e6e6;
}
div.caution {
padding: .2em 60px .2em .2em;
background-position: right;
}
th.rowtitle {
text-align: right;
}
.enablebox table {
margin-right: 1em;
}
.enablebox.mini table {
float: left;
}
.enablebox tr td {
padding: .5px .5em 1px 1em;
}
/* Attribute presentation in example page */
table.attributes td.attrname {
text-align: left;
}
fieldset.fancyfieldset {
margin: 2em 0px 1em 1em;
}
fieldset.fancyfieldset legend {
margin-right: 2em;
}
/* Reverse Float Left <-> Right */
.right {
float: left;
}
.left {
float: right;
}
.v-center-right{
right: 0;
}
.logo-footer-right{
left:0;
right: auto;
}
.message-box {
border-left-style: initial;
order-left-width: 0;
border-left-color: none;
border-right-style: solid;
border-right-width: 0.3125rem;
}
.message-box.error{
border-right-color: #cc4b37;
}
.message-box.success{
border-right-color: #46cc48;
}
.code-box-title .clipboard-btn {
right: auto;
left: 0;
margin-left: 4px;
margin-right: auto;
}
/*selectize elements*/
div .item{
float: right;
}
.selectize-input{
padding-right:8px;
}
.selectize-input:after{
transform: translate(-8px, 0);
}
/*purecss elements*/
.pure-form-aligned .pure-control-group label {
text-align: left;
margin: 0 0 0 1em;
}
@media only screen and (max-width : 480px) {
.pure-form-aligned .pure-control-group label {
text-align: right;
}
}
.pure-form-aligned .pure-controls {
margin: 1.5em 11em 0 0;
}
.pure-form .pure-help-inline,
.pure-form-message-inline {
padding-left: 0;
padding-right: 0.3em;
}
.pure-select{
float: left;
}
.pure-table-attributes ul{
margin:0;
}
.pure-table-attributes li{
margin:0;
}
/* language side menu on medium and small screens*/
#layout.active #menu {
right: initial;
left: 11em;
}
#layout.active .menu-link {
right: initial;
left: 11em;
}
#menu {
right: initial;
margin-right: 0;
margin-left: -11em; /* "#menu" width */
left: 0;
}
#menu a {
padding: 0.6em 0.6em 0.6em 0em;
}
.menu-link {
right: initial;
left: 0; /* "#menu width" */
}
/* -- Responsive Styles (Media Queries) ------------------------------------- */
@media screen and (max-width: 0em), screen and (min-width: 40em) {
#layout.active {
right: auto;
left: 11em;
}
#menuLink.menu-link.active {
right: auto;
left: 13em;
}
#foot.active {
margin-right: auto;
margin-left: 11em;
}
}

View File

0
saml/assets/js/.gitkeep Normal file
View File

61
saml/errorreport.php Normal file
View File

@ -0,0 +1,61 @@
<?php
require_once('_include.php');
$config = \SimpleSAML\Configuration::getInstance();
// this page will redirect to itself after processing a POST request and sending the email
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
// the message has been sent. Show error report page
$t = new \SimpleSAML\XHTML\Template($config, 'errorreport.php', 'errors');
$t->show();
exit;
}
$reportId = $_REQUEST['reportId'];
$email = $_REQUEST['email'];
$text = $_REQUEST['text'];
if (!preg_match('/^[0-9a-f]{8}$/', $reportId)) {
throw new \SimpleSAML\Error\Exception('Invalid reportID');
}
$data = null;
try {
$session = \SimpleSAML\Session::getSessionFromRequest();
$data = $session->getData('core:errorreport', $reportId);
} catch (\Exception $e) {
\SimpleSAML\Logger::error('Error loading error report data: ' . var_export($e->getMessage(), true));
}
if ($data === null) {
$data = [
'exceptionMsg' => 'not set',
'exceptionTrace' => 'not set',
'trackId' => 'not set',
'url' => 'not set',
'referer' => 'not set',
];
if (isset($session)) {
$data['trackId'] = $session->getTrackID();
}
}
$data['reportId'] = $reportId;
$data['version'] = $config->getVersion();
$data['hostname'] = php_uname('n');
$data['directory'] = dirname(dirname(__FILE__));
if ($config->getBoolean('errorreporting', true)) {
$mail = new SimpleSAML\Utils\EMail('SimpleSAMLphp error report from ' . $email);
$mail->setData($data);
$mail->addReplyTo($email);
$mail->setText($text);
$mail->send();
SimpleSAML\Logger::error('Report with id ' . $reportId . ' sent');
}
// redirect the user back to this page to clear the POST request
\SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Utils\HTTP::getSelfURLNoQuery());

11
saml/index.php Normal file
View File

@ -0,0 +1,11 @@
<?php
require_once('_include.php');
$config = \SimpleSAML\Configuration::getInstance();
if ($config->getBoolean('usenewui', false)) {
\SimpleSAML\Utils\HTTP::redirectTrustedURL(SimpleSAML\Module::getModuleURL('core/login'));
}
\SimpleSAML\Utils\HTTP::redirectTrustedURL(SimpleSAML\Module::getModuleURL('core/frontpage_welcome.php'));

23
saml/logout.php Normal file
View File

@ -0,0 +1,23 @@
<?php
require_once('_include.php');
$config = \SimpleSAML\Configuration::getInstance();
if (array_key_exists('link_href', $_REQUEST)) {
$link = \SimpleSAML\Utils\HTTP::checkURLAllowed($_REQUEST['link_href']);
} else {
$link = 'index.php';
}
if (array_key_exists('link_text', $_REQUEST)) {
$text = $_REQUEST['link_text'];
} else {
$text = '{logout:default_link_text}';
}
$t = new \SimpleSAML\XHTML\Template($config, 'logout.php');
$t->data['link'] = $link;
$t->data['text'] = $text;
$t->show();
exit();

10
saml/module.php Normal file
View File

@ -0,0 +1,10 @@
<?php
/**
* This web page receives requests for web-pages hosted by modules, and directs them to
* the process() handler in the Module class.
*/
require_once('_include.php');
\SimpleSAML\Module::process()->send();

View File

@ -0,0 +1,70 @@
/* these styles are in the head of this page because this is a unique page */
/* THE BIG GUYS */
html {
direction: rtl;
}
/* LISTS */
ul {
margin: .3em 2em 1.5em 0;
}
li {
margin-right: 2em;
}
#wrap {
text-align: right;
}
/* TYPOGRAPHY */
dl dd {
margin-right: 3em;
}
.efieldlist {
border-right: 1px solid #e6e6e6;
}
div.caution {
padding: .2em 60px .2em .2em;
background-position: right;
}
th.rowtitle {
text-align: right;
}
.enablebox table {
margin-right: 1em;
}
.enablebox.mini table {
float: left;
}
.enablebox tr td {
padding: .5px .5em 1px 1em;
}
/* Attribute presentation in example page */
table.attributes td.attrname {
text-align: left;
}
fieldset.fancyfieldset {
margin: 2em 0px 1em 1em;
}
fieldset.fancyfieldset legend {
margin-right: 2em;
}
.ui-tabs .ui-tabs-nav li {
float: right;
}
/* Reverse Float Left <-> Right */
.float-r {
float: left;
}
.float-l {
float: right;
}

468
saml/resources/default.css Normal file
View File

@ -0,0 +1,468 @@
/* these styles are in the head of this page because this is a unique page */
/* THE BIG GUYS */
* {
margin: 0;
padding: 0;
}
body {
text-align: center;
padding: 10px 0;
background: #1c1c1c;
/* background-image: url(icons/ssplogo-fish.png); */
/* background-repeat: no-repeat; */
color: #333;
font: 83%/1.5 arial,tahoma,verdana,sans-serif;
}
.body-embed {
padding: 0;
background: #ffffff;
font: 83%/1.5 arial,tahoma,verdana,sans-serif;
}
img {
border: none;
display: block;
}
hr {
margin: 1em 0;
background: #eee;
height: 1px;
color: #eee;
border: none;
clear: both;
}
/* LINKS */
a, a:link, a:link, a:link, a:hover {
text-decoration: none;
color: #777;
border-bottom: 1px dotted #ccc;
font-weight: normal;
}
a:link, a:visited {
text-decoration: none;
color: #777;
border-bottom: 1px dotted #ccc;
font-weight: normal;
}
.ui-tabs-nav a {
border: none ! important;
text-decoration: none;
}
a:visited {
color: #999;
}
a:hover, a:active {
color: #069;
text-decoration: none;
color: #333;
border-bottom: 1px solid #333;
}
#header a {
color: #fff;
text-decoration: none;
}
/* LISTS */
ul {
margin: .3em 0 1.5em 2em;
}
ul.related {
margin-top: -1em;
}
li {
margin-left: 2em;
}
dt {
font-weight: bold;
}
#wrap {
background: #fff;
border: 1px solid #fff;
position: relative;
text-align: left;
margin: 20px 75px 2em 75px;
max-width: 950px;
}
#languagebar {
padding-left: 10px;
padding-right: 10px;
}
#languagebar a:link, #languagebar a:visited {
text-decoration: none;
color: #777;
border-bottom: 1px dotted #ccc;
font-weight: normal;
}
#languagebar a:hover {
text-decoration: none;
color: #333;
border-bottom: 1px solid #333;
}
#header {
background: #666 url("header-bkg.png") repeat-x 0 100%;
margin: 0px;
padding: 0 0 8px;
}
#header h1 {
color: #fff;
font-size: 145%;
padding: 20px 20px 12px;
}
#content, #footer {
padding: 0 20px;
}
/* TYPOGRAPHY */
p, ul, ol {
margin: 0 0 1.5em;
}
h1, h2, h3, h4, h5, h6 {
letter-spacing: -1px;
font-family: arial,verdana,sans-serif;
margin: 1.2em 0 .3em;
color: #000;
border-bottom: 1px solid #eee;
padding-bottom: .1em;
}
h1 {
font-size: 196%;
margin-top: 0;
border: none;
}
h2 {
font-size: 136%;
}
h3 {
font-size: 126%;
}
h4 {
font-size: 116%;
font-weight: bold;
}
h5 {
font-size: 106%;
}
h6 {
font-size: 96%;
}
input {
border: 1px solid #ddd;
border-radius: 3px;
padding: 5px;
line-height: 1.5em;
}
h1 a {
text-decoration: none;
border: none ! important;
color: white;
}
h1 a:hover {
border-bottom: 1px dotted #eee;
}
#content {
margin-top: 2em;
}
.old {
text-decoration: line-through;
}
dl dt {
color: #333;
}
dl dd {
color: #666;
margin-left: 3em;
/* font-family: monospace; */
}
.efieldlist {
padding: .4em;
margin: .8em;
border-top: 1px solid #e6e6e6;
border-left: 1px solid #e6e6e6;
}
.efieldlist.warning {
background-color: #922;
border: 1px solid #333;
color: white;
}
.efieldlist.warning h5 {
color: white;
}
.efieldlist h5 {
font-weight: bold;
color: #200;
margin: .3em;
}
.trackidtext {
border: 1px dashed #aaa;
background: #eaeaea;
padding: .6em;
margin: .4em;
}
.trackidtext .trackid {
border: 1px solid #ccc;
background: #eee;
margin: .4em;
padding: .4em;
font-family: monospace;
font-size: large;
}
div.caution {
background-color: #FF9;
background-image: url('icons/experience/gtk-dialog-warning.48x48.png');
background-repeat: no-repeat;
border: thin solid #444;
padding: .2em .2em .2em 60px;
margin: 1em 0px 1em 0px;
}
th.rowtitle {
text-align: left;
}
.enablebox table {
border: 1px solid #eee;
margin-left: 1em;
}
.enablebox.mini table {
float: right;
}
.enablebox tr td {
padding: .5px 1em 1px .5em;
margin: 0px;
}
.enablebox {
font-size: 85%;
}
.enablebox tr.enabled td {
background: #eee;
}
.enablebox tr.disabled td {
background: #ccc;
}
.metadatabox {
overflow: scroll;
border: 1px solid #eee;
padding: 0.5em;
border-radius: 3px;
}
div.preferredidp {
border: 1px dashed #ccc;
background: #eee;
padding: 2px 2em 2px 2em;
}
table.modules {
border-collapse: collapse;
}
table.modules tr td {
border-bottom: 1px solid #ddd;
}
table.modules tr.even td {
background: #f0f0f0;
}
/* Attribute presentation in example page */
table.attributes {
width: 100%;
margin: 0px;
border: 1px solid #bbb;
border-collapse: collapse;
}
table.attributes td.attrname {
text-align: right;
}
table.attributes tr.even td {
background: #eee;
}
table.attributes tr td {
border-bottom: 1px solid #bbb;
border-left: 0px;
border-right: 0px;
background: #fff;
padding-top: 5px;
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
.attrvalue {
word-break: break-all;
word-wrap: break-word;
}
table#table_with_attributes tr:last-child td {
border-bottom: none;
}
fieldset.fancyfieldset {
margin: 2em 1em 1em 0px;
border: 1px solid #bbb;
}
fieldset.fancyfieldset legend {
margin-left: 2em;
padding: 3px 2em 3px 2em;
border: 1px solid #bbb;
}
div#confirmation input {
margin-top: .5em;
margin-bottom: .5em;
}
div#confirmation {
border: 1px solid #aaa;
background: #eee;
padding: .6em 1em .1em 1em;
}
caption {
display: none;
}
/* Left-to-Right CSS for RTL (Right to Left Support) */
.float-r {
float: right;
}
.float-l {
float: left;
}
#mobile_remember_username, #mobile_remember_me {
display: none;
}
@media handheld, only screen and (max-width: 480px), only screen and (max-device-width: 480px) {
#header, #languagebar, #footer, .erroricon, .loginicon, .logintext,
#regular_remember_username, #regular_remember_me {
display: none;
}
body {
font-size: 20px;
}
#wrap {
margin: 0;
}
h1,h2,h3,h4 {
font-size: 110%;
}
#content {
margin-bottom: 10px;
padding: 0;
padding-left: 5px;
}
input[type="text"], input[type="password"] {
height: 1.5em;
font-size: 1em;
}
.youareadmin {
font-size: 50%;
}
#mobilesubmit, #mobile_remember_username, #mobile_remember_me {
display: table-row;
}
}
.btn, .btnaddonright {
color: #000000;
border: 1px solid #eee;
border-radius: 3px;
background-color: #eee;
background-image: linear-gradient(#fcfcfc, #eee);
text-align: center;
padding: 5px;
cursor: hand;
}
.btn:hover, .btnaddonright:hover {
border-color: #ccc;
background-color: #ddd;
background-image: linear-gradient(#eee, #ddd);
}
.btn img,
.btnaddonright img {
max-height: 15px;
max-width: 15px;
}
.topright {
position: absolute;
right: 2em;
}
.input-group {
display: table;
}
.input-group pre {
background: white;
position: relative;
width: 100%;
vertical-align: middle;
border: 1px solid #eee;
padding: 0.5em;
display: table-cell;
}
.input-group .btnaddonright {
position: relative;
display: inline-block;
border-bottom-left-radius: 0;
border-bottom-right-radius: 3px;
border-top-left-radius: 0;
border-top-right-radius: 3px;
border-left: none;
}
.input-group .btnaddonright:hover {
border-left: 1px solid #ccc;
}
.input-group .input-left {
border-bottom-left-radius: 3px;
border-bottom-right-radius: 0;
border-top-left-radius: 3px;
border-top-right-radius: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with EazyDraw for Mac ( http://www.eazydraw.com/ ) -->
<svg
version="1.1"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
width="22.3999988313"
height="23.9999987478"
viewBox="0, 0, 22.3999988313, 23.9999987478"
preserveAspectRatio="none"
id="svg2">
<defs
id="defs_F220240E"/>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer_Paper"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1;fill-rule:nonzero;stroke-linecap:square;stroke-linejoin:miter;stroke-width:1;stroke-miterlimit:10">
<path
style="stroke:none"
id="9BFB96DD"
d="M3.199999833043,19.1999989983 L9.59999949913,19.1999989983 L9.59999949913,20.7999989148 L3.199999833043,20.7999989148 L3.199999833043,19.1999989983 z M11.1999994157,9.59999949913 L3.199999833043,9.59999949913
L3.199999833043,11.1999994157 L11.1999994157,11.1999994157 L11.1999994157,9.59999949913 z M14.3999992487,14.3999992487 L14.3999992487,11.1999994157 L9.59999949913,15.9999991652 L14.3999992487,20.7999989148
L14.3999992487,17.5999990817 L22.3999988313,17.5999990817 L22.3999988313,14.3999992487 L14.3999992487,14.3999992487 z M7.199999624348,12.7999993322 L3.199999833043,12.7999993322 L3.199999833043,14.3999992487
L7.199999624348,14.3999992487 L7.199999624348,12.7999993322 z M3.199999833043,17.5999990817 L7.199999624348,17.5999990817 L7.199999624348,15.9999991652 L3.199999833043,15.9999991652 L3.199999833043,17.5999990817
z M17.5999990817,19.1999989983 L19.1999989983,19.1999989983 L19.1999989983,22.3999988313 C19.1749989996,22.8499988078 19.0249990074,23.2249987883 18.724999023,23.5249987726 C18.4249990387,23.824998757 18.0499990583,23.9749987491 17.5999990817,23.9999987478
L1.599999916522,23.9999987478 C0.724999962174,23.9999987478 0,23.2749987857 0,22.3999988313 L0,4.799999749565 C0,3.924999795217 0.724999962174,3.199999833043 1.599999916522,3.199999833043 L6.399999666087,3.199999833043
C6.399999666087,1.424999925652 7.824999591739,0 9.59999949913,0 C11.3749994065,0 12.7999993322,1.424999925652 12.7999993322,3.199999833043 L17.5999990817,3.199999833043 C18.4749990361,3.199999833043 19.1999989983,3.924999795217 19.1999989983,4.799999749565
L19.1999989983,12.7999993322 L17.5999990817,12.7999993322 L17.5999990817,7.999999582609 L1.599999916522,7.999999582609 L1.599999916522,22.3999988313 L17.5999990817,22.3999988313 L17.5999990817,19.1999989983
z M3.199999833043,6.399999666087 L15.9999991652,6.399999666087 C15.9999991652,5.524999711739 15.274999203,4.799999749565 14.3999992487,4.799999749565 L12.7999993322,4.799999749565 C11.9249993778,4.799999749565 11.1999994157,4.074999787391 11.1999994157,3.199999833043
C11.1999994157,2.324999878696 10.4749994535,1.599999916522 9.59999949913,1.599999916522 C8.724999544783,1.599999916522 7.999999582609,2.324999878696 7.999999582609,3.199999833043 C7.999999582609,4.074999787391 7.274999620435,4.799999749565 6.399999666087,4.799999749565
L4.799999749565,4.799999749565 C3.924999795217,4.799999749565 3.199999833043,5.524999711739 3.199999833043,6.399999666087 z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,17 @@
These images are from the Crystal theme, licensed under the GNU LGPL.
See: http://www.everaldo.com/crystal/
Original readme:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
This copyright and license notice covers the images in this directory.
************************************************************************
TITLE: Crystal Project Icons
AUTHOR: Everaldo Coelho
SITE: http://www.everaldo.com
CONTACT: everaldo@everaldo.com
Copyright (c) 2006-2007 Everaldo Coelho.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,6 @@
The icons in this directory is from the eXperience theme by
David Christian Berg. The icons are released under the GNU GPL.
See:
- http://art.gnome.org/themes/icon
- http://art.gnome.org/download/themes/icon/1096/ICON-EXperience.tar.gz

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

View File

@ -0,0 +1,5 @@
These images are from the silk icon set, and are licensed under the
Creative Commons Attribution 2.5 License.
See:
http://famfamfam.com/lab/icons/silk/

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

2
saml/resources/jquery-1.8.js vendored Normal file

File diff suppressed because one or more lines are too long

5
saml/resources/jquery-ui-1.8.js vendored Normal file

File diff suppressed because one or more lines are too long

3
saml/resources/post.css Normal file
View File

@ -0,0 +1,3 @@
input#postLoginSubmitButton {
display:none;
}

7
saml/resources/post.js Normal file
View File

@ -0,0 +1,7 @@
/**
* Automatically click the input button to redirect the user to
* the SSO
*/
window.onload = function () {
document.getElementById('postLoginSubmitButton').click();
};

BIN
saml/resources/progress.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

44
saml/resources/script.js Normal file
View File

@ -0,0 +1,44 @@
/**
* Set focus to the element with the given id.
*
* @param id The id of the element which should receive focus.
*/
function SimpleSAML_focus(id)
{
var element = document.getElementById(id);
if (element != null) {
element.focus();
}
}
/**
* Show the given DOM element.
*
* @param id The id of the element which should be shown.
*/
function SimpleSAML_show(id)
{
var element = document.getElementById(id);
if (element == null) {
return;
}
element.style.display = 'block';
}
/**
* Hide the given DOM element.
*
* @param id The id of the element which should be hidden.
*/
function SimpleSAML_hide(id)
{
var element = document.getElementById(id);
if (element == null) {
return;
}
element.style.display = 'none';
}

81
saml/resources/slo.css Normal file
View File

@ -0,0 +1,81 @@
table#slostatustable {
/* width: 100%; */
border-collapse: collapse;
margin-bottom: 1em;
}
table#slostatustable tr td {
/* border-top: 1px solid #ccc; */
padding-left: 4px;
padding-right: 4px;
}
table#slostatustable tr td.statustext {
min-width: 5em;
padding-left: 0px;
}
table#slostatustable tr td.statustext span { display: none; }
table#slostatustable tr.completed td.statustext span.completed { display: inline; }
table#slostatustable tr.onhold td.statustext span.onhold { display: inline; }
table#slostatustable tr.inprogress td.statustext span.inprogress { display: inline; }
table#slostatustable tr.failed td.statustext span.failed { display: inline; }
table#slostatustable tr td.icons img {
/* margin: 3px; */
display: none;
}
table#slostatustable tr.completed td.icons img.completed { display: inline; }
table#slostatustable tr.onhold td.icons img.onhold { display: inline; }
table#slostatustable tr.inprogress td.icons img.inprogress { display: inline; }
table#slostatustable tr.failed td.icons img.failed { display: inline; }
iframe.hiddeniframe {
display: none;
}
/* From old CSS
div.allcompleted#interrupt {
display: none;
}
div#interrupt a:link {
color: #036;
border-bottom: 1px dotted #036;
text-decoration: none;
}
div#interrupt a:hover {
border-bottom: 1px solid #036;
}
div#interrupt {
display: block;
border: 3px solid #036;
background: #39F;
padding: 1em;
margin: .2em;
}
div#iscompleted {
display: none;
border: 3px solid #993;
background: #FF9;
padding: 1em;
margin: .2em;
}
div.allcompleted#iscompleted {
display: block ! important;
}
div.inprogress, div.loggedout {
background: #eee;
color: #444;
padding: .2em 1em;
margin: .2em;
}
div.inprogress {
border: 1px dotted #888;
}
div.loggedout {
border: 1px solid #888;
background: #9f9 ! important;
}
iframe.hiddeniframe {
display: none;
}
*/

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.47pre4 r22446"
width="16"
height="16"
sodipodi:docname="ssplogo-fish.icon.svg">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6">
<linearGradient
id="linearGradient3607">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3609" />
<stop
style="stop-color:#d1d1d1;stop-opacity:1;"
offset="1"
id="stop3611" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3607"
id="linearGradient3613"
x1="277.12003"
y1="52.042328"
x2="277.12003"
y2="378.57556"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3607"
id="linearGradient3665"
gradientUnits="userSpaceOnUse"
x1="277.12003"
y1="27.166664"
x2="277.12003"
y2="404.08838"
gradientTransform="matrix(0.03696855,0,0,0.03696855,7.60047,8.3543873)" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1126"
id="namedview4"
showgrid="false"
inkscape:zoom="36.660194"
inkscape:cx="14.83847"
inkscape:cy="5.9954998"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
style="fill:url(#linearGradient3665);fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4.0999999;stroke-opacity:1;stroke-dasharray:none"
d="m 9.6205185,8.2105307 c 0,1.2054091 0.5026335,1.8380793 1.2095645,1.8380793 1.026799,0 0.883174,-0.8139968 2.065657,-0.6164036 -0.609954,1.7050766 -1.695369,2.2507596 -2.70683,2.6097686 0.01445,0.713465 0.696837,0.972365 0.663749,1.74271 -0.0126,0.620173 -0.540523,1.16597 -1.849053,1.199755 C 7.937029,15.01198 7.1694148,14.428558 7.1621101,13.672056 7.1538401,12.8153 7.794439,12.748742 7.7801781,11.972659 7.0121384,11.658782 5.9969211,11.120437 5.2801801,9.3917916 4.5595881,9.4316547 4.2463443,10.078721 3.5334162,10.057225 2.820488,10.03573 2.3532378,9.3650782 2.3596648,8.2105307 2.3699546,7.0612227 2.8890256,6.3083345 3.6866947,6.347702 4.7041225,6.3979148 4.5628318,7.0174937 5.2842137,6.956665 6.0080941,5.3023375 7.0082024,4.758849 7.7761444,4.44437 7.8705492,3.6923296 7.2680513,3.6072458 7.1621101,2.7490058 7.0644371,1.9577466 7.9149765,1.4581701 9.003606,1.4769589 c 1.264656,0.043103 1.758244,0.6249683 1.869222,1.1634518 0.198595,0.9636163 -0.661983,1.1126875 -0.683918,1.7386769 1.016506,0.3514412 2.051693,0.8212046 2.690696,2.5492635 C 11.505643,7.0675225 12.118475,6.3518306 10.830083,6.3522838 10.040991,6.3818947 9.6263626,7.2818233 9.6205185,8.2105307 z"
id="path2818"
sodipodi:nodetypes="cccccssccscsccscscccc"
inkscape:export-filename="/home/ica/olavmo/ssplogo-fish.16x16.png"
inkscape:export-xdpi="3.8204713"
inkscape:export-ydpi="3.8204713" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path3595"
sodipodi:cx="325.25742"
sodipodi:cy="141.73412"
sodipodi:rx="7.9104872"
sodipodi:ry="7.9104872"
d="m 333.1679,141.73412 a 7.9104872,7.9104872 0 1 1 -15.82097,0 7.9104872,7.9104872 0 1 1 15.82097,0 z"
transform="matrix(0.03696855,0,0,0.03696855,-1.3157193,0.26343856)"
inkscape:export-filename="/home/ica/olavmo/ssplogo-fish.16x16.png"
inkscape:export-xdpi="3.8204713"
inkscape:export-ydpi="3.8204713" />
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.47pre4 r22446"
width="605"
height="412"
sodipodi:docname="ssplogo-fish.svg">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6">
<linearGradient
id="linearGradient3607">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3609" />
<stop
style="stop-color:#d1d1d1;stop-opacity:1;"
offset="1"
id="stop3611" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3607"
id="linearGradient3613"
x1="277.12003"
y1="52.042328"
x2="277.12003"
y2="378.57556"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3607"
id="linearGradient3665"
gradientUnits="userSpaceOnUse"
x1="277.12003"
y1="27.166664"
x2="277.12003"
y2="404.08838" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1126"
id="namedview4"
showgrid="false"
inkscape:zoom="1.620167"
inkscape:cx="291.53461"
inkscape:cy="196.53189"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
style="fill:url(#linearGradient3665);stroke:#505050;stroke-width:11.50000000000000000;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1;stroke-miterlimit:4.09999990000000025;stroke-dasharray:none"
d="m 296.34375,215.07812 c 0,32.60634 13.59626,49.72008 32.71875,49.72008 27.77495,0 23.88987,-22.01863 55.87606,-16.67373 -16.49926,46.12236 -45.85975,60.88308 -73.21981,70.59428 0.39081,19.29927 18.84947,26.30254 17.95445,47.14036 -0.34076,16.77569 -14.62118,31.5395 -50.01695,32.45339 -28.85093,0.74491 -49.61491,-15.03662 -49.8125,-35.5 -0.22378,-23.17528 17.10451,-24.97567 16.71875,-45.96875 -20.77549,-8.49037 -48.23714,-23.05263 -67.625,-69.8125 -19.49203,1.0783 -27.96528,18.58146 -47.25,18 -19.28472,-0.58146 -31.923849,-18.7226 -31.75,-49.95313 0.27834,-31.08881 14.31922,-51.45445 35.89619,-50.38956 27.52144,1.35827 23.69952,18.11788 43.21292,16.47246 19.58098,-44.74959 46.63393,-59.45097 67.40678,-67.95763 2.55365,-20.34271 -13.74393,-22.644231 -16.60964,-45.85964 -2.64206,-21.403585 20.36505,-34.917116 49.8125,-34.408898 34.20898,1.166056 47.56055,16.905412 50.5625,31.471398 5.372,26.065843 -17.90666,30.098219 -18.5,47.03125 27.49653,9.50649 55.49834,22.2136 72.78337,68.95763 -37.16568,3.76459 -20.58858,-15.59489 -55.43962,-15.58263 -21.34496,0.80098 -32.56067,25.14406 -32.71875,50.26562 z"
id="path2818"
sodipodi:nodetypes="cccccssccscsccscscccc"
inkscape:export-filename="/home/ica/olavmo/ssplogo-fish.16x16.png"
inkscape:export-xdpi="3.8204713"
inkscape:export-ydpi="3.8204713" />
<path
sodipodi:type="arc"
style="fill:#505050;fill-opacity:1;stroke:none"
id="path3595"
sodipodi:cx="325.25742"
sodipodi:cy="141.73412"
sodipodi:rx="7.9104872"
sodipodi:ry="7.9104872"
d="m 333.1679,141.73412 a 7.9104872,7.9104872 0 1 1 -15.82097,0 7.9104872,7.9104872 0 1 1 15.82097,0 z"
transform="translate(0.51827331,0.10911017)"
inkscape:export-filename="/home/ica/olavmo/ssplogo-fish.16x16.png"
inkscape:export-xdpi="3.8204713"
inkscape:export-ydpi="3.8204713" />
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;stroke:#505050;stroke-width:11;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3597"
sodipodi:cx="448.71918"
sodipodi:cy="161.40855"
sodipodi:rx="14.504678"
sodipodi:ry="14.504678"
d="m 463.22386,161.40855 a 14.504678,14.504678 0 1 1 -29.00936,0 14.504678,14.504678 0 1 1 29.00936,0 z"
transform="translate(0.43644068,-0.21822034)" />
<path
transform="matrix(1.6489362,0,0,1.6489362,-241.51074,-155.90234)"
d="m 463.22386,161.40855 a 14.504678,14.504678 0 1 1 -29.00936,0 14.504678,14.504678 0 1 1 29.00936,0 z"
sodipodi:ry="14.504678"
sodipodi:rx="14.504678"
sodipodi:cy="161.40855"
sodipodi:cx="448.71918"
id="path3601"
style="fill:#ffffff;fill-opacity:1;stroke:#505050;stroke-width:6.67096762;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;stroke:#505050;stroke-width:4.7214613;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3605"
sodipodi:cx="448.71918"
sodipodi:cy="161.40855"
sodipodi:rx="14.504678"
sodipodi:ry="14.504678"
d="m 463.22386,161.40855 a 14.504678,14.504678 0 1 1 -29.00936,0 14.504678,14.504678 0 1 1 29.00936,0 z"
transform="matrix(2.3297873,0,0,2.3297873,-486.997,-327.67385)" />
<path
style="fill:none;stroke:#505050;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 67.662778,176.76189 c 0,0 -10.629563,24.70204 -10.569898,37.26469 0.06444,13.56817 11.650034,36.64746 11.650034,36.64746"
id="path3615"
sodipodi:nodetypes="csc" />
<path
sodipodi:nodetypes="csc"
id="path3617"
d="m 28.164897,176.76189 c 0,0 -10.629563,24.70204 -10.569898,37.26469 0.06444,13.56817 11.650034,36.64746 11.650034,36.64746"
style="fill:none;stroke:#505050;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

563
saml/resources/uitheme1.8/jquery-ui.css vendored Normal file
View File

@ -0,0 +1,563 @@
/*!
* jQuery UI CSS Framework 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
.ui-helper-clearfix:after { clear: both; }
.ui-helper-clearfix { zoom: 1; }
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/*!
* jQuery UI CSS Framework 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
*/
/* Component containers
----------------------------------*/
/*.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }*/
.ui-widget .ui-widget { font-size: 1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
.ui-widget-content a { color: #222222; }
.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
.ui-widget-header a { color: #222222; }
/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
.ui-widget :active { outline: none; }
/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-off { background-position: -96px -144px; }
.ui-icon-radio-on { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
/* Overlays */
.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*!
* jQuery UI Resizable 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Resizable#theming
*/
.ui-resizable { position: relative;}
.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*!
* jQuery UI Selectable 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Selectable#theming
*/
.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
/*!
* jQuery UI Accordion 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Accordion#theming
*/
/* IE/Win - Fix animation bug - #4615 */
.ui-accordion { width: 100%; }
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
.ui-accordion .ui-accordion-li-fix { display: inline; }
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
.ui-accordion .ui-accordion-content-active { display: block; }
/*!
* jQuery UI Autocomplete 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Autocomplete#theming
*/
.ui-autocomplete { position: absolute; cursor: default; }
/* workarounds */
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
/*
* jQuery UI Menu 1.8.23
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Menu#theming
*/
.ui-menu {
list-style:none;
padding: 2px;
margin: 0;
display:block;
float: left;
}
.ui-menu .ui-menu {
margin-top: -3px;
}
.ui-menu .ui-menu-item {
margin:0;
padding: 0;
zoom: 1;
float: left;
clear: left;
width: 100%;
}
.ui-menu .ui-menu-item a {
text-decoration:none;
display:block;
padding:.2em .4em;
line-height:1.5;
zoom:1;
}
.ui-menu .ui-menu-item a.ui-state-hover,
.ui-menu .ui-menu-item a.ui-state-active {
font-weight: normal;
margin: -1px;
}
/*!
* jQuery UI Button 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Button#theming
*/
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
.ui-button-icons-only { width: 3.4em; }
button.ui-button-icons-only { width: 3.7em; }
/*button text element */
.ui-button .ui-button-text { display: block; line-height: 1.4; }
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
/* no icon support for input elements, provide padding by default */
input.ui-button { padding: .4em 1em; }
/*button icon element(s) */
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
/*button sets*/
.ui-buttonset { margin-right: 7px; }
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
/* workarounds */
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
/*!
* jQuery UI Dialog 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Dialog#theming
*/
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
.ui-draggable .ui-dialog-titlebar { cursor: move; }
/*!
* jQuery UI Slider 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Slider#theming
*/
.ui-slider { position: relative; text-align: left; }
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
.ui-slider-horizontal { height: .8em; }
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
.ui-slider-vertical { width: .8em; height: 100px; }
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
.ui-slider-vertical .ui-slider-range-max { top: 0; }/*!
* jQuery UI Tabs 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Tabs#theming
*/
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
.ui-tabs .ui-tabs-hide { display: none !important; }
/*!
* jQuery UI Datepicker 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Datepicker#theming
*/
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
.ui-datepicker .ui-datepicker-prev { left:2px; }
.ui-datepicker .ui-datepicker-next { right:2px; }
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
.ui-datepicker td { border: 0; padding: 1px; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi { width:auto; }
.ui-datepicker-multi .ui-datepicker-group { float:left; }
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
/* RTL support */
.ui-datepicker-rtl { direction: rtl; }
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
.ui-datepicker-cover {
position: absolute; /*must have*/
z-index: -1; /*must have*/
filter: mask(); /*must have*/
top: -4px; /*must have*/
left: -4px; /*must have*/
width: 200px; /*must have*/
height: 200px; /*must have*/
}/*!
* jQuery UI Progressbar 1.8.23
*
* Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Progressbar#theming
*/
.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }

View File

@ -0,0 +1,69 @@
<?php
/**
* The ArtifactResolutionService receives the samlart from the sp.
* And when the artifact is found, it sends a \SAML2\ArtifactResponse.
*
* @author Danny Bollaert, UGent AS. <danny.bollaert@ugent.be>
* @package SimpleSAMLphp
*/
require_once('../../_include.php');
$config = \SimpleSAML\Configuration::getInstance();
if (!$config->getBoolean('enable.saml20-idp', false)) {
throw new \SimpleSAML\Error\Error('NOACCESS');
}
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
$idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted');
if (!$idpMetadata->getBoolean('saml20.sendartifact', false)) {
throw new \SimpleSAML\Error\Error('NOACCESS');
}
$store = \SimpleSAML\Store::getInstance();
if ($store === false) {
throw new Exception('Unable to send artifact without a datastore configured.');
}
$binding = new \SAML2\SOAP();
try {
$request = $binding->receive();
} catch (Exception $e) {
// TODO: look for a specific exception
// This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should throw
// an specific exception when the binding is unknown, and we should capture that here. Also note that the exception
// message here is bogus!
if ($e->getMessage() === 'Invalid message received to AssertionConsumerService endpoint.') {
throw new \SimpleSAML\Error\Error('ARSPARAMS', $e, 400);
} else {
throw $e; // do not ignore other exceptions!
}
}
if (!($request instanceof \SAML2\ArtifactResolve)) {
throw new Exception('Message received on ArtifactResolutionService wasn\'t a ArtifactResolve request.');
}
$issuer = $request->getIssuer();
$spMetadata = $metadata->getMetaDataConfig($issuer, 'saml20-sp-remote');
$artifact = $request->getArtifact();
$responseData = $store->get('artifact', $artifact);
$store->delete('artifact', $artifact);
if ($responseData !== null) {
$document = \SAML2\DOMDocumentFactory::fromString($responseData);
$responseXML = $document->firstChild;
} else {
$responseXML = null;
}
$artifactResponse = new \SAML2\ArtifactResponse();
$artifactResponse->setIssuer($idpEntityId);
$artifactResponse->setInResponseTo($request->getId());
$artifactResponse->setAny($responseXML);
\SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $artifactResponse);
$binding->send($artifactResponse);

View File

@ -0,0 +1,29 @@
<?php
/**
* The SSOService is part of the SAML 2.0 IdP code, and it receives incoming Authentication Requests
* from a SAML 2.0 SP, parses, and process it, and then authenticates the user and sends the user back
* to the SP with an Authentication Response.
*
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @package SimpleSAMLphp
*/
require_once('../../_include.php');
\SimpleSAML\Logger::info('SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP endpoint SSOService');
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
$idp = \SimpleSAML\IdP::getById('saml2:' . $idpEntityId);
try {
\SimpleSAML\Module\saml\IdP\SAML2::receiveAuthnRequest($idp);
} catch (\Exception $e) {
if ($e->getMessage() === "Unable to find the current binding.") {
throw new \SimpleSAML\Error\Error('SSOPARAMS', $e, 400);
} else {
throw $e; // do not ignore other exceptions!
}
}
assert(false);

View File

@ -0,0 +1,37 @@
<?php
/**
* This SAML 2.0 endpoint can receive incoming LogoutRequests. It will also send LogoutResponses,
* and LogoutRequests and also receive LogoutResponses. It is implemeting SLO at the SAML 2.0 IdP.
*
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @package SimpleSAMLphp
*/
require_once('../../_include.php');
\SimpleSAML\Logger::info('SAML2.0 - IdP.SingleLogoutService: Accessing SAML 2.0 IdP endpoint SingleLogoutService');
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
$idp = \SimpleSAML\IdP::getById('saml2:' . $idpEntityId);
if (isset($_REQUEST['ReturnTo'])) {
$idp->doLogoutRedirect(\SimpleSAML\Utils\HTTP::checkURLAllowed((string) $_REQUEST['ReturnTo']));
} else {
try {
\SimpleSAML\Module\saml\IdP\SAML2::receiveLogoutMessage($idp);
} catch (\Exception $e) {
// TODO: look for a specific exception
/*
* This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should
* throw an specific exception when the binding is unknown, and we should capture that here
*/
if ($e->getMessage() === 'Unable to find the current binding.') {
throw new \SimpleSAML\Error\Error('SLOSERVICEPARAMS', $e, 400);
} else {
throw $e; // do not ignore other exceptions!
}
}
}
assert(false);

View File

@ -0,0 +1,16 @@
<?php
require_once('../../_include.php');
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
$idp = \SimpleSAML\IdP::getById('saml2:' . $idpEntityId);
\SimpleSAML\Logger::info('SAML2.0 - IdP.initSLO: Accessing SAML 2.0 IdP endpoint init Single Logout');
if (!isset($_GET['RelayState'])) {
throw new \SimpleSAML\Error\Error('NORELAYSTATE');
}
$idp->doLogoutRedirect(\SimpleSAML\Utils\HTTP::checkURLAllowed((string) $_GET['RelayState']));
assert(false);

247
saml/saml2/idp/metadata.php Normal file
View File

@ -0,0 +1,247 @@
<?php
require_once('../../_include.php');
use SAML2\Constants;
use SimpleSAML\Module;
use SimpleSAML\Utils\Auth as Auth;
use SimpleSAML\Utils\Crypto as Crypto;
use SimpleSAML\Utils\HTTP as HTTP;
use SimpleSAML\Utils\Config\Metadata as Metadata;
// load SimpleSAMLphp configuration and metadata
$config = \SimpleSAML\Configuration::getInstance();
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
if (!$config->getBoolean('enable.saml20-idp', false)) {
throw new \SimpleSAML\Error\Error('NOACCESS');
}
// check if valid local session exists
if ($config->getBoolean('admin.protectmetadata', false)) {
Auth::requireAdmin();
}
try {
$idpentityid = isset($_GET['idpentityid']) ?
$_GET['idpentityid'] : $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
$idpmeta = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-hosted');
$availableCerts = [];
$keys = [];
$certInfo = Crypto::loadPublicKey($idpmeta, false, 'new_');
if ($certInfo !== null) {
$availableCerts['new_idp.crt'] = $certInfo;
$keys[] = [
'type' => 'X509Certificate',
'signing' => true,
'encryption' => true,
'X509Certificate' => $certInfo['certData'],
];
$hasNewCert = true;
} else {
$hasNewCert = false;
}
$certInfo = Crypto::loadPublicKey($idpmeta, true);
$availableCerts['idp.crt'] = $certInfo;
$keys[] = [
'type' => 'X509Certificate',
'signing' => true,
'encryption' => ($hasNewCert ? false : true),
'X509Certificate' => $certInfo['certData'],
];
if ($idpmeta->hasValue('https.certificate')) {
$httpsCert = Crypto::loadPublicKey($idpmeta, true, 'https.');
assert(isset($httpsCert['certData']));
$availableCerts['https.crt'] = $httpsCert;
$keys[] = [
'type' => 'X509Certificate',
'signing' => true,
'encryption' => false,
'X509Certificate' => $httpsCert['certData'],
];
}
$metaArray = [
'metadata-set' => 'saml20-idp-remote',
'entityid' => $idpentityid,
];
$ssob = $metadata->getGenerated('SingleSignOnServiceBinding', 'saml20-idp-hosted');
$slob = $metadata->getGenerated('SingleLogoutServiceBinding', 'saml20-idp-hosted');
$ssol = $metadata->getGenerated('SingleSignOnService', 'saml20-idp-hosted');
$slol = $metadata->getGenerated('SingleLogoutService', 'saml20-idp-hosted');
if (is_array($ssob)) {
foreach ($ssob as $binding) {
$metaArray['SingleSignOnService'][] = [
'Binding' => $binding,
'Location' => $ssol,
];
}
} else {
$metaArray['SingleSignOnService'][] = [
'Binding' => $ssob,
'Location' => $ssol,
];
}
if (is_array($slob)) {
foreach ($slob as $binding) {
$metaArray['SingleLogoutService'][] = [
'Binding' => $binding,
'Location' => $slol,
];
}
} else {
$metaArray['SingleLogoutService'][] = [
'Binding' => $slob,
'Location' => $slol,
];
}
if (count($keys) === 1) {
$metaArray['certData'] = $keys[0]['X509Certificate'];
} else {
$metaArray['keys'] = $keys;
}
if ($idpmeta->getBoolean('saml20.sendartifact', false)) {
// Artifact sending enabled
$metaArray['ArtifactResolutionService'][] = [
'index' => 0,
'Location' => HTTP::getBaseURL() . 'saml2/idp/ArtifactResolutionService.php',
'Binding' => Constants::BINDING_SOAP,
];
}
if ($idpmeta->getBoolean('saml20.hok.assertion', false)) {
// Prepend HoK SSO Service endpoint.
array_unshift($metaArray['SingleSignOnService'], [
'hoksso:ProtocolBinding' => Constants::BINDING_HTTP_REDIRECT,
'Binding' => Constants::BINDING_HOK_SSO,
'Location' => HTTP::getBaseURL() . 'saml2/idp/SSOService.php'
]);
}
if ($idpmeta->getBoolean('saml20.ecp', false)) {
$metaArray['SingleSignOnService'][] = [
'index' => 0,
'Binding' => Constants::BINDING_SOAP,
'Location' => HTTP::getBaseURL() . 'saml2/idp/SSOService.php',
];
}
$metaArray['NameIDFormat'] = $idpmeta->getArrayizeString(
'NameIDFormat',
'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
);
if ($idpmeta->hasValue('OrganizationName')) {
$metaArray['OrganizationName'] = $idpmeta->getLocalizedString('OrganizationName');
$metaArray['OrganizationDisplayName'] = $idpmeta->getLocalizedString(
'OrganizationDisplayName',
$metaArray['OrganizationName']
);
if (!$idpmeta->hasValue('OrganizationURL')) {
throw new \SimpleSAML\Error\Exception(
'If OrganizationName is set, OrganizationURL must also be set.'
);
}
$metaArray['OrganizationURL'] = $idpmeta->getLocalizedString('OrganizationURL');
}
if ($idpmeta->hasValue('scope')) {
$metaArray['scope'] = $idpmeta->getArray('scope');
}
if ($idpmeta->hasValue('EntityAttributes')) {
$metaArray['EntityAttributes'] = $idpmeta->getArray('EntityAttributes');
// check for entity categories
if (Metadata::isHiddenFromDiscovery($metaArray)) {
$metaArray['hide.from.discovery'] = true;
}
}
if ($idpmeta->hasValue('UIInfo')) {
$metaArray['UIInfo'] = $idpmeta->getArray('UIInfo');
}
if ($idpmeta->hasValue('DiscoHints')) {
$metaArray['DiscoHints'] = $idpmeta->getArray('DiscoHints');
}
if ($idpmeta->hasValue('RegistrationInfo')) {
$metaArray['RegistrationInfo'] = $idpmeta->getArray('RegistrationInfo');
}
if ($idpmeta->hasValue('validate.authnrequest')) {
$metaArray['sign.authnrequest'] = $idpmeta->getBoolean('validate.authnrequest');
}
if ($idpmeta->hasValue('redirect.validate')) {
$metaArray['redirect.sign'] = $idpmeta->getBoolean('redirect.validate');
}
if ($idpmeta->hasValue('contacts')) {
$contacts = $idpmeta->getArray('contacts');
foreach ($contacts as $contact) {
$metaArray['contacts'][] = Metadata::getContact($contact);
}
}
$technicalContactEmail = $config->getString('technicalcontact_email', false);
if ($technicalContactEmail && $technicalContactEmail !== 'na@example.org') {
$techcontact['emailAddress'] = $technicalContactEmail;
$techcontact['name'] = $config->getString('technicalcontact_name', null);
$techcontact['contactType'] = 'technical';
$metaArray['contacts'][] = Metadata::getContact($techcontact);
}
$metaBuilder = new \SimpleSAML\Metadata\SAMLBuilder($idpentityid);
$metaBuilder->addMetadataIdP20($metaArray);
$metaBuilder->addOrganizationInfo($metaArray);
$metaxml = $metaBuilder->getEntityDescriptorText();
$metaflat = '$metadata[' . var_export($idpentityid, true) . '] = ' . var_export($metaArray, true) . ';';
// sign the metadata if enabled
$metaxml = \SimpleSAML\Metadata\Signer::sign($metaxml, $idpmeta->toArray(), 'SAML 2 IdP');
if (array_key_exists('output', $_GET) && $_GET['output'] == 'xhtml') {
$t = new \SimpleSAML\XHTML\Template($config, 'metadata.tpl.php', 'admin');
$t->data['clipboard.js'] = true;
$t->data['available_certs'] = $availableCerts;
$certdata = [];
foreach (array_keys($availableCerts) as $availableCert) {
$certdata[$availableCert]['name'] = $availableCert;
$certdata[$availableCert]['url'] = Module::getModuleURL('saml/idp/certs.php') . '/' . $availableCert;
$certdata[$availableCert]['comment'] = (
$availableCerts[$availableCert]['certFingerprint'][0] === 'afe71c28ef740bc87425be13a2263d37971da1f9' ?
'This is the default certificate. Generate a new certificate if this is a production system.' :
''
);
}
$t->data['certdata'] = $certdata;
$t->data['header'] = 'saml20-idp'; // TODO: Replace with headerString in 2.0
$t->data['headerString'] = \SimpleSAML\Locale\Translate::noop('metadata_saml20-idp');
$t->data['metaurl'] = HTTP::getSelfURLNoQuery();
$t->data['metadata'] = htmlspecialchars($metaxml);
$t->data['metadataflat'] = htmlspecialchars($metaflat);
$t->show();
} else {
header('Content-Type: application/xml');
echo $metaxml;
exit(0);
}
} catch (\Exception $exception) {
throw new \SimpleSAML\Error\Error('METADATA', $exception);
}

View File

@ -0,0 +1,21 @@
<?php
/**
* The SSOService is part of the Shibboleth 1.3 IdP code, and it receives incoming Authentication Requests
* from a Shibboleth 1.3 SP, parses, and process it, and then authenticates the user and sends the user back
* to the SP with an Authentication Response.
*
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @package SimpleSAMLphp
*/
require_once '../../_include.php';
\SimpleSAML\Logger::info('Shib1.3 - IdP.SSOService: Accessing Shibboleth 1.3 IdP endpoint SSOService');
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
$idpEntityId = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted');
$idp = \SimpleSAML\IdP::getById('saml1:'.$idpEntityId);
\SimpleSAML\Module\saml\IdP\SAML1::receiveAuthnRequest($idp);
assert(false);

View File

@ -0,0 +1,109 @@
<?php
require_once('../../_include.php');
// load configuration and metadata
$config = \SimpleSAML\Configuration::getInstance();
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
if (!$config->getBoolean('enable.shib13-idp', false)) {
throw new \SimpleSAML\Error\Error('NOACCESS');
}
// check if valid local session exists
if ($config->getBoolean('admin.protectmetadata', false)) {
\SimpleSAML\Utils\Auth::requireAdmin();
}
try {
$idpentityid = isset($_GET['idpentityid']) ?
$_GET['idpentityid'] : $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted');
$idpmeta = $metadata->getMetaDataConfig($idpentityid, 'shib13-idp-hosted');
$keys = [];
$certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, false, 'new_');
if ($certInfo !== null) {
$keys[] = [
'type' => 'X509Certificate',
'signing' => true,
'encryption' => false,
'X509Certificate' => $certInfo['certData'],
];
}
$certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true);
$keys[] = [
'type' => 'X509Certificate',
'signing' => true,
'encryption' => false,
'X509Certificate' => $certInfo['certData'],
];
$metaArray = [
'metadata-set' => 'shib13-idp-remote',
'entityid' => $idpentityid,
'SingleSignOnService' => $metadata->getGenerated('SingleSignOnService', 'shib13-idp-hosted'),
];
if (count($keys) === 1) {
$metaArray['certData'] = $keys[0]['X509Certificate'];
} else {
$metaArray['keys'] = $keys;
}
$metaArray['NameIDFormat'] = $idpmeta->getArrayizeString('NameIDFormat', 'urn:mace:shibboleth:1.0:nameIdentifier');
if ($idpmeta->hasValue('OrganizationName')) {
$metaArray['OrganizationName'] = $idpmeta->getLocalizedString('OrganizationName');
$metaArray['OrganizationDisplayName'] = $idpmeta->getLocalizedString(
'OrganizationDisplayName',
$metaArray['OrganizationName']
);
if (!$idpmeta->hasValue('OrganizationURL')) {
throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.');
}
$metaArray['OrganizationURL'] = $idpmeta->getLocalizedString('OrganizationURL');
}
$metaflat = '$metadata['.var_export($idpentityid, true).'] = '.var_export($metaArray, true).';';
$metaBuilder = new \SimpleSAML\Metadata\SAMLBuilder($idpentityid);
$metaBuilder->addMetadataIdP11($metaArray);
$metaBuilder->addOrganizationInfo($metaArray);
$metaBuilder->addContact('technical', \SimpleSAML\Utils\Config\Metadata::getContact([
'emailAddress' => $config->getString('technicalcontact_email', null),
'name' => $config->getString('technicalcontact_name', null),
'contactType' => 'technical',
]));
$metaxml = $metaBuilder->getEntityDescriptorText();
// sign the metadata if enabled
$metaxml = \SimpleSAML\Metadata\Signer::sign($metaxml, $idpmeta->toArray(), 'Shib 1.3 IdP');
if (array_key_exists('output', $_GET) && $_GET['output'] == 'xhtml') {
$defaultidp = $config->getString('default-shib13-idp', null);
$t = new \SimpleSAML\XHTML\Template($config, 'metadata.tpl.php', 'admin');
$t->data['clipboard.js'] = true;
$t->data['header'] = 'shib13-idp'; // TODO: Replace with headerString in 2.0
$t->data['headerString'] = \SimpleSAML\Locale\Translate::noop('metadata_shib13-idp');
$t->data['metaurl'] = \SimpleSAML\Utils\HTTP::addURLParameters(
\SimpleSAML\Utils\HTTP::getSelfURLNoQuery(),
['output' => 'xml']
);
$t->data['metadata'] = htmlspecialchars($metaxml);
$t->data['metadataflat'] = htmlspecialchars($metaflat);
$t->data['defaultidp'] = $defaultidp;
$t->show();
} else {
header('Content-Type: application/xml');
echo $metaxml;
exit(0);
}
} catch (\Exception $exception) {
throw new \SimpleSAML\Error\Error('METADATA', $exception);
}