diff --git a/Classes/Controller/BesamlController.php b/Classes/Controller/BesamlController.php index ef67655..f63cedb 100644 --- a/Classes/Controller/BesamlController.php +++ b/Classes/Controller/BesamlController.php @@ -5,11 +5,25 @@ use Exception; use Miniorange\Helper\Constants; use PDO; +use DOMDocument; +use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Messaging\Renderer\ListRenderer; use Miniorange\Helper\CustomerSaml; +use TYPO3\CMS\Extbase\Domain\Repository\FrontendUserGroupRepository; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use Miniorange\Helper\Utilities; +use TYPO3\CMS\Tstemplate\Controller\TypoScriptTemplateModuleController; +use TYPO3\CMS\Extbase\Object\ObjectManager; +use Psr\Http\Message\ResponseInterface; +use TYPO3\CMS\Extbase\Persistence\Repository; +use Psr\Http\Message\ResponseFactoryInterface; +use TYPO3\CMS\Core\Information\Typo3Version; +use Miniorange\Helper\SAMLUtilities; +use Miniorange\Helper\IDPMetadataReader; +use Miniorange\Helper\IdentityProviders; +use Miniorange\Helper\SetRedirect; /** @@ -25,7 +39,7 @@ class BesamlController extends ActionController protected $response = null; - protected $tab = ""; + private $tab = null; /** * @var TYPO3\CMS\Extbase\Object\ObjectManagerInterface @@ -38,6 +52,37 @@ class BesamlController extends ActionController public function requestAction() { + //-------------Upload Metadata----------------------- + + if(isset($_POST['option']) and $_POST['option']=='upload_metadata_file') + { + Self::_handle_upload_metadata(); + } + //----------- Download metadata--------------- + if(isset($_POST['option']) and $_POST['option']=='mosaml_metadata_download') + { + $value1 = $this->validateURL($_POST['site_base_url']); + $value2 = $this->validateURL($_POST['acs_url']); + $value3 = $this->validateURL($_POST['sp_entity_id']); + + if($value1 == 1 && $value2 == 1 && $value3 == 1) + { + SAMLUtilities::mo_saml_miniorange_generate_metadata(true); + } + else{ + Utilities::showErrorFlashMessage('Fill all the fields to download the metadata file'); + } + + } + + + //---------------show Metadata------------------------- + + if(isset($_POST['option']) and $_POST['option']=='mosaml_metadata') + { + SAMLUtilities::mo_saml_miniorange_generate_metadata(); + } + //------------ IDENTITY PROVIDER SETTINGS--------------- if(isset($_POST['option']) and $_POST['option'] == 'idp_settings'){ @@ -59,11 +104,6 @@ public function requestAction() } } -//------------ HANDLING SUPPORT QUERY--------------- - elseif ( isset( $_POST['option'] ) and $_POST['option'] == "mo_saml_contact_us_query_option" ) { - $this->support(); - } - //------------ VERIFY CUSTOMER--------------- elseif ( isset( $_POST['option'] ) and $_POST['option'] == "mo_saml_verify_customer" ) { @@ -114,6 +154,7 @@ public function requestAction() } //------------ CHANGING TABS--------------- +if(!empty($_POST['option'])){ if($_POST['option'] == 'save_sp_settings' ) { $this->tab = "Service_Provider"; @@ -134,6 +175,7 @@ public function requestAction() { $this->tab = "Identity_Provider"; } + } $this->objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); $allUserGroups= $this->objectManager->get('TYPO3\\CMS\\Extbase\\Domain\\Repository\\FrontendUserGroupRepository')->findAll(); @@ -145,24 +187,15 @@ public function requestAction() $this->view->assign('conf_idp', json_decode($this->fetch('object'), true)); $this->view->assign('conf_sp', json_decode($this->fetch('spobject'), true)); -//------------ LOADING VARIABLES TO BE USED IN VIEW--------------- -// if($this->fetch_cust(Constants::CUSTOMER_REGSTATUS) == 'logged'){ -// $this->view->assign('status','logged'); -// $this->view->assign('log', ''); -// $this->view->assign('nolog', 'display:none'); -// $this->view->assign('email',$this->fetch_cust('cust_email')); -// $this->view->assign('key',$this->fetch_cust('cust_key')); -// $this->view->assign('token',$this->fetch_cust('cust_token')); -// $this->view->assign('api_key',$this->fetch_cust('cust_api_key')); -// }else{ -// $this->view->assign('log', 'disabled'); -// $this->view->assign('nolog', 'display:block'); -// $this->view->assign('status','not_logged'); -// } - $this->view->assign('tab', $this->tab); $this->view->assign('extPath', Utilities::getExtensionRelativePath()); - $this->cacheService->clearPageCache([$GLOBALS['TSFE']->id]); + // $this->cacheService->clearPageCache([$GLOBALS['TSFE']->id]); + GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->flushCaches(); + + return $this->responseFactory->createResponse() + ->withAddedHeader('Content-Type', 'text/html; charset=utf-8') + ->withBody($this->streamFactory->createStream($this->view->render())); + } public function save($column,$value,$table) @@ -179,13 +212,24 @@ public function remove_cust(){ $this->update_cust('cust_reg_status', ''); $this->update_cust('cust_email',''); -// $this->update_saml_setting('idp_name',""); -// $this->update_saml_setting('idp_entity_id',""); -// $this->update_saml_setting('saml_login_url',""); -// $this->update_saml_setting('saml_logout_url',""); -// $this->update_saml_setting('x509_certificate',""); -// $this->update_saml_setting('login_binding_type',""); -// $this->update_saml_setting('object',""); + } + + public static function generic_update_query($database_name, $updatefieldsarray){ + $idp_obj = json_encode($updatefieldsarray); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('saml'); + foreach ($updatefieldsarray as $key => $value) + { + //$queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT)))->set($key, $value)->execute(); + if($key == 'idp_entity_id') + { + $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT)))->set('idp_entity_id', $value)->execute(); + + } + $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT)))->set('object', $idp_obj)->execute(); + + } + + Utilities::showSuccessFlashMessage('IDP Setting saved successfully.'); } // VALIDATE CERTIFICATE @@ -307,34 +351,6 @@ public function insertValue() $affectedRows = $queryBuilder->insert('customer')->values([ 'id' => '1' ])->execute(); } -// --------------------SUPPORT QUERY--------------------- - public function support(){ - if(!$this->mo_saml_is_curl_installed() ) { - Utilities::showErrorFlashMessage('ERROR: PHP cURL extension is not installed or disabled. Query submit failed.'); - return; - } - // Contact Us query - $email = $_POST['mo_saml_contact_us_email']; - $phone = $_POST['mo_saml_contact_us_phone']; - $query = $_POST['mo_saml_contact_us_query']; - - $customer = new CustomerSaml(); - - if($this->mo_saml_check_empty_or_null( $email ) || $this->mo_saml_check_empty_or_null( $query ) ) { - Utilities::showErrorFlashMessage('Please enter a valid Email address. '); - }elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)) { - Utilities::showErrorFlashMessage('Please enter a valid Email address. '); - }else { - $submitted = json_decode($customer->submit_contact( $email, $phone, $query ), true); - if ( $submitted['status'] == 'SUCCESS' ) { - Utilities::showSuccessFlashMessage('Support query sent ! We will get in touch with you shortly.'); - }else{ - Utilities::showErrorFlashMessage('could not send query. Please try again later or mail us at info@miniorange.com'); - } - } - } - /** * @param $var * @return bool|string @@ -402,20 +418,85 @@ public function storeToDatabase($creds) }else { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('saml'); + if(!empty($creds['idp_name'])) $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT))) ->set('idp_name', $creds['idp_name'])->execute(); + if(!empty($creds['idp_entity_id'])) $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT))) ->set('idp_entity_id', $creds['idp_entity_id'])->execute(); + if(!empty($creds['saml_login_url'])) $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT))) ->set('saml_login_url', $creds['saml_login_url'])->execute(); + if(!empty($creds['saml_logout_url'])) $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT))) ->set('saml_logout_url', $creds['saml_logout_url'])->execute(); $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT))) ->set('login_binding_type', Constants::HTTP_REDIRECT)->execute(); + if(!empty($creds['x509_certificate'])) $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT))) ->set('x509_certificate', $creds['x509_certificate'])->execute(); $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT))) ->set('object', $this->myjson)->execute(); } } + + public static function _handle_upload_metadata() { + $obj1= new BesamlController(); + if (isset($_FILES['metadata_file']) || isset($_POST['upload_url'])) { + if (!empty($_FILES['metadata_file']['tmp_name'])) { + $file = @file_get_contents($_FILES['metadata_file']['tmp_name']); + } else { + $url = filter_var($_POST['upload_url'], FILTER_SANITIZE_URL); + $arrContextOptions = array( + "ssl" => array( + "verify_peer" => false, + "verify_peer_name" => false, + ), + ); + if (empty($url)) { + Utilities::showErrorFlashMessage('No Metadata File/URL Provided.'); + return; + } else { + $file = file_get_contents($url, false, stream_context_create($arrContextOptions)); + } + } + self::upload_metadata($file); + } + } + + public static function upload_metadata($file) { + $besaml=new BesamlController(); + $document = new DOMDocument(); + $document->loadXML($file); + restore_error_handler(); + $first_child = $document->firstChild; + if (!empty($first_child)) { + $metadata = new IDPMetadataReader($document); + $identity_providers = $metadata->getIdentityProviders(); + if (empty($identity_providers)) { + Utilities::showErrorFlashMessage('Please provide valid metadata.'); + + return; + } + foreach ($identity_providers as $key => $idp) { + $saml_login_url = $idp->getLoginURL('HTTP-Redirect'); + $saml_issuer = $idp->getEntityID(); + $saml_x509_certificate = $idp->getSigningCertificate(); + $database_name = 'saml'; + $updatefieldsarray = array( + 'idp_entity_id' => isset($saml_issuer) ? $saml_issuer : 0, + 'saml_login_url' => isset($saml_login_url) ? $saml_login_url : 0, + 'login_binding_type' => 'HttpRedirect', + 'x509_certificate' => isset($saml_x509_certificate) ? $saml_x509_certificate[0] : 0, + ); + + self::generic_update_query($database_name, $updatefieldsarray); + break; + } + return; + } else { + + return; + } + } } diff --git a/Classes/Controller/FesamlController.php b/Classes/Controller/FesamlController.php index 34a03ab..eac5f47 100644 --- a/Classes/Controller/FesamlController.php +++ b/Classes/Controller/FesamlController.php @@ -13,18 +13,14 @@ use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use Miniorange\Helper\lib\XMLSecLibs\XMLSecurityKey; +use TYPO3\CMS\Tstemplate\Controller\TypoScriptTemplateModuleController; +use TYPO3\CMS\Core\Database\Connection; + /** * FesamlController */ class FesamlController extends ActionController { -// /** -// * fesamlRepository -// * -// * @var \Miniorange\MiniorangeSaml\Domain\Repository\FesamlRepository -// * @inject -// */ -// protected $fesamlRepository = null; protected $idp_name = null; @@ -85,17 +81,26 @@ class FesamlController extends ActionController */ public function requestAction() { - $this->cacheService->clearPageCache([$GLOBALS['TSFE']->id]); + if(isset($_REQUEST['option']) and $_REQUEST['option']=='mosaml_metadata') + { + SAMLUtilities::mo_saml_miniorange_generate_metadata(); + } + error_log("relaystate : ".print_r($_REQUEST,true)); $this->controlAction(); - $this->bindingType = Constants::HTTP_REDIRECT; $samlRequest = $this->build(); $relayState = isset($_REQUEST['RelayState']) ? $_REQUEST['RelayState'] : '/'; - + if ($this->findSubstring($_REQUEST) == 1) { $relayState = 'testconfig'; } + + + GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->flushCaches(); + + $this->controlAction(); + error_log("relaystate : ".$relayState); $this->sendHTTPRedirectRequest($samlRequest, $relayState, $this->saml_login_url); @@ -108,7 +113,7 @@ public function requestAction() */ public function findSubstring($request) { - if (strpos($request["id"], 'RelayState') !== false) { + if (!empty($request["id"]) && strpos($request["id"], 'RelayState') !== false) { return 1; }else{ return 0; @@ -144,7 +149,6 @@ public function controlAction() public function build() { - //$pluginSettings=PluginSettings::getPluginSettings(); $requestXmlStr = $this->generateXML(); if (empty($this->bindingType) || $this->bindingType == Constants::HTTP_REDIRECT) { $deflatedStr = gzdeflate($requestXmlStr); @@ -165,17 +169,9 @@ public function sendHTTPRedirectRequest($samlRequest, $sendRelayState, $idpUrl) { $samlRequest = 'SAMLRequest=' . $samlRequest . '&RelayState=' . urlencode($sendRelayState) . '&SigAlg=' . urlencode(XMLSecurityKey::RSA_SHA256); $param = ['type' => 'private']; -// $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, $param); -// $certFilePath = file_get_contents(Utilities::getBaseUrl().Utilities::getResourceDir(). 'sp-key.key'); -// $key->loadKey($certFilePath); -// $signature = $key->signData($samlRequest); -// $signature = base64_encode($signature); $redirect = $idpUrl; $redirect .= strpos($idpUrl, '?') !== false ? '&' : '?'; $redirect .= $samlRequest ; -// .'&Signature=' . urlencode($signature); - //var_dump - //($redirect);exit; if (isset($_REQUEST)) { header('Location:' . $redirect); die; diff --git a/Classes/Controller/ResponseController.php b/Classes/Controller/ResponseController.php index b570dd4..faf0d26 100644 --- a/Classes/Controller/ResponseController.php +++ b/Classes/Controller/ResponseController.php @@ -12,6 +12,7 @@ use Miniorange\Helper\Exception\InvalidSignatureInResponseException; use Miniorange\Helper\SAMLUtilities; use Miniorange\Helper\Utilities; +use PDO; use ReflectionClass; use ReflectionException; use TYPO3\CMS\Core\Crypto\Random; @@ -31,6 +32,11 @@ use TYPO3\CMS\Extbase\Annotation\Inject; use TYPO3\CMS\Core\Utility\HttpUtility; +use Psr\Http\Message\ResponseFactoryInterface; +use TYPO3\CMS\Core\Session\UserSessionManager; +use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; +use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication; + /** * ResponseController */ @@ -75,9 +81,7 @@ class ResponseController extends ActionController public function responseAction() { - $this->cacheService->clearPageCache([$GLOBALS['TSFE']->id]); -// error_log("in ResponseController: "); //.print_r($_REQUEST,true) - + GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->flushCaches(); if (array_key_exists('SAMLResponse', $_REQUEST) && !empty($_REQUEST['SAMLResponse'])) { $samlResponseObj = ReadResponseAction::execute(); @@ -149,37 +153,42 @@ public function responseAction() */ public function createIfNotExist($username) { -// $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); - $objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); $user = Utilities::fetchUserFromUsername($username); - debug("User Search 1 : ".$user); if($user == false){ - $frontendUser = new FrontendUser(); - $frontendUser->setUsername($username); - - $frontendUser->setFirstName($this->first_name); - $frontendUser->setLastName($this->last_name); - $frontendUser->setEmail($this->ssoemail); - $frontendUser->setPassword(SAMLUtilities::generateRandomAlphanumericValue(10)); //Setting Random Password - - $mappedGroupUid = Utilities::fetchUidFromGroupName(Utilities::fetchFromTable(Constants::COLUMN_GROUP_DEFAULT,Constants::TABLE_SAML)); - $userGroup = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Domain\\Repository\\FrontendUserGroupRepository')->findByUid($mappedGroupUid); - - if($userGroup!=null){ - $frontendUser->addUsergroup($userGroup); - }else{ - exit("Unable to create User. No UserGroup found."); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(Constants::TABLE_SAML); + $count = $queryBuilder->select('countuser')->from(Constants::TABLE_SAML)->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT)))->execute()->fetchColumn(0); + if($count>0) + { + $frontendUser = new FrontendUser(); + $frontendUser->setUsername($username); + $fnamelname = explode("@", $username); + $this->first_name = $fnamelname[0]; + $this->last_name = $fnamelname[1]; + $frontendUser->setFirstName($this->first_name); + $frontendUser->setLastName($this->last_name); + $frontendUser->setEmail($this->ssoemail); + $frontendUser->setPassword(SAMLUtilities::generateRandomAlphanumericValue(10)); //Setting Random Password + + $mappedGroupUid = Utilities::fetchUidFromGroupName(Utilities::fetchFromTable(Constants::COLUMN_GROUP_DEFAULT,Constants::TABLE_SAML)); + $userGroup = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Domain\\Repository\\FrontendUserGroupRepository')->findByUid($mappedGroupUid); + if($userGroup!=null){ + $frontendUser->addUsergroup($userGroup); + }else{ + exit("Unable to create User. No UserGroup found."); + } + $queryBuilder->update('saml')->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(1, PDO::PARAM_INT)))->set('countuser', $count-1)->execute(); + $this->frontendUserRepository = $objectManager->get('TYPO3\\CMS\\Extbase\\Domain\\Repository\\FrontendUserRepository')->add($frontendUser); + $this->persistenceManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager')->persistAll(); + $user = Utilities::fetchUserFromUsername($username); + return $user; } - - $this->frontendUserRepository = $objectManager->get('TYPO3\\CMS\\Extbase\\Domain\\Repository\\FrontendUserRepository')->add($frontendUser); - $this->persistenceManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager')->persistAll(); - $user = Utilities::fetchUserFromUsername($username); - debug("User Search 1 : ".$user); - - return $user; - - }else{ + else + { + echo "User limit exceeded!!!";exit; + } + } + else{ if($user['disable'] == 1){ exit("You are not allowed to login. Please contact your admin."); } diff --git a/Helper/Actions/ReadResponseAction.php b/Helper/Actions/ReadResponseAction.php index f011da9..3a8cd98 100644 --- a/Helper/Actions/ReadResponseAction.php +++ b/Helper/Actions/ReadResponseAction.php @@ -19,7 +19,7 @@ class ReadResponseAction */ public static function execute() { - + // read the response $samlResponse = $_REQUEST['SAMLResponse']; $relayState = array_key_exists('RelayState', $_REQUEST) ? $_REQUEST['RelayState'] : '/'; diff --git a/Helper/IDPMetadataReader.php b/Helper/IDPMetadataReader.php new file mode 100644 index 0000000..5f6ce4a --- /dev/null +++ b/Helper/IDPMetadataReader.php @@ -0,0 +1,44 @@ +identityProviders = array(); + $this->serviceProviders = array(); + + $entityDescriptors = SAMLUtilities::xpQuery($xml, './saml_metadata:EntityDescriptor'); + + foreach ($entityDescriptors as $entityDescriptor) { + $idpSSODescriptor = SAMLUtilities::xpQuery($entityDescriptor, './saml_metadata:IDPSSODescriptor'); + + if(isset($idpSSODescriptor) && !empty($idpSSODescriptor)){ + array_push($this->identityProviders,new IdentityProviders($entityDescriptor)); + } + //TODO: add sp descriptor + } + } + + public function getIdentityProviders(){ + return $this->identityProviders; + } + + public function getServiceProviders(){ + return $this->serviceProviders; + } + +} \ No newline at end of file diff --git a/Helper/IdentityProviders.php b/Helper/IdentityProviders.php new file mode 100644 index 0000000..7637442 --- /dev/null +++ b/Helper/IdentityProviders.php @@ -0,0 +1,157 @@ +idpName = ''; + $this->loginDetails = array(); + $this->logoutDetails = array(); + $this->signingCertificate = array(); + $this->encryptionCertificate = array(); + + if ($xml->hasAttribute('entityID')) { + $this->entityID = $xml->getAttribute('entityID'); + } + + if($xml->hasAttribute('WantAuthnRequestsSigned')){ + $this->signedRequest = $xml->getAttribute('WantAuthnRequestsSigned'); + } + + $idpSSODescriptor = SAMLUtilities::xpQuery($xml, './saml_metadata:IDPSSODescriptor'); + + if (count($idpSSODescriptor) > 1) { + throw new Exception('More than one in .'); + } elseif (empty($idpSSODescriptor)) { + throw new Exception('Missing required in .'); + } + $idpSSODescriptorEL = $idpSSODescriptor[0]; + + $info = SAMLUtilities::xpQuery($xml, './saml_metadata:Extensions'); + + if($info) + $this->parseInfo($idpSSODescriptorEL); + $this->parseSSOService($idpSSODescriptorEL); + $this->parseSLOService($idpSSODescriptorEL); + $this->parsex509Certificate($idpSSODescriptorEL); + +} + +private function parseInfo($xml){ + $displayNames = SAMLUtilities::xpQuery($xml, './mdui:UIInfo/mdui:DisplayName'); + foreach ($displayNames as $name) { + if($name->hasAttribute('xml:lang') && $name->getAttribute('xml:lang')=="en"){ + $this->idpName = $name->textContent; + } + } +} + +private function parseSSOService($xml){ + $ssoServices = SAMLUtilities::xpQuery($xml, './saml_metadata:SingleSignOnService'); + foreach ($ssoServices as $ssoService) { + $binding = str_replace("urn:oasis:names:tc:SAML:2.0:bindings:","",$ssoService->getAttribute('Binding')); + $this->loginDetails = array_merge( + $this->loginDetails, + array($binding => $ssoService->getAttribute('Location')) + ); + } +} + +private function parseSLOService($xml){ + $sloServices = SAMLUtilities::xpQuery($xml, './saml_metadata:SingleLogoutService'); + foreach ($sloServices as $sloService) { + $binding = str_replace("urn:oasis:names:tc:SAML:2.0:bindings:","",$sloService->getAttribute('Binding')); + $this->logoutDetails = array_merge( + $this->logoutDetails, + array($binding => $sloService->getAttribute('Location')) + ); + } +} + +private function parsex509Certificate($xml){ + foreach ( SAMLUtilities::xpQuery($xml, './saml_metadata:KeyDescriptor') as $KeyDescriptorNode ) { + if($KeyDescriptorNode->hasAttribute('use')){ + if($KeyDescriptorNode->getAttribute('use')=='encryption'){ + $this->parseEncryptionCertificate($KeyDescriptorNode); + }else{ + $this->parseSigningCertificate($KeyDescriptorNode); + } + }else{ + $this->parseSigningCertificate($KeyDescriptorNode); + } + } +} + +private function parseSigningCertificate($xml){ + $certNode = SAMLUtilities::xpQuery($xml, './ds:KeyInfo/ds:X509Data/ds:X509Certificate'); + $certData = trim($certNode[0]->textContent); + $certData = str_replace(array ( "\r", "\n", "\t", ' '), '', $certData); + if(!empty($certNode)) + array_push($this->signingCertificate, SAMLUtilities::sanitize_certificate( $certData )); +} + + +private function parseEncryptionCertificate($xml){ + $certNode = SAMLUtilities::xpQuery($xml, './ds:KeyInfo/ds:X509Data/ds:X509Certificate'); + $certData = trim($certNode[0]->textContent); + $certData = str_replace(array ( "\r", "\n", "\t", ' '), '', $certData); + if(!empty($certNode)) + array_push($this->encryptionCertificate, $certData); +} + +public function getIdpName(){ + return ""; +} + +public function getEntityID(){ + return $this->entityID; +} + +public function getLoginURL($binding){ + return $this->loginDetails[$binding]; +} + +public function getLogoutURL($binding){ + return $this->logoutDetails[$binding]; +} + +public function getLoginDetails(){ + return $this->loginDetails; +} + +public function getLogoutDetails(){ + return $this->logoutDetails; +} + +public function getSigningCertificate(){ + return $this->signingCertificate; +} + +public function getEncryptionCertificate(){ + return $this->encryptionCertificate[0]; +} + +public function isRequestSigned(){ + return $this->signedRequest; +} + +} diff --git a/Helper/SAMLUtilities.php b/Helper/SAMLUtilities.php index 4a3eec5..a4fa88b 100644 --- a/Helper/SAMLUtilities.php +++ b/Helper/SAMLUtilities.php @@ -6,13 +6,15 @@ use DOMNode; use DOMDocument; use Exception; +use PDO; use Miniorange\Helper\lib\XMLSecLibs\XMLSecurityKey; use Miniorange\Helper\lib\XMLSecLibs\XMLSecEnc; use Miniorange\Helper\lib\XMLSecLibs\XMLSecurityDSig; +use Miniorange\Helper\lib\XMLSecLibs\Utils\XPath; /** @todo - optimize this class */ -class SAMLUtilities +class SAMLUtilities extends Utilities { public static function generateID() @@ -650,4 +652,43 @@ public static function generateRandomAlphanumericValue($length) $uniqueID .= substr($chars,rand(0,15),1); return 'a'.$uniqueID; } + + //---------------------Generate Metadata------------------- + + public static function mo_saml_miniorange_generate_metadata($download=false) { + $sp_base_url = self::fetchFromTable('site_base_url',Constants::TABLE_SAML); + $sp_response_url= self::fetchFromTable('response',Constants::TABLE_SAML); + $sp_entity_id = self::fetchFromTable('sp_entity_id',Constants::TABLE_SAML); + + $entity_id = $sp_entity_id; + $acs_url = $sp_response_url; + if(ob_get_contents()) + ob_clean(); + + header('Content-Type: text/rss+xml; charset=utf-8'); + if($download) + header('Content-Disposition: attachment; filename="Metadata.xml"'); + + echo ' + + urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + + + + miniOrange + miniOrange + http://miniorange.com + + + miniOrange + info@xecurify.com + + + miniOrange + info@xecurify.com + + '; + exit; + + } } diff --git a/Helper/SetRedirect b/Helper/SetRedirect new file mode 100644 index 0000000..2558075 --- /dev/null +++ b/Helper/SetRedirect @@ -0,0 +1,42 @@ +redirect = $url; + + if ($msg !== null) + { + // Controller may have set this directly + $this->message = $msg; + } + + // Ensure the type is not overwritten by a previous call to setMessage. + if (empty($type)) + { + if (empty($besaml->messageType)) + { + $this->messageType = 'message'; + } + } + // If the type is explicitly set, set it. + else + { + $this->messageType = $type; + } + // echo print_r($besaml,true);exit; + return $besaml; + } + +} \ No newline at end of file diff --git a/Helper/resources/js/backend.js b/Helper/resources/js/backend.js index 4b83349..2aded14 100644 --- a/Helper/resources/js/backend.js +++ b/Helper/resources/js/backend.js @@ -7,8 +7,6 @@ $(document).ready(function() { if (session == "Service_Provider"){ openTab('Service_Provider'); - }else if(session == "Support"){ - openTab( 'Support'); }else if(session == "Attribute_Mapping") { openTab( 'Attribute_Mapping'); }else if(session == "Group_Mapping") { @@ -37,14 +35,7 @@ function openTab(activeTab) { document.getElementById(activeTab).style.display = "block"; - // if(activeTab==="Support"){ - // document.getElementById("Support_Tab").className += " active"; - // document.getElementById("leftContainer").hidden = true; - // }else{ - // document.getElementById(activeTab).style.display = "block"; document.getElementById(activeTab + "_Tab").className += " active"; - // document.getElementById("leftContainer").hidden = false; - // } } //remove flash messages diff --git a/Helper/resources/sp-certificate.crt b/Helper/resources/sp-certificate.crt new file mode 100644 index 0000000..4781a9b --- /dev/null +++ b/Helper/resources/sp-certificate.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDoTCCAokCFAkYOm9dmoCuy2scWoVezjHAIYInMA0GCSqGSIb3DQEBCwUAMIGM +MQswCQYDVQQGEwJJTjELMAkGA1UECAwCTUgxDTALBgNVBAcMBFBVTkUxEzARBgNV +BAoMCk1JTklPUkFOR0UxEzARBgNVBAsMCk1JTklPUkFOR0UxEzARBgNVBAMMCk1J +TklPUkFOR0UxIjAgBgkqhkiG9w0BCQEWE2luZm9AbWluaW9yYW5nZS5jb20wHhcN +MjIwMjIxMTExNjAyWhcNMjcwMjIwMTExNjAyWjCBjDELMAkGA1UEBhMCSU4xCzAJ +BgNVBAgMAk1IMQ0wCwYDVQQHDARQVU5FMRMwEQYDVQQKDApNSU5JT1JBTkdFMRMw +EQYDVQQLDApNSU5JT1JBTkdFMRMwEQYDVQQDDApNSU5JT1JBTkdFMSIwIAYJKoZI +hvcNAQkBFhNpbmZvQG1pbmlvcmFuZ2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4Dp+Gm15FArPhyGw44CMOXvHuXOsU4RNGm5rpB4LRZh8eGOQ +aJPBck3s8oM0lOE2jugxuBtPBFlM0LT4hdWo/wfSPFvbcXvKegz9DXPGd7pCfJ34 +N++g259sKTB8/EtwpfqCd06SPIQ/+LpPgihULQfGOpHz/hB7vCZO0uHO0pZw2gvt +mA1uJ5r9EFm+t6gAo0H87t3D/0Re8YLsu/mJTasEaAAadA39DdrK5LjBHR7ua716 +u7p69Wh84QAV6G78ySGeovzubtq0+wdFdM2P/qVrecI/OgMZUee1HtJ4QSNPESPY +2vIsMi1qA4oJOHK3dmnM9rqDqDI3KSo4syvr4QIDAQABMA0GCSqGSIb3DQEBCwUA +A4IBAQBVRch/h7SrDn8rmdZmf91hNoE5fn0R4AcYUhpKcJw9Jx3Dy9pJFczao3e0 +ni4vx59dyVbTR4pRyvsm1XvT165vGW1McYbNwA0yLbpJkM2TdrS4ydb0RukoCyJy +RxRya+dWZgrmCKlYMaAJmXsD5P3EvGHdeBIYBwHeZSaq2LEvq8BdBoK9nHkpT6Si +I/zgrEiy3Cy2GZO9L9NEGydb9f8cqWzQKYIH5Yh7SMb5fP6QE26MiKxaVATw26e8 +WWMBwGCbafSjBa2H5Zaj//uHlQFmgbopCe6m2lIq0YGkWNpPt4jUbswGolVF/408 +hntu8CcHMp+Rx5pL7aLdGfKri6Ly +-----END CERTIFICATE----- diff --git a/Helper/resources/sp-certificate.key b/Helper/resources/sp-certificate.key new file mode 100644 index 0000000..3983f17 --- /dev/null +++ b/Helper/resources/sp-certificate.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDgOn4abXkUCs+H +IbDjgIw5e8e5c6xThE0abmukHgtFmHx4Y5Bok8FyTezygzSU4TaO6DG4G08EWUzQ +tPiF1aj/B9I8W9txe8p6DP0Nc8Z3ukJ8nfg376Dbn2wpMHz8S3Cl+oJ3TpI8hD/4 +uk+CKFQtB8Y6kfP+EHu8Jk7S4c7SlnDaC+2YDW4nmv0QWb63qACjQfzu3cP/RF7x +guy7+YlNqwRoABp0Df0N2srkuMEdHu5rvXq7unr1aHzhABXobvzJIZ6i/O5u2rT7 +B0V0zY/+pWt5wj86AxlR57Ue0nhBI08RI9ja8iwyLWoDigk4crd2acz2uoOoMjcp +KjizK+vhAgMBAAECggEBAKuXF3lR3R4hR765YYw3ixdSSfz5MB6ZWAeqCGWHOEkB +7/6Q8qmUqKy4RWMwVMS5s+6YcbPZ8hX54Ha2hpikcLb5XUEjakLl4ISV+/CXcIGe +39JNcO4dSpPG5BaBLKRFducNVVnHntEAw5Orv7xy8Delg2S+3GDIbGgHSLrIYmVz +nAwnp8rgvsI2wkW+w9jQqjkgOd4LULO+4qss/wev3+lhCtDRAPwhcA4LboYaJkby +fAf7hWA3Nn3SBJuKpzKe9Dy5dxyi84COixphdpCAs1eOCw0poZpsab9DRS24HlqD +RKZdc7YhSYBNqCXfYQLvGdshfJzvAGP5EhE5Evaet6ECgYEA9WYrDv3pBglpAg/a +HVP1UwBvJnFmemfyXy49EivlszjWvHpnZ/b362psRQ7+3b5hQZ16rU+aIbGKpb3q +gKy3Js+oHRPVzY9B++3zefHj6WNt+T/nlK4MqmixOlwitPSIP4zExH3tfg2zHytt +vxjoMb3YOwWhWbkMfqMizqE4KocCgYEA6eozqh13tBkvYonn6sYMa4N9b06E5GeV +1eVAAMLiBMAXBrQpaQoe8yL8MyzdzSZXu8el18aN6vuLLRvmpgfdsk5X4OutJqd6 +SA21F38zTI/bbgDnsvqjT5ypKi+w95i3KPMREoxcw9vqq5tuSyxSeJnst49HKJy7 +rhlEXGREyFcCgYEAlalOv2DpWc4pZaGHU3Wd25YbM6XbavG0JopLoqZ0+13B0McS +A5ziTIfmKiPgGhp+tAa4B7TRepUNytFNkFZFiP0COWGcdjZVdrEDWa7FYdRLAMUR +lmKjxNX+qGoCnLu50JAofPGUAtmWEX9p+i7VhWiT1EM1yUOLNDyIAN7gI0cCgYAf +QlMBKsryYGM6sd8yOqEyRPIgS8fqlgUp/mbdMy3tIJZzKORXyyhzqXs2g4poffU/ +fOCmwzv36QGiV5YtHeP8jgekYRpUjhEDTAGlUDRUyOyz+J7+BgyI+RCKOLFXhSsE +5+aiKevDqMHliPHmTdf/keJWbWk+/iL+kxXVmviuJQKBgCqX2pQuaBDYHbTsxOv2 +tsJ8s1u3W98eAPHt4KyphCWeYDgFCRlSJvU937QRBba8quFo/4Ir2e3MwiXAgS6T +TkBmBSa/hgMmumspgmDx6r7cnKqBxL3x5+vwOvbBUAbsZZm9tp3Dtfp6gkTQlyfo +UJAIAB7iOfEp/vzIL3zPjFhU +-----END PRIVATE KEY----- diff --git a/Resources/Private/Templates/Besaml/Request.html b/Resources/Private/Templates/Besaml/Request.html index 1a368fa..48e528b 100644 --- a/Resources/Private/Templates/Besaml/Request.html +++ b/Resources/Private/Templates/Besaml/Request.html @@ -61,7 +61,6 @@ SP Settings Attribute Mapping Group Mapping - Get Premium @@ -77,8 +76,34 @@ Identity Provider Settings + + + + + Upload IDP XML Metadata + + + + + + Upload File: + + + OR + + Upload URL: + + + + + + Upload + Cancel + + + Upload IDP Metadata Identity Provider Name* @@ -229,6 +254,19 @@ Service Provider Settings Save Click Here for User Guide + + Metadata URL : + Show Metadata   + + Copy to clipboardCopy URL + + + + + + You can download the metadata XML from here : + Download + @@ -389,8 +427,141 @@ Map Typo3 Groups to IDP Groups - + + + +