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