Commit ba277898 authored by Lukas Haemmerle's avatar Lukas Haemmerle

Merge branch 'master+isolate-metadata-update' into 'master'

Master+isolate metadata update

See merge request aai/SWITCHwayf!1
parents 33ae0b95 2ae94956
......@@ -53,7 +53,7 @@ Installation
This file contains the list of Identity Providers that that can be
configured by hand
3. Enure that permissions for the files:
3. Ensure that permissions for the files:
- SProvider.metadata.php
- IDProvider.metadata.php
- metadata.lock
......@@ -64,12 +64,12 @@ Installation
4. Adapt the SWITCHwayf configuration in config.php. There are comments in that
file that should help you make suitable choices for your use case.
5. If Apache 2 is used, add the following statement to the Apache configugration:
5. If Apache 2 is used, add the following statement to the Apache configuration:
--
Alias /SWITCHaai /#YOUR-PATH-TO#/SWITCHwayf
<Directory /#YOUR-PATH-TO#/SWITCHwayf>
Alias /SWITCHaai /#YOUR-PATH-TO#/SWITCHwayf/www
<Directory /#YOUR-PATH-TO#/SWITCHwayf/www>
Options Indexes MultiViews
AllowOverride None
Order allow,deny
......@@ -83,6 +83,7 @@ Alias /SWITCHaai /#YOUR-PATH-TO#/SWITCHwayf
</Directory>
--
Beware, only the www subdirectory should be exposed, not the top-level directory.
Alternatively, one also could rename the file 'WAYF' to 'WAYF.php'.
......
......@@ -7,19 +7,25 @@ if (isset($_SERVER['REMOTE_ADDR'])){
exit('No direct script access allowed');
}
if (!file_exists('config.dist.php')) {
die('The default configuration file config.dist.php does not exist in this directory!');
$toplevelDir = dirname(__DIR__);
$distConfigFilePath = $topLevelDir . '/etc/config.dist.php');
$newConfigFilePath = $topLevelDir . '/etc/config.new.php');
$currentConfigFilePath = $topLevelDir . '/etc/config.php');
if (!file_exists($distConfigFilePath)) {
die("The default configuration file 'config.dist.php' does not exist in configuration directory!");
}
if (!file_exists('config.php')) {
die('The configuration file config.php does not exist in this directory!');
if (!file_exists($currentConfigFilePath)) {
die("The configuration file 'config.php' does not exist in configuration directory!");
}
require_once('config.php');
require_once($currentConfigFilePath);
echo "Parsing current configuration and default configuration...\n";
$fp = fopen('config.new.php', 'w') or die("Cannot open file 'config.new.php' for writing!") ;
$distConfigFile = file('config.dist.php');
$currentConfigFile = file('config.php');
$fp = fopen($newConfigFilePath, 'w')
or die("Cannot open file 'config.new.php' for writing!") ;
$distConfigFile = file($distConfigFilePath);
$currentConfigFile = file($currentConfigFilePath);
$configSettings = Array();
foreach ($currentConfigFile as $line){
......
......@@ -16,7 +16,10 @@ Usage:
php update-metadata.php -help|-h
php update-metadata.php --metadata-file <file> \
--metadata-idp-file <file> --metadata-sp-file <file> \
[--verbose | -v]
[--verbose | -v] [--min-sp-count <count>] [--min-idp-count <count>]
php update-metadata.php --metadata-url <url> \
--metadata-idp-file <file> --metadata-sp-file <file> \
[--verbose | -v] [--min-sp-count <count>] [--min-idp-count <count>]
Example usage:
......@@ -28,9 +31,12 @@ php update-metadata.php \
Argument Description
-------------------
--metadata-url <url> SAML2 metadata URL
--metadata-file <file> SAML2 metadata file
--metadata-idp-file <file> File containing Service Providers
--metadata-sp-file <file> File containing Identity Providers
--min-idp-count <count> Minimum expected number of IdPs in metadata
--min-sp-count <count> Minimum expected number of SPs in metadata
--language <locale> Language locale, e.g. 'en', 'jp', ...
--verbose | -v Verbose mode
--help | -h Print this man page
......@@ -38,14 +44,19 @@ Argument Description
PAGE;
require_once('functions.php');
require_once('readMetadata.php');
$toplevelDir = dirname(__DIR__);
require_once($topLevelDir . '/lib/functions.php');
require_once($topLevelDir . '/lib/readMetadata.php');
// Script options
$longopts = array(
"metadata-url:",
"metadata-file:",
"metadata-idp-file:",
"metadata-sp-file:",
"min-idp-count:",
"min-sp-count:",
"language:",
"verbose",
"help",
......@@ -57,10 +68,12 @@ if (isset($options['help']) || isset($options['h'])) {
exit($MAN);
}
if (!isset($options['metadata-file'])) {
exit("Exiting: mandatory --metadata-file parameter missing\n");
} else {
if (isset($options['metadata-url'])) {
$metadataURL = $options['metadata-url'];
} elseif (isset($options['metadata-file'])) {
$metadataFile = $options['metadata-file'];
} else {
exit("Exiting: both --metadata-url and --metadata-file parameters missing\n");
}
if (!isset($options['metadata-sp-file'])) {
......@@ -77,20 +90,55 @@ if (!isset($options['metadata-idp-file'])) {
$metadataTempIDPFile = $metadataIDPFile.'.swp';
}
if (isset($options['min-sp-count'])) {
if (!is_numeric($options['min-sp-count'])) {
exit("Exiting: invalid value for --min-sp-count parameter\n");
} else {
$minSPCount = $options['min-sp-count'];
}
} else {
$minSPCount = 0;
}
if (isset($options['min-idp-count'])) {
if (!is_numeric($options['min-idp-count'])) {
exit("Exiting: invalid value for --min-idp-count parameter\n");
} else {
$minIDPCount = $options['min-idp-count'];
}
} else {
$minIDPCount = 0;
}
// Set other options
$language = isset($options['language']) ? $options['language'] : 'en';
$verbose = isset($options['verbose']) || isset($options['v']) ? true : false;
// Input validation
if (
!file_exists($metadataFile)
|| filesize($metadataFile) == 0
) {
exit("Exiting: File $metadataFile is empty or does not exist\n");
}
if ($metadataURL) {
$metadataFile = tempnam(sys_get_temp_dir(), 'metadata');
if (!ini_get('allow_url_fopen')) {
exit("Exiting: allow_url_fopen disabled, unabled to download $metadataURL\n");
}
if ($verbose) {
echo "Downloading metadata from $metadataURL to $metadataFile\n";
}
$result = copy($metadataURL, $metadataFile);
if (!$result) {
$error = error_get_last();
exit("Exiting: could not download $metadataURL: $error\n");
}
} else {
if (
!file_exists($metadataFile)
|| filesize($metadataFile) == 0
) {
exit("Exiting: File $metadataFile is empty or does not exist\n");
}
if (!is_readable($metadataFile)){
exit("Exiting: File $metadataFile is not readable\n");
if (!is_readable($metadataFile)){
exit("Exiting: File $metadataFile is not readable\n");
}
}
if ($verbose) {
......@@ -102,6 +150,10 @@ list($metadataIDProviders, $metadataSProviders) = parseMetadata($metadataFile, $
// If $metadataIDProviders is not FALSE, dump results in $metadataIDPFile.
if (is_array($metadataIDProviders)){
$IDPCount = count($metadataIDProviders);
if ($IDPCount < $minIDPCount) {
exit("Exiting: number of Identity Providers found ($IDPCount) lower than expected ($minIDPCount)\n");
}
if ($verbose) {
echo "Dumping parsed Identity Providers to file $metadataIDPFile\n";
......@@ -115,6 +167,10 @@ if (is_array($metadataIDProviders)){
// If $metadataSProviders is not FALSE, dump results in $metadataSPFile.
if (is_array($metadataSProviders)){
$SPCount = count($metadataSProviders);
if ($SPCount < $minSPCount) {
exit("Exiting: number of Service Providers found ($SPCount) lower than expected ($minSPCount)\n");
}
if ($verbose) {
echo "Dumping parsed Service Providers to file $metadataSPFile\n";
......@@ -125,3 +181,12 @@ if (is_array($metadataSProviders)){
exit("Exiting: Could not rename temporary file $metadataTempSPFile to $metadataSPFile");
}
}
// clean up if needed
if ($metadataURL) {
$result = unlink($metadataFile);
if (!$result) {
$error = error_get_last();
exit("Exiting: could not delete temporary file $metadataFile: $error\n");
}
}
......@@ -185,6 +185,7 @@
// 4. Files and path Settings
//***************************
// all relatives paths are resolved relatively to configuration directory
// Set both config files to the same value if you don't want to use the
// the WAYF to read a (potential) automatically generated file that undergoes
......
......@@ -55,6 +55,7 @@ function initConfigOptions(){
global $kerberosRedirectURL;
global $instanceIdentifier;
global $developmentMode;
global $topLevelDir;
// Set independet default configuration options
......@@ -124,6 +125,17 @@ function initConfigOptions(){
$$key = $value;
}
}
// Turn relatives paths into absolute ones
$files = array(
'IDPConfigFile', 'backupIDPConfigFile', 'metadataFile',
'metadataIDPFile', 'metadataSPFile', 'metadataLockFile'
);
foreach($files as $file) {
if (substr($$file, 0, 1) != '/') {
$$file = $topLevelDir . '/etc/' . $$file;
}
}
}
/******************************************************************************/
......
......@@ -4,12 +4,13 @@ function updateMetadata() {
global $metadataLockFile, $metadataIDPFile, $metadataSPFile;
global $metadataFile, $defaultLanguage;
global $SAML2MetaOverLocalConf, $includeLocalConfEntries;
global $verbose;
global $verbose, $IDProviders, $SProviders;
// Open the metadata lock file.
if (($lockFp = fopen($metadataLockFile, 'a+')) === false) {
$errorMsg = 'Could not open lock file '.$metadataLockFile;
logError($errorMsg);
return false;
}
// Check that $IDProviders exists
......@@ -17,44 +18,46 @@ function updateMetadata() {
$IDProviders = array();
}
// Run as included file
if(!file_exists($metadataIDPFile) or filemtime($metadataFile) > filemtime($metadataIDPFile)){
if (!file_exists($metadataIDPFile) or filemtime($metadataFile) > filemtime($metadataIDPFile)) {
// Get an exclusive lock to regenerate the IdP and SP files
// from the metadata file.
if (flock($lockFp, LOCK_EX) === false) {
$errorMsg = 'Could not get exclusive lock on '.$metadataLockFile;
logError($errorMsg);
fclose($lockFp);
return false;
}
// parse metadata file
list($metadataIDProviders, $metadataSProviders) = parseMetadata($metadataFile, $defaultLanguage);
// Get an exclusive lock to regenerate the parsed files.
if ($lockFp !== false) {
if (flock($lockFp, LOCK_EX) === false) {
$errorMsg = 'Could not get exclusive lock on '.$metadataLockFile;
logError($errorMsg);
}
if ($metadataIDProviders != false && is_array($metadataIDProviders)){
dumpFile($metadataIDPFile, $metadataIDProviders, 'metadataIDProviders');
}
}
// Now that we have the lock, check again
if(
(!file_exists($metadataIDPFile) or filemtime($metadataFile) > filemtime($metadataIDPFile))
and regenerateMetadata($metadataFile, $defaultLanguage)
){
if ($metadataSProviders != false && is_array($metadataSProviders)){
dumpFile($metadataSPFile, $metadataSProviders, 'metadataSProviders');
}
// release the exclusive lock
flock($lockFp, LOCK_UN);
// Now merge IDPs from metadata and static file
$IDProviders = mergeInfo($IDProviders, $metadataIDProviders, $SAML2MetaOverLocalConf, $includeLocalConfEntries);
// For now copy the array by reference
$SProviders = &$metadataSProviders;
} elseif (file_exists($metadataIDPFile)){
} elseif (file_exists($metadataIDPFile)) {
// Get a shared lock to read the IdP and SP files
// generated from the metadata file.
if ($lockFp !== false) {
// Release the lock in case we had it for some
// reason and still ended up here
flock($lockFp, LOCK_UN);
if (flock($lockFp, LOCK_SH) === false) {
$errorMsg = 'Could not lock file '.$metadataLockFile;
logError($errorMsg);
}
if (flock($lockFp, LOCK_SH) === false) {
$errorMsg = 'Could not lock file '.$metadataLockFile;
logError($errorMsg);
fclose($lockFp);
return false;
}
// Read SP and IDP files generated with metadata
......@@ -62,9 +65,7 @@ function updateMetadata() {
require($metadataSPFile);
// Release the lock.
if ($lockFp !== false) {
flock($lockFp, LOCK_UN);
}
flock($lockFp, LOCK_UN);
// Now merge IDPs from metadata and static file
$IDProviders = mergeInfo($IDProviders, $metadataIDProviders, $SAML2MetaOverLocalConf, $includeLocalConfEntries);
......@@ -74,10 +75,7 @@ function updateMetadata() {
}
// Close the metadata lock file.
if ($lockFp !== false) {
fclose($lockFp);
}
fclose($lockFp);
}
// Function parseMetadata, parses metadata file and returns Array($IdPs, SPs) or
......@@ -218,31 +216,6 @@ function parseMetadata($metadataFile, $defaultLanguage){
return Array($metadataIDProviders, $metadataSProviders);
}
// Load SAML metadata file, parse it and update
// IDProvider.metadata.php and SProvider.metadata.php files
function regenerateMetadata($metadataFile, $defaultLanguage) {
global $metadataIDPFile, $metadataSPFile, $IDProviders, $SAML2MetaOverLocalConf, $includeLocalConfEntries;
// Regenerate $metadataIDPFile.
list($metadataIDProviders, $metadataSProviders) = parseMetadata($metadataFile, $defaultLanguage);
if($metadataIDProviders == false) {
return false;
}
// If $metadataIDProviders is not an array (parse error in metadata),
// $IDProviders from $IDPConfigFile will be used.
if(is_array($metadataIDProviders)){
dumpFile($metadataIDPFile, $metadataIDProviders, 'metadataIDProviders');
$IDProviders = mergeInfo($IDProviders, $metadataIDProviders, $SAML2MetaOverLocalConf, $includeLocalConfEntries);
}
if(is_array($metadataSProviders)){
dumpFile($metadataSPFile, $metadataSProviders, 'metadataSProviders');
require($metadataSPFile);
}
}
// Processes an IDPRoleDescriptor XML node and returns an IDP entry or false if
// something went wrong
function processIDPRoleDescriptor($IDPRoleDescriptorNode){
......
......@@ -13,21 +13,23 @@ Web site: https://www.switch.ch/aai/support/tools/wayf/
// Load general configuration and template file
/*------------------------------------------------*/
$topLevelDir = dirname(__DIR__);
if (isset($_SERVER{'SWITCHWAYF_CONFIG'})){
require_once($_SERVER{'SWITCHWAYF_CONFIG'});
} else {
require_once('config.php');
require_once($topLevelDir . '/etc/config.php');
}
require_once('languages.php');
require_once('functions.php');
require_once('templates.php');
require_once($topLevelDir . '/lib/languages.php');
require_once($topLevelDir . '/lib/functions.php');
require_once($topLevelDir . '/lib/templates.php');
// Set default config options
initConfigOptions();
// Read custom locales
if (file_exists('custom-languages.php')){
require_once('custom-languages.php');
if (file_exists($topLevelDir . '/lib/custom-languages.php')){
require_once($topLevelDir . '/lib/custom-languages.php');
}
/*------------------------------------------------*/
......@@ -62,7 +64,7 @@ if ($IDPConfigFile == $backupIDPConfigFile){
// Read metadata file if configuration option is set
if($useSAML2Metadata && function_exists('xml_parser_create')){
require('readMetadata.php');
require($topLevelDir . '/lib/readMetadata.php');
updateMetadata();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment