$value){ if (!isset($$key)){ $$key = $value; } } // Set dependent default configuration options $defaults = array(); $defaults['redirectCookieName'] = $cookieNamePrefix.'_redirect_user_idp'; $defaults['redirectStateCookieName'] = $cookieNamePrefix.'_redirection_state'; $defaults['SAMLDomainCookieName'] = $cookieNamePrefix.'_saml_idp'; $defaults['SPCookieName'] = $cookieNamePrefix.'_saml_sp'; $defaults['logoURL'] = $imageURL.'/switch-aai-transparent.png'; $defaults['smallLogoURL'] = $imageURL.'/switch-aai-transparent-small.png'; // Initialize dependent defaults foreach($defaults as $key => $value){ if (!isset($$key)){ $$key = $value; } } } /******************************************************************************/ // Generates an array of IDPs using the cookie value function getIdPArrayFromValue($value){ // Decodes and splits cookie value $CookieArray = preg_split('/ /', $value); $CookieArray = array_map('base64_decode', $CookieArray); return $CookieArray; } /******************************************************************************/ // Generate the value that is stored in the cookie using the list of IDPs function getValueFromIdPArray($CookieArray){ // Merges cookie content and encodes it $CookieArray = array_map('base64_encode', $CookieArray); $value = implode(' ', $CookieArray); return $value; } /******************************************************************************/ // Append a value to the array of IDPs function appendValueToIdPArray($value, $CookieArray){ // Remove value if it already existed in array foreach (array_keys($CookieArray) as $i){ if ($CookieArray[$i] == $value){ unset($CookieArray[$i]); } } // Add value to end of array $CookieArray[] = $value; return $CookieArray; } /******************************************************************************/ // Checks if the configuration file has changed. If it has, check the file // and change its timestamp. function checkConfig($IDPConfigFile, $backupIDPConfigFile){ // Do files have the same modification time if (filemtime($IDPConfigFile) == filemtime($backupIDPConfigFile)) return true; // Availability check if (!file_exists($IDPConfigFile)) return false; // Readability check if (!is_readable($IDPConfigFile)) return false; // Size check if (filesize($IDPConfigFile) < 200) return false; // Make modification time the same // If that doesnt work we won't notice it touch ($IDPConfigFile, filemtime($backupIDPConfigFile)); return true; } /******************************************************************************/ // Checks if an IDP exists and returns true if it does, false otherwise function checkIDP($IDP){ global $IDProviders; if (isset($IDProviders[$IDP])){ return true; } else { return false; } } /******************************************************************************/ // Checks if an IDP exists and returns true if it exists and prints an error // if it doesnt function checkIDPAndShowErrors($IDP){ global $IDProviders; if (checkIDP($IDP)){ return true; } // Otherwise show an error $message = sprintf(getLocalString('invalid_user_idp'), htmlentities($IDP))."
\n";
foreach ($IDProviders as $key => $value){
if (isset($value['SSO'])){
$message .= $key."
\n";
}
}
$message .= "\n";
printError($message);
exit;
}
/******************************************************************************/
// Validates the URL format and returns the URL without GET arguments and fragment
function verifyAndStripReturnURL($url){
$components = parse_url($url);
if (!$components){
return false;
}
$recomposedURL = $components['scheme'].'://';
if (isset($components['user'])){
$recomposedURL .= $components['user'];
if (isset($components['pass'])){
$recomposedURL .= ':'.$components['pass'];
}
$recomposedURL .= '@';
}
if (isset($components['host'])){
$recomposedURL .= $components['host'];
}
if (isset($components['port'])){
$recomposedURL .= ':'.$components['port'];
}
if (isset($components['path'])){
$recomposedURL .= $components['path'];
}
return $recomposedURL;
}
/******************************************************************************/
// Parses the hostname out of a string and returns it
function getHostNameFromURI($string){
// Check if string is URN
if (preg_match('/^urn:mace:/i', $string)){
// Return last component of URN
return end(explode(':', $string));
}
// Apparently we are dealing with something like a URL
if (preg_match('/([a-zA-Z0-9\-\.]+\.[a-zA-Z0-9\-\.]{2,6})/', $string, $matches)){
return $matches[0];
} else {
return '';
}
}
/******************************************************************************/
// Parses the domain out of a string and returns it
function getDomainNameFromURI($string){
// Check if string is URN
if (preg_match('/^urn:mace:/i', $string)){
// Return last component of URN
return getTopLevelDomain(end(explode(':', $string)));
}
// Apparently we are dealing with something like a URL
if (preg_match('/[a-zA-Z0-9\-\.]+\.([a-zA-Z0-9\-\.]{2,6})/', $string, $matches)){
return getTopLevelDomain($matches[0]);
} else {
return '';
}
}
/******************************************************************************/
// Returns top level domain name from a DNS name
function getTopLevelDomain($string){
$hostnameComponents = explode('.', $string);
if (count($hostnameComponents) >= 2){
return $hostnameComponents[count($hostnameComponents)-2].'.'.$hostnameComponents[count($hostnameComponents)-1];
} else {
return $string;
}
}
/******************************************************************************/
// Parses the reverse dns lookup hostname out of a string and returns domain
function getDomainNameFromURIHint(){
global $IDProviders;
$clientHostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
if ($clientHostname == $_SERVER['REMOTE_ADDR']){
return '-';
}
// Get domain name from client host name
$clientDomainName = getDomainNameFromURI($clientHostname);
if ($clientDomainName == ''){
return '-';
}
// Return first matching IdP entityID that contains the client domain name
foreach ($IDProviders as $key => $value){
if (
preg_match('/^http.+'.$clientDomainName.'/', $key)
|| preg_match('/^urn:.+'.$clientDomainName.'$/', $key)){
return $key;
}
}
// No matching entityID was found
return '-';
}
/******************************************************************************/
// Get the user's language using the accepted language http header
function determineLanguage(){
global $langStrings, $defaultLanguage;
// Check if language is enforced by PATH-INFO argument
if (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO'])){
foreach ($langStrings as $lang => $values){
if (preg_match('#/'.$lang.'($|/)#',$_SERVER['PATH_INFO'])){
return $lang;
}
}
}
// Check if there is a language GET argument
if (isset($_GET['lang'])){
$localeComponents = decomposeLocale($_GET['lang']);
if (
$localeComponents !== false
&& isset($langStrings[$localeComponents[0]])
){
// Return language
return $localeComponents[0];
}
}
// Return default language if no headers are present otherwise
if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
return $defaultLanguage;
}
// Inspect Accept-Language header which looks like:
// Accept-Language: en,de-ch;q=0.8,fr;q=0.7,fr-ch;q=0.5,en-us;q=0.3,de;q=0.2
$languages = explode( ',', trim($_SERVER['HTTP_ACCEPT_LANGUAGE']));
foreach ($languages as $language){
$languageParts = explode(';', $language);
// Only treat art before the prioritization
$localeComponents = decomposeLocale($languageParts[0]);
if (
$localeComponents !== false
&& isset($langStrings[$localeComponents[0]])
){
// Return language
return $localeComponents[0];
}
}
return $defaultLanguage;
}
/******************************************************************************/
// Splits up a string (relazed) according to
// http://www.debian.org/doc/manuals/intro-i18n/ch-locale.en.html#s-localename
// and returns an array with the four components
function decomposeLocale($locale){
// Locale name syntax: language[_territory][.codeset][@modifier]
if (!preg_match('/^([a-zA-Z]{2})([-_][a-zA-Z]{2})?(\.[^@]+)?(@.+)?$/', $locale, $matches)){
return false;
} else {
// Remove matched string in first position
array_shift($matches);
return $matches;
}
}
/******************************************************************************/
// Gets a string in the user's language. If no localized version is available
// for the string, the English string is returned as default.
function getLocalString($string, $encoding = ''){
global $defaultLanguage, $langStrings, $language;
$textString = '';
if (isset($langStrings[$language][$string])){
$textString = $langStrings[$language][$string];
} else {
$textString = $langStrings[$defaultLanguage][$string];
}
// Change encoding if necessary
if ($encoding == 'js'){
$textString = convertToJSString($textString);
}
return $textString;
}
/******************************************************************************/
// Converts string to a JavaScript format that can be used in JS alert
function convertToJSString($string){
return addslashes(html_entity_decode($string, ENT_COMPAT, 'UTF-8'));
}
/******************************************************************************/
// Checks if entityID hostname of a valid IdP exists in path info
function getIdPPathInfoHint(){
global $IDProviders;
// Check if path info is available at all
if (!isset($_SERVER['PATH_INFO']) || empty($_SERVER['PATH_INFO'])){
return '-';
}
// Check for entityID hostnames of all available IdPs
foreach ($IDProviders as $key => $value){
// Only check actual IdPs
if (
isset($value['SSO'])
&& !empty($value['SSO'])
&& $value['Type'] != 'wayf'
&& isPartOfPathInfo(getHostNameFromURI($key))
){
return $key;
}
}
// Check for entityID domain names of all available IdPs
foreach ($IDProviders as $key => $value){
// Only check actual IdPs
if (
isset($value['SSO'])
&& !empty($value['SSO'])
&& $value['Type'] != 'wayf'
&& isPartOfPathInfo(getDomainNameFromURI($key))
){
return $key;
}
}
return '-';
}
/******************************************************************************/
// Parses the Kerbores realm out of the string and returns it
function composeOptionTitle($IdPValues){
$title = '';
foreach($IdPValues as $key => $value){
if (is_array($value) && isset($value['Name'])){
$title .= ' '.$value['Name'];
} elseif (is_array($value) && isset($value['Keywords'])) {
$title .= ' '.$value['Keywords'];
}
}
return $title;
}
/******************************************************************************/
// Parses the Kerbores realm out of the string and returns it
function getKerberosRealm($string){
global $IDProviders;
if ($string !='' ) {
// Find a matching Kerberos realm
foreach ($IDProviders as $key => $value){
if ($value['Realm'] == $string) return $key;
}
}
return '-';
}
/******************************************************************************/
// Determines the IdP according to the IP address if possible
function getIPAdressHint() {
global $IDProviders;
foreach($IDProviders as $name => $idp) {
if (is_array($idp) && array_key_exists("IP", $idp)) {
$clientIP = $_SERVER["REMOTE_ADDR"];
foreach( $idp["IP"] as $network ) {
if (isIPinCIDRBlock($network, $clientIP)) {
return $name;
}
}
}
}
return '-';
}
/******************************************************************************/
// Returns true if IP is in IPv4/IPv6 CIDR range
// and returns false otherwise
function isIPinCIDRBlock($cidr, $ip) {
// Split CIDR notation
list ($net, $mask) = preg_split ("|/|", $cidr);
// Convert to binary string value of 1s and 0s
$netAsBinary = convertIPtoBinaryForm($net);
$ipAsBinary = convertIPtoBinaryForm($ip);
// Return false if netmask and ip are using different protocols
if (strlen($netAsBinary) != strlen($ipAsBinary)){
return false;
}
// Compare the first $mask bits
for($i = 0; $i < $mask; $i++){
// Return false if bits don't match
if ($netAsBinary[$i] != $ipAsBinary[$i]){
return false;
}
}
// If we got here, ip matches net
return true;
}
/******************************************************************************/
// Converts IP in human readable format to binary string
function convertIPtoBinaryForm($ip){
// Handle IPv4 IP
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false){
return base_convert(ip2long($ip),10,2);
}
// Return false if IP is neither IPv4 nor a IPv6 IP
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false){
return false;
}
// Convert IP to binary structure and return false if this fails
if(($ipAsBinStructure = inet_pton($ip)) === false) {
return false;
}
$numOfBytes = 16;
$ipAsBinaryString = '';
// Convert IP to binary string
while ($numOfBytes > 0){
// Convert current byte to decimal number
$currentByte = ord($ipAsBinStructure[$numOfBytes - 1]);
// Convert currenty byte to string of 1 and 0
$currentByteAsBinary = sprintf("%08b", $currentByte);
// Prepend to rest of IP in binary string
$ipAsBinaryString = $currentByteAsBinary.$ipAsBinaryString;
// Decrease byte counter
$numOfBytes--;
}
return $ipAsBinaryString;
}
/******************************************************************************/
// Returns true if URL could be verified or if no check is necessary, false otherwise
function verifyReturnURL($entityID, $returnURL) {
global $SProviders, $useACURLsForReturnParamCheck;
// If SP has a