diff --git a/modules/InfoCard/README.txt b/modules/InfoCard/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..43278eb77498a6a98a41b1e3b8400eb5e9476580 --- /dev/null +++ b/modules/InfoCard/README.txt @@ -0,0 +1,77 @@ +/* +* AUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: What you should read before starting doing things. +*/ + +WARNING: THIS IS NOT mature software, it's released with testing, educational, developing purposes. It's on a very early version, so don't rely the life of anybody on it. + + + +------------ INFORMATION CARDS MODULE FOR SIMPLESAMLPHP ----------------------- + + +INTRODUCTION: + This is a simpleSAMLphp module that works with Information Cards techcnologies and provides two basic functionalities: + -RP + Acting as a Relying Party, you can accept user authentication through InfoCards comsumming tokens sent by aSTS. + + -STS + Acting as a Secure Token Service you can provide information to a RP generating tokens. Currently, only user-password authentication is supported. + + -InfoCard Generator + Your users could request their InfoCard filling a form with their username and password. + + +VERY IMPORTANT: + This document is not a strict guide, I mean it might have some errors or missed information. I've tried to comment almost every trick i've used to make the system work and make your life easier. So, if at any point of the installation you feel lost, breathe twice, think for ten minutes in what you are trying to do, read again the documentation and use your common sense. It'll be usefull when you'll face again the configuration file. + + +BASIC INSTALLATION: + 1. Copy the InfoCard folder in your modules directoy in your SimpleSAMLphp installation directory. + 2. Copy (or move) the file modules/InfoCard/extra/config-login-infocard.php to the config directory in your SimpleSAMLphp installation directory. + 3. Edit the config/config-login-infocard.php file, you should configure some values like: help_desk_email_URL, contact_info_URL, server_key, server_crt, sts_crt, requiredClaims and optionalClaims to feet your needs. + 4. Edit the config/authsources.php file, add this text before the last ); + 'InfoCard' => array( + 'InfoCard:ICAuth', + ), + 5. That's all. + + +ADDING AND INFOCARD GENERATOR: + 1. Go into the modules/InfoCard folder. + 2. Copy extra/getinfocard.php to www/getinfocard.php + 3. Edit the config/config-login-infocard.php file and uncomment this line +// 'CardGenerator' => 'getinfocard.php', (delete the two //). + 4. Following the previous example, uncomment this values:certificates, sts_key, tokenserviceurl and mexurl. + 6. Check the previous values andm modify them if you need. + 5. Read the USER FUNCTIONS section. + + +ADDING THE STS FUNCTIONALITY + 1. Go into the modules/InfoCard folder. + 2. Copy extra/mex.php and extra/tokenservice.php to the www folder. + 3. Edit the config/config-login-infocard.php file and uncomment the values: certificates and sts_key. + 4. Read the USER FUNCTIONS section. + + +USER FUNCTIONS + Because there are many authentication issues I cannot guess for you, you'll have to code a little bit to fit this module to your authentication system. + We we'll work with the file UserFunctions.php located in modules/InfoCard/lib/ + + validateUser, it receives two strings, username and password, you do the validation (against your database?) and return true if you want to validate the user or false instead. + + fillClaims, it's used by the tokenservice to give information about the user to the relying party. It receives the username, the configured required and optional claims and the claims requested by the RP. + It works filling the claimValues array and your job is the ensure the 'value' variable ($claimValues[$claim]['value']= ) of the array gets the value you want. Understand that requested values and your configured ones could not match. + + fillICdata, it's used by the card generator to retrieve needed information. It receives an authenticated username and returns an array containing information such as the card name, the card image, the expiring time, etc. + + +CERTIFICATES AND HOSTS + The architecture is composed by three independent elements: + -User: Identity Selector + -IDP: Relying Party + -STS: IC and token generation. + + That's because you should configure two hosts (with two x509 certificates) if you want two have the IDP and STS functionalities in the same machine. \ No newline at end of file diff --git a/modules/InfoCard/dictionaries/logininfocard.php b/modules/InfoCard/dictionaries/logininfocard.php index 8d8dfa65c0f942bfdcda52795f5a3c7adaeeb0e2..a8525b813cdc43acdb147a3138231541e6abfb64 100644 --- a/modules/InfoCard/dictionaries/logininfocard.php +++ b/modules/InfoCard/dictionaries/logininfocard.php @@ -3,7 +3,7 @@ /* * AUTHOR: Samuel Muñoz Hidalgo * EMAIL: samuel.mh@gmail.com -* LAST REVISION: 1-DEC-08 +* LAST REVISION: 16-DEC-08 * DESCRIPTION: 'login-infocard' module dictionary. */ @@ -26,6 +26,60 @@ $lang = array( 'pt' => '', 'pt-BR' => '', ), + 'get_IC' => array ( + 'no' => '', + 'nn' => '', + 'da' => '', + 'en' => 'Get your InfoCard', + 'de' => '', + 'sv' => '', + 'fi' => '', + 'es' => 'Consiga su InfoCard', + 'fr' => '', + 'nl' => '', + 'lb' => '', + 'sl' => '', + 'hr' => '', + 'hu' => '', + 'pt' => '', + 'pt-BR' => '', + ), + 'form_username' => array ( + 'no' => '', + 'nn' => '', + 'da' => '', + 'en' => 'Username', + 'de' => '', + 'sv' => '', + 'fi' => '', + 'es' => 'Usuario', + 'fr' => '', + 'nl' => '', + 'lb' => '', + 'sl' => '', + 'hr' => '', + 'hu' => '', + 'pt' => '', + 'pt-BR' => '', + ), + 'form_password' => array ( + 'no' => '', + 'nn' => '', + 'da' => '', + 'en' => 'Password', + 'de' => '', + 'sv' => '', + 'fi' => '', + 'es' => 'Contraseña', + 'fr' => '', + 'nl' => '', + 'lb' => '', + 'sl' => '', + 'hr' => '', + 'hu' => '', + 'pt' => '', + 'pt-BR' => '', + ), 'error_header' => array ( 'no' => 'Feil', 'nn' => 'Feil', @@ -98,6 +152,24 @@ $lang = array( 'pt' => '', 'pt-BR' => '', ), + 'get_button' => array ( + 'no' => '', + 'nn' => '', + 'da' => '', + 'en' => 'Get my Infocard', + 'de' => '', + 'sv' => '', + 'fi' => '', + 'es' => 'Conseguir mi Infocard', + 'fr' => '', + 'nl' => '', + 'lb' => '', + 'sl' => '', + 'hr' => '', + 'hu' => '', + 'pt' => '', + 'pt-BR' => '', + ), 'help_header' => array ( 'no' => '', 'nn' => '', @@ -120,7 +192,7 @@ $lang = array( 'no' => '', 'nn' => '', 'da' => '', - 'en' => 'Information Cards (aka InfoCard) is a web authentication technology. Contact with your services provider in order to configure your computer and gives you and Information Card (identification virtual card).', + 'en' => 'Information Cards (aka InfoCard) is a web authentication technology. Contact with your services provider in order to configure your computer and give you and Information Card (identification virtual card).', 'de' => '', 'sv' => '', 'fi' => '', @@ -165,18 +237,18 @@ $lang = array( 'pt-BR' => 'Envie um e-mail para a Central de Ajuda.', ), 'contact_info' => array ( - 'no' => 'Kontaktinformasjon:', - 'nn' => 'Kontaktinformasjon:', + 'no' => 'Kontaktinformasjon', + 'nn' => 'Kontaktinformasjon', 'da' => 'Kontaktoplysninger', - 'en' => 'Contact information:', + 'en' => 'Contact information', 'de' => 'Kontakt', - 'sv' => 'Kontaktinformation:', - 'es' => 'InformaciĂłn de contacto:', + 'sv' => 'Kontaktinformation', + 'es' => 'InformaciĂłn de contacto', 'nl' => 'Contact informatie', 'sl' => 'Kontakt', 'hr' => 'Kontakt podaci', 'hu' => 'ElĂ©rĂ©si informáciĂłk', - 'pt' => 'Contactos:', + 'pt' => 'Contactos', 'pt-BR' => 'Informações de Contato', ), diff --git a/modules/InfoCard/extra/config-login-infocard.php b/modules/InfoCard/extra/config-login-infocard.php new file mode 100644 index 0000000000000000000000000000000000000000..e94d757429effe42f5b0b8d87b8245539bc277db --- /dev/null +++ b/modules/InfoCard/extra/config-login-infocard.php @@ -0,0 +1,174 @@ +<?php + +/* +* AUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: 'InfoCard' module configuration for simpleSAMLphp. + + +Some definitions were taken from: +A Guide to Using the Identity Selector +Interoperability Profile V1.5 within Web +Applications and Browsers. +Copyright Microsoft + +*/ + + +$config = array ( + +//------------- TEMPLATE OPTIONS --------------- + 'IClogo' => 'resources/infocard_114x80.png', //Infocard logo button + 'help_desk_email_URL' => 'mailto:asd@asd.com', //Help desk e-mail + 'contact_info_URL' => 'http://google.es', //Contact information + + + + +//------------- CERTIFICATE OPTIONS --------------- + + /* + * USED IN: Relying Party + * DESCRIPTION: Key of the certificate used in the https connection with the idp, it'll be used + * for decrypting the received XML token, + */ + 'idp_key' => '/etc/apache2/ssl/idp.key', + + + /* + * USED IN: Relying Party + * DESCRIPTION: Only accept tokens signed with this certificate, + * if no certificate is set, it'll be assumed to accept + * a self isued token and accept any token. + */ + 'sts_crt' => '/etc/apache2/ssl/sts.crt', + + + /* + * USED IN: Infocard Generator, STS + * DESCRIPTION: STS certificate for signing Infocards and tokens. + */ + 'sts_key' => '/etc/apache2/ssl/sts.key', + + + /* + * USED IN: + * DESCRIPTION: Array of certificates forming a trust chain. The local signing + * certificate is [0], the one that signed that is [1], etc, chaining to a + * trust anchor. + * HINT: The first one, [0], should be the same as the sts_crt. + */ + 'certificates' => array( + 0 => '/etc/apache2/ssl/sts.crt', + 1 => '/etc/apache2/ssl/CA.crt' + ), + + + +//------------- DATA (InfoCard) OPTIONS --------------- + + /* + * USED IN: InfoCard Generator, Relying Party and STS + * DESCRIPTION: Infocard information + */ + 'InfoCard' => array( + /* + * -issuer (optional, taken from the sts_crt common name value, if no set, self issuer is assumed ) + * This parameter specifies the URL of the STS from which to obtain a token. If omitted, no + * specific STS is requested. The special value + * “http://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self” specifies that the + * token should come from a Self-issued Identity Provider + */ + /* + * Root of the current InfoCard schema + */ + 'schema' => 'http://schemas.xmlsoap.org/ws/2005/05/identity', + /* + * -issuerPolicy (optional) + * This parameter specifies the URL of an endpoint from which the STS’s WS-SecurityPolicy + * can be retrieved using WS-MetadataExchange. This endpoint must use HTTPS. + */ + 'issuerPolicy' => '', + /* + * -privacyUrl (optional) + * This parameter specifies the URL of the human-readable Privacy Policy of the site, if + * provided. + */ + 'privacyURL' => '', + /* + * -tokenType (optional) + * This parameter specifies the type of the token to be requested from the STS as a URI. Th + * parameter can be omitted if the STS and the Web site front-end have a mutual + * understanding about what token type will be provided or if the Web site is willing to accep + * any token type. + */ + 'tokenType' => 'urn:oasis:names:tc:SAML:1.0:assertion', + + /*-Claims supported by the current schema + givenname + surname + emailaddress + streetaddress + locality + stateorprovince + postalcode + country + primaryphone + dateofbirth + privatepersonalid + gender + webpage + */ + + /* + * -requiredClaims (optional) + * This parameter specifies the types of claims that must be supplied by the identity. If + * omitted, there are no required claims. The value of requiredClaims is a space-separate + * list of URIs, each specifying a required claim type. + */ + 'requiredClaims' => array( + 'privatepersonalidentifier' => array('displayTag'=>"Id", 'description'=>"id"), + 'givenname' => array('displayTag'=>"Given Name", 'description'=>"etc"), + 'surname' => array('displayTag'=>"Surname", 'description'=>"apellidos"), + 'emailaddress' => array('displayTag'=>"e-mail", 'description'=>"E-mail address") + ), + /* + * -optionalClaims (optional) + * This parameter specifies the types of optional claims that may be supplied by the identity + * If omitted, there are no optional claims. The value of optionalClaims is a space-separat + * list of URIs, each specifying a claim type that can be optionally submitted + */ + 'optionalClaims' => array( + 'country' => array('displayTag'=>"country", 'description'=>"PaĂs"), + 'webpage' => array('displayTag'=>"webpage", 'description'=>"Página web") + ), + ), + + + + +//------------- WEB PAGES --------------- + + /* + * USED IN: InfoCard Generator, Relying Party (optional form) + * DESCRIPTION: Infocard generator URL, if set it'll appear a form with username-password authentication in the template + */ +// 'CardGenerator' => 'https://sts.aut.uah.es/simplesaml/module.php/InfoCard/getinfocard.php', + + + /* + * USED IN: InfoCard Generator, Relying Party (issuer), STS (Metadata-Exchange) + * DESCRIPTION: Token generator URL + */ + 'tokenserviceurl' => 'https://sts.aut.uah.es/simplesaml/module.php/InfoCard/tokenservice.php', + + + /* + * USED IN: InfoCard Generator + * DESCRIPTION: Metadata Exchange URL + */ + 'mexurl' => 'https://sts.aut.uah.es/simplesaml/module.php/InfoCard/mex.php', +); + +?> \ No newline at end of file diff --git a/modules/InfoCard/extra/getinfocard.php b/modules/InfoCard/extra/getinfocard.php new file mode 100644 index 0000000000000000000000000000000000000000..d1fac6a9ab3094e57a64eb8dfc47c0b3d658c6ae --- /dev/null +++ b/modules/InfoCard/extra/getinfocard.php @@ -0,0 +1,198 @@ +<?php + + +/* +* COAUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: InfoCard module Infocard generator +*/ + +//Generate a raw InfoCard with the given data and the configuration +//NOTA: hay namespaces totalmente innecesarios desde un punto de vista práctico xml, están cubiertos por el nodo +// Signature, pero si no se ponen, la canonicalizaciĂłn de generaciĂłn de firma la de comprobaciĂłn son diferentes +// y no funciona. +//EJ: xmlns="http://www.w3.org/2000/09/xmldsig#" en los nodos Object y SignedInfo + +function create_card($ICdata,$ICconfig) { + + $infocardbuf = "<Object Id=\"IC01\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"; + $infocardbuf .= "<InformationCard xml:lang=\"en-us\" xmlns=\"http://schemas.xmlsoap.org/ws/2005/05/identity\" xmlns:wsa=\"http://www.w3.org/2005/08/addressing\" xmlns:wst=\"http://schemas.xmlsoap.org/ws/2005/02/trust\" xmlns:wsx=\"http://schemas.xmlsoap.org/ws/2004/09/mex\">"; + + //cardId + $infocardbuf .= "<InformationCardReference>"; + $infocardbuf .= "<CardId>".$ICdata['CardId']."</CardId>"; //xs:anyURI cardId (="$cardurl/$ppid"; $ppid = "$uname-" . time();) + $infocardbuf .= "<CardVersion>1</CardVersion>"; //xs:unsignedInt + $infocardbuf .= "</InformationCardReference>"; + + //cardName + $infocardbuf .= "<CardName>".$ICdata['CardName']."</CardName>"; + + //image + $infocardbuf .= "<CardImage MimeType=\"".mime_content_type($ICdata['CardImage'])."\">"; + $infocardbuf .= base64_encode(file_get_contents($ICdata['CardImage'])); + $infocardbuf .= "</CardImage>"; + + //issuer - times + $infocardbuf .= "<Issuer>".$ICconfig['InfoCard']['issuer']."</Issuer>"; + $infocardbuf .= "<TimeIssued>".gmdate('Y-m-d').'T'.gmdate('H:i:s').'Z'."</TimeIssued>"; + $infocardbuf .= "<TimeExpires>".$ICdata['TimeExpires']."</TimeExpires>"; + + //Token Service List + $infocardbuf .= "<TokenServiceList>"; + $infocardbuf .= "<TokenService>"; + $infocardbuf .= "<wsa:EndpointReference>"; + $infocardbuf .= "<wsa:Address>".$ICconfig['tokenserviceurl']."</wsa:Address>"; + $infocardbuf .= "<wsa:Metadata>"; + $infocardbuf .= "<wsx:Metadata>"; + $infocardbuf .= "<wsx:MetadataSection>"; + $infocardbuf .= "<wsx:MetadataReference>"; + $infocardbuf .= "<wsa:Address>".$ICconfig['mexurl']."</wsa:Address>"; + $infocardbuf .= "</wsx:MetadataReference>"; + $infocardbuf .= "</wsx:MetadataSection>"; + $infocardbuf .= "</wsx:Metadata>"; + $infocardbuf .= "</wsa:Metadata>"; + $infocardbuf .= "</wsa:EndpointReference>"; + + + + /*Types of User Credentials + * UsernamePasswordCredential + * KerberosV5Credential + * X509V3Credential + * SelfIssuedCredential + */ + $infocardbuf .= "<UserCredential>"; + $infocardbuf .= "<DisplayCredentialHint>".$ICdata['DisplayCredentialHint']."</DisplayCredentialHint>"; + switch($ICdata['UserCredential']){ + case "UsernamePasswordCredential": + $infocardbuf .= "<UsernamePasswordCredential>"; + $infocardbuf .= "<Username>".$ICdata['UserName']."</Username>"; + $infocardbuf .= "</UsernamePasswordCredential>"; + break; + case "KerberosV5Credential": + $infocardbuf .= "<KerberosV5Credential/>"; + break; + case "X509V3Credential": + $infocardbuf .= "<X509V3Credential>"; + $infocardbuf .= "<ds:X509Data>"; + $infocardbuf .= "<wsse:KeyIdentifier ValueType=\"http://docs.oasis-open.org/wss/2004/xx/oasis-2004xx-wss-soap-message-security-1.1#ThumbprintSHA1\" EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis200401-wss-soap-message-security-1.0#Base64Binary"> + /*This element provides a key identifier for the X.509 certificate based on the SHA1 hash + of the entire certificate content expressed as a “thumbprint.” Note that the extensibility + point in the ds:X509Data element is used to add wsse:KeyIdentifier as a child + element.*/ + $infocardbuf .= $ICdata['KeyIdentifier']; //xs:base64binary; + $infocardbuf .= "</wsse:KeyIdentifier>"; + $infocardbuf .= "</ds:X509Data>"; + $infocardbuf .= "</X509V3Credential>"; + break; + default: //SelfIssuedCredential + $infocardbuf .= "<SelfIssuedCredential>"; + $infocardbuf .= "<PrivatePersonalIdentifier>"; + $infocardbuf .= $ICdata['PPID']; //xs:base64binary; + $infocardbuf .= "</PrivatePersonalIdentifier>"; + $infocardbuf .= "</SelfIssuedCredential> "; + break; + } + $infocardbuf .= "</UserCredential>"; + + $infocardbuf .= "</TokenService>"; + $infocardbuf .= "</TokenServiceList>"; + + + //Tokentype + $infocardbuf .= "<SupportedTokenTypeList>"; + $infocardbuf .= "<wst:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</wst:TokenType>"; + $infocardbuf .= "</SupportedTokenTypeList>"; + + //Claims + $infocardbuf .= "<SupportedClaimTypeList>"; + $url = $ICconfig['InfoCard']['schema']."/claims/"; + foreach ($ICconfig['InfoCard']['requiredClaims'] as $claim=>$data) { + $infocardbuf .= "<SupportedClaimType Uri=\"".$url.$claim."\">"; + $infocardbuf .= "<DisplayTag>".$data['displayTag']."</DisplayTag>"; + $infocardbuf .= "<Description>".$data['description']."</Description>"; + $infocardbuf .= "</SupportedClaimType>"; + } + foreach ($ICconfig['InfoCard']['optionalClaims'] as $claim=>$data) { + $infocardbuf .= "<SupportedClaimType Uri=\"".$url.$claim."\">"; + $infocardbuf .= "<DisplayTag>".$data['displayTag']."</DisplayTag>"; + $infocardbuf .= "<Description>".$data['description']."</Description>"; + $infocardbuf .= "</SupportedClaimType>"; + } + $infocardbuf .= "</SupportedClaimTypeList>"; + + //Privacy URL + $infocardbuf .= "<PrivacyNotice>".$ICconfig['InfoCard']['privacyURL']."</PrivacyNotice>"; + + $infocardbuf .= "</InformationCard>"; + $infocardbuf .= "</Object>"; + + $canonicalbuf = sspmod_InfoCard_Utils::canonicalize($infocardbuf); + + //construct a SignedInfo block + $signedinfo = "<SignedInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"; + $signedinfo .= "<CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>"; + $signedinfo .= "<SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>"; + $signedinfo .= "<Reference URI=\"#IC01\">"; + $signedinfo .= "<Transforms>"; + $signedinfo .= "<Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>"; + $signedinfo .= "</Transforms>"; + $signedinfo .= "<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>"; + $signedinfo .= "<DigestValue>".base64_encode(sha1($canonicalbuf, TRUE))."</DigestValue>"; + $signedinfo .= "</Reference>"; + $signedinfo .= "</SignedInfo>"; + + $canonicalbuf = sspmod_InfoCard_Utils::canonicalize($signedinfo); + + $signature = ''; + $privkey = openssl_pkey_get_private(file_get_contents($ICconfig['sts_key'])); + openssl_sign($canonicalbuf, &$signature, $privkey); + openssl_free_key($privkey); + $infocard_signature = base64_encode($signature); + + //Envelope + $buf = "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"; + $buf .= $signedinfo; + $buf .= "<SignatureValue>".$infocard_signature."</SignatureValue>"; + $buf .= "<KeyInfo>"; + $buf .= "<X509Data>"; + // signing certificate(s) + foreach ($ICconfig['certificates'] as $idx=>$cert) + $buf .= "<X509Certificate>".sspmod_InfoCard_Utils::takeCert($cert)."</X509Certificate>"; + $buf .= "</X509Data>"; + $buf .= "</KeyInfo>"; + $buf .= $infocardbuf; + $buf .= "</Signature>"; + + return $buf; +} + + + +$username = $_POST['username']; +$password = $_POST['password']; + +if (sspmod_InfoCard_UserFunctions::validateUser($username,$password)){ + + $config = SimpleSAML_Configuration::getInstance(); + $autoconfig = $config->copyFromBase('logininfocard', 'config-login-infocard.php'); + $ICconfig['InfoCard'] = $autoconfig->getValue('InfoCard'); + $ICconfig['InfoCard']['issuer'] = $autoconfig->getValue('tokenserviceurl');//sspmod_InfoCard_Utils::getIssuer($sts_crt); + $ICconfig['tokenserviceurl'] = $autoconfig->getValue('tokenserviceurl'); + $ICconfig['mexurl'] = $autoconfig->getValue('mexurl'); + $ICconfig['sts_key'] = $autoconfig->getValue('sts_key'); + $ICconfig['certificates'] = $autoconfig->getValue('certificates'); + + $ICdata = sspmod_InfoCard_UserFunctions::fillICdata($username); + + $IC = create_card($ICdata,$ICconfig); + header("Content-Disposition: attachment; filename=\"".$ICdata['CardName'].".crd\""); + header('Content-Type: application/x-informationcard'); + header('Content-Length:'.strlen($IC)); +}else{ + $IC = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"><head><title>ERROR!</title></head><body><h1>Wrong credentials!</h1> Could not authenticate you</body></html>"; +} + +echo $IC; +?> diff --git a/modules/InfoCard/extra/mex.php b/modules/InfoCard/extra/mex.php new file mode 100644 index 0000000000000000000000000000000000000000..ba7f3908cf9d4172ecdec5d0ec58741b4adfd4ea --- /dev/null +++ b/modules/InfoCard/extra/mex.php @@ -0,0 +1,441 @@ +<?php +/* + * Copyright (C) 2007 Carillon Information Security Inc. + * + * WS-MetadataExchange responder for the Carillon STS. Everything is + * pretty much hard-coded -- the only things that get customized are the + * tokenservice URL and the certificate. + * + */ + +/* +* COAUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: InfoCard module metadata exchange +*/ + + +$method = $_SERVER["REQUEST_METHOD"]; +if ($method == "POST") + $use_soap = true; +else + $use_soap = false; + +if ($use_soap) + Header('Content-Type: application/soap+xml;charset=utf-8'); +else + Header('Content-Type: application/xml;charset=utf-8'); + +$config = SimpleSAML_Configuration::getInstance(); +$autoconfig = $config->copyFromBase('logininfocard', 'config-login-infocard.php'); +$ICconfig['tokenserviceurl'] = $autoconfig->getValue('tokenserviceurl'); +$ICconfig['certificates'] = $autoconfig->getValue('certificates'); + + +// Grab the important parts of the token request. That's pretty much just +// the request ID. +$request_id = ''; +if ($use_soap && strlen($HTTP_RAW_POST_DATA)) +{ + $token = new DOMDocument(); + $token->loadXML($HTTP_RAW_POST_DATA); + $doc = $token->documentElement; + $elements = $doc->getElementsByTagname('MessageID'); + $request_id = $elements->item(0)->nodeValue; +} + +$buf = '<?xml version="1.0"?>'; + +if ($use_soap) +{ + $buf .= '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">'; + $buf .= '<s:Header>'; + $buf .= '<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2004/09/transfer/GetResponse</a:Action>'; + if ($request_id) + $buf .= "<a:RelatesTo>$request_id</a:RelatesTo>"; + $buf .= '</s:Header>'; + $buf .= '<s:Body>'; +} +$buf .= '<Metadata xmlns="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">'; +$buf .= '<wsx:MetadataSection xmlns="" Dialect="http://schemas.xmlsoap.org/wsdl/" Identifier="http://schemas.xmlsoap.org/ws/2005/02/trust">'; +$buf .= '<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" targetNamespace="http://schemas.xmlsoap.org/ws/2005/02/trust">'; +$buf .= '<wsdl:types>'; +$buf .= '<xsd:schema targetNamespace="http://schemas.xmlsoap.org/ws/2005/02/trust/Imports">'; +$buf .= '<xsd:import namespace="http://schemas.microsoft.com/Message"/>'; +$buf .= '</xsd:schema>'; +$buf .= '</wsdl:types>'; +$buf .= '<wsdl:message name="IWSTrustContract_Cancel_InputMessage">'; +$buf .= '<wsdl:part xmlns:q1="http://schemas.microsoft.com/Message" name="request" type="q1:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:message name="IWSTrustContract_Cancel_OutputMessage">'; +$buf .= '<wsdl:part xmlns:q2="http://schemas.microsoft.com/Message" name="CancelResult" type="q2:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:message name="IWSTrustContract_Issue_InputMessage">'; +$buf .= '<wsdl:part xmlns:q3="http://schemas.microsoft.com/Message" name="request" type="q3:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:message name="IWSTrustContract_Issue_OutputMessage">'; +$buf .= '<wsdl:part xmlns:q4="http://schemas.microsoft.com/Message" name="IssueResult" type="q4:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:message name="IWSTrustContract_Renew_InputMessage">'; +$buf .= '<wsdl:part xmlns:q5="http://schemas.microsoft.com/Message" name="request" type="q5:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:message name="IWSTrustContract_Renew_OutputMessage">'; +$buf .= '<wsdl:part xmlns:q6="http://schemas.microsoft.com/Message" name="RenewResult" type="q6:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:message name="IWSTrustContract_Validate_InputMessage">'; +$buf .= '<wsdl:part xmlns:q7="http://schemas.microsoft.com/Message" name="request" type="q7:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:message name="IWSTrustContract_Validate_OutputMessage">'; +$buf .= '<wsdl:part xmlns:q8="http://schemas.microsoft.com/Message" name="ValidateResult" type="q8:MessageBody"/>'; +$buf .= '</wsdl:message>'; +$buf .= '<wsdl:portType name="IWSTrustContract">'; +$buf .= '<wsdl:operation name="Cancel">'; +$buf .= '<wsdl:input wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Cancel" message="tns:IWSTrustContract_Cancel_InputMessage"/>'; +$buf .= '<wsdl:output wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Cancel" message="tns:IWSTrustContract_Cancel_OutputMessage"/>'; +$buf .= '</wsdl:operation>'; +$buf .= '<wsdl:operation name="Issue">'; +$buf .= '<wsdl:input wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue" message="tns:IWSTrustContract_Issue_InputMessage"/>'; +$buf .= '<wsdl:output wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue" message="tns:IWSTrustContract_Issue_OutputMessage"/>'; +$buf .= '</wsdl:operation>'; +$buf .= '<wsdl:operation name="Renew">'; +$buf .= '<wsdl:input wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Renew" message="tns:IWSTrustContract_Renew_InputMessage"/>'; +$buf .= '<wsdl:output wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Renew" message="tns:IWSTrustContract_Renew_OutputMessage"/>'; +$buf .= '</wsdl:operation>'; +$buf .= '<wsdl:operation name="Validate">'; +$buf .= '<wsdl:input wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Validate" message="tns:IWSTrustContract_Validate_InputMessage"/>'; +$buf .= '<wsdl:output wsaw:Action="http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Validate" message="tns:IWSTrustContract_Validate_OutputMessage"/>'; +$buf .= '</wsdl:operation>'; +$buf .= '</wsdl:portType>'; +$buf .= '</wsdl:definitions>'; +$buf .= '</wsx:MetadataSection>'; +$buf .= '<wsx:MetadataSection xmlns="" Dialect="http://schemas.xmlsoap.org/wsdl/" Identifier="http://tempuri.org/">'; +$buf .= '<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:i0="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" name="STS" targetNamespace="http://tempuri.org/">'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<wsp:Policy>'; +$buf .= '<sp:TransportToken>'; +$buf .= '<wsp:Policy>'; +$buf .= '<sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">'; +$buf .= '<wsp:Policy>'; +$buf .= '<sp:RequireThumbprintReference/>'; +$buf .= '<sp:WssX509V3Token10/>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:X509Token>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:TransportToken>'; +$buf .= '<sp:AlgorithmSuite>'; +$buf .= '<wsp:Policy>'; +$buf .= '<sp:Basic128/>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:AlgorithmSuite>'; +$buf .= '<sp:Layout>'; +$buf .= '<wsp:Policy>'; +$buf .= '<sp:Strict/>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:Layout>'; +if ($_GET['auth'] == 'x509') + $buf .= '<sp:IncludeTimestamp/>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:TransportBinding>'; + +// is this metadata for an infocard that wants an x509-authenticated +// token, or a username/password token? +if ($_GET['auth'] == 'x509') +{ + $buf .= '<sp:EndorsingSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; + $buf .= '<wsp:Policy>'; + $buf .= '<sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">'; + $buf .= '<wsp:Policy>'; + $buf .= '<sp:RequireThumbprintReference/>'; + $buf .= '<sp:WssX509V3Token10/>'; + $buf .= '</wsp:Policy>'; + $buf .= '</sp:X509Token>'; + $buf .= '</wsp:Policy>'; + $buf .= '</sp:EndorsingSupportingTokens>'; +} +else +{ + $buf .= '<sp:SignedSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; + $buf .= '<wsp:Policy>'; + $buf .= '<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">'; + $buf .= '<wsp:Policy>'; + $buf .= '<sp:WssUsernameToken10/>'; + $buf .= '</wsp:Policy>'; + $buf .= '</sp:UsernameToken>'; + $buf .= '</wsp:Policy>'; + $buf .= '</sp:SignedSupportingTokens>'; +} + +$buf .= '<sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<wsp:Policy>'; +$buf .= '<sp:MustSupportRefKeyIdentifier/>'; +$buf .= '<sp:MustSupportRefIssuerSerial/>'; +$buf .= '<sp:MustSupportRefThumbprint/>'; +$buf .= '<sp:MustSupportRefEncryptedKey/>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:Wss11>'; +$buf .= '<sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<wsp:Policy>'; +$buf .= '<sp:MustSupportIssuedTokens/>'; +$buf .= '<sp:RequireServerEntropy/>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:Trust10>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Cancel_Input_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Cancel_output_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Issue_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:EndorsingSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<wsp:Policy>'; +$buf .= '<mssp:RsaToken xmlns:mssp="http://schemas.microsoft.com/ws/2005/07/securitypolicy" sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never" wsp:Optional="true"/>'; +$buf .= '</wsp:Policy>'; +$buf .= '</sp:EndorsingSupportingTokens>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Issue_Input_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Issue_output_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Renew_Input_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Renew_output_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Validate_Input_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsp:Policy wsu:Id="CustomBinding_IWSTrustContract_Validate_output_policy">'; +$buf .= '<wsp:ExactlyOne>'; +$buf .= '<wsp:All>'; +$buf .= '<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>'; +$buf .= '</sp:SignedParts>'; +$buf .= '<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">'; +$buf .= '<sp:Body/>'; +$buf .= '</sp:EncryptedParts>'; +$buf .= '</wsp:All>'; +$buf .= '</wsp:ExactlyOne>'; +$buf .= '</wsp:Policy>'; +$buf .= '<wsdl:import namespace="http://schemas.xmlsoap.org/ws/2005/02/trust" location=""/>'; +$buf .= '<wsdl:types/>'; +$buf .= '<wsdl:binding name="CustomBinding_IWSTrustContract" type="i0:IWSTrustContract">'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_policy"/>'; +$buf .= '<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>'; +$buf .= '<wsdl:operation name="Cancel">'; +$buf .= '<soap12:operation soapAction="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Cancel" style="document"/>'; +$buf .= '<wsdl:input>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Cancel_Input_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:input>'; +$buf .= '<wsdl:output>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Cancel_output_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:output>'; +$buf .= '</wsdl:operation>'; +$buf .= '<wsdl:operation name="Issue">'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Issue_policy"/>'; +$buf .= '<soap12:operation soapAction="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue" style="document"/>'; +$buf .= '<wsdl:input>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Issue_Input_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:input>'; +$buf .= '<wsdl:output>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Issue_output_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:output>'; +$buf .= '</wsdl:operation>'; +$buf .= '<wsdl:operation name="Renew">'; +$buf .= '<soap12:operation soapAction="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Renew" style="document"/>'; +$buf .= '<wsdl:input>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Renew_Input_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:input>'; +$buf .= '<wsdl:output>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Renew_output_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:output>'; +$buf .= '</wsdl:operation>'; +$buf .= '<wsdl:operation name="Validate">'; +$buf .= '<soap12:operation soapAction="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Validate" style="document"/>'; +$buf .= '<wsdl:input>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Validate_Input_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:input>'; +$buf .= '<wsdl:output>'; +$buf .= '<wsp:PolicyReference URI="#CustomBinding_IWSTrustContract_Validate_output_policy"/>'; +$buf .= '<soap12:body use="literal"/>'; +$buf .= '</wsdl:output>'; +$buf .= '</wsdl:operation>'; +$buf .= '</wsdl:binding>'; +$buf .= '<wsdl:service name="STS">'; +$buf .= '<wsdl:port name="CustomBinding_IWSTrustContract" binding="tns:CustomBinding_IWSTrustContract">'; +$buf .= "<soap12:address location=\"".$ICconfig['tokenserviceurl']."\"/>"; +$buf .= '<wsa10:EndpointReference>'; +$buf .= "<wsa10:Address>".$ICconfig['tokenserviceurl']."</wsa10:Address>"; +$buf .= '<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">'; +$buf .= '<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">'; +$buf .= '<X509Data>'; +$buf .= '<X509Certificate>'.sspmod_InfoCard_Utils::takeCert($ICconfig['certificates'][0]).'</X509Certificate>'; +$buf .= '</X509Data>'; +$buf .= '</KeyInfo>'; +$buf .= '</Identity>'; +$buf .= '</wsa10:EndpointReference>'; +$buf .= '</wsdl:port>'; +$buf .= '</wsdl:service>'; +$buf .= '</wsdl:definitions>'; +$buf .= '</wsx:MetadataSection>'; +$buf .= '<wsx:MetadataSection xmlns="" Dialect="http://www.w3.org/2001/XMLSchema" Identifier="http://schemas.microsoft.com/Message">'; +$buf .= '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/Message" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/Message">'; +$buf .= '<xs:complexType name="MessageBody">'; +$buf .= '<xs:sequence>'; +$buf .= '<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any"/>'; +$buf .= '</xs:sequence>'; +$buf .= '</xs:complexType>'; +$buf .= '</xs:schema>'; +$buf .= '</wsx:MetadataSection>'; +$buf .= '</Metadata>'; + +if ($use_soap) +{ + $buf .= '</s:Body>'; + $buf .= '</s:Envelope>'; +} + + + +print($buf); + +?> diff --git a/modules/InfoCard/extra/tokenservice.php b/modules/InfoCard/extra/tokenservice.php new file mode 100644 index 0000000000000000000000000000000000000000..7b6267c974383730c1f7ae541948ccb9d2d9ab41 --- /dev/null +++ b/modules/InfoCard/extra/tokenservice.php @@ -0,0 +1,296 @@ +<?php +/* + * Copyright (C) 2007 Carillon Information Security Inc. + * + * Token responder for the Carillon STS. Accepts a SOAP token request from + * a relying party (or an infocard client, more likely) and produces a + * token with the proper attributes, as stored in the database of issued + * infocards. + * + */ + +/* +* COAUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: InfoCard module token generator +*/ + + + +// Windows CardSpace doesn't support using the infocard's certificate as +// the SSL cert for transport binding... so we make it sign a timestamp in +// the token request, and validate the signature on that. +function validate_embedded_cert() +{ + global $doc, $row; + global $db_usertable; + global $uidnum, $uname, $fullname; + global $HTTP_RAW_POST_DATA; + + // FIXME: Add error checking to this! + + // get the signed part (the timestamp) in a horribly cheating way for + // now + // first grab the namespace for u + $begin = 'xmlns:u="'; + $end = 'xsd"'; + $xmlnsu = $HTTP_RAW_POST_DATA; + $xmlnsu = substr($xmlnsu, strpos($xmlnsu, $begin)); + $xmlnsu = substr($xmlnsu, 0, strpos($xmlnsu, $end)+strlen($end)); + $begin = '<u:Timestamp '; + $end = '</u:Timestamp>'; + $tmp = $HTTP_RAW_POST_DATA; + $tmp = substr($tmp, strpos($tmp, $begin)); + $tmp = substr($tmp, 0, strpos($tmp, $end)+strlen($end)); + $tmp1 = substr($tmp, 0, strpos($tmp, ' ')); + $tmp2 = substr($tmp, strpos($tmp, ' ')+1); + $timestamp = $tmp1." $xmlnsu ".$tmp2; + + // canonicalize the timestamp and digest it + $canonical_timestamp = sspmod_InfoCard_Utils::canonicalize($timestamp); + $myhash = sha1($canonical_timestamp,TRUE); + $mydigest = base64_encode($myhash); + + // grab the digest from the request + $elements = $doc->getElementsByTagname('DigestValue'); + $request_digest = $elements->item(0)->nodeValue; + + // if the digests don't match, we fail + if ($mydigest != $request_digest) + return false; + + // get the SignedInfo in a horribly cheating way for now + $begin = '<SignedInfo'; + $end = '</SignedInfo>'; + $sinfo = $HTTP_RAW_POST_DATA; + $sinfo = substr($sinfo, strpos($sinfo, $begin)); + $sinfo = substr($sinfo, 0, strpos($sinfo, $end)+strlen($end)); + + // grab the signing certificate and PEM-encode it to satisfy openssl + $elements = $doc->getElementsByTagname('BinarySecurityToken'); + $cert = $elements->item(0)->nodeValue; + $certpem = "-----BEGIN CERTIFICATE-----\n"; + $offset = 0; + while ($segment=substr($cert, $offset, 64)) + { + $certpem .= $segment."\n"; + $offset += 64; + } + $certpem .= "-----END CERTIFICATE-----\n"; + + $pubkey = openssl_pkey_get_public($certpem); + + // canonicalize the signed info + $canonical_sinfo = sspmod_InfoCard_Utils::canonicalize($sinfo); + + // grab the signature from the request + $elements = $doc->getElementsByTagname('SignatureValue'); + $request_sig = $elements->item(0)->nodeValue; + + $request_sig = base64_decode($request_sig); + + // try to verify the signature... if we can't, we fail. + if (openssl_verify($canonical_sinfo, $request_sig, $pubkey) == false) + return false; + + // so, the signature is OK. Was it the right cert? Check its + // thumbprint against the cert we recorded in the infocard... + $thumb = sspmod_InfoCard_Utils::thumbcert($cert); + if ($row['x509thumb'] != $thumb) + return false; + + // at this point we've succeeded, but we need to populate some fields + // based on the usertable to create a card... + $arr = openssl_x509_parse($certpem); + $who = $arr['subject']['CN']; + $query = "SELECT * FROM $db_usertable WHERE full_name='$who'"; + $userrow = pg_fetch_assoc(do_query($query)); + if ($userrow['status'] == "1") + { + $uidnum = $userrow['id']; + $uname = $userrow['userid']; + $fullname = $userrow['full_name']; + return true; + } + return false; +} + + + +/* +* claimValues ( 'claim'('value','displayTag'), 'claim'('value','displayTag'), ... ) +*/ +function create_token($claimValues,$config){ + // build a SAML assertion + $now = gmdate('Y-m-d').'T'.gmdate('H:i:s').'Z'; + $later = gmdate('Y-m-d', time()+3600).'T'.gmdate('H:i:s', time()+3600).'Z'; + $assertionid = uniqid('uuid-'); + + $saml = "<saml:Assertion MajorVersion=\"1\" MinorVersion=\"0\" AssertionID=\"$assertionid\" Issuer=\"".$config['issuer']."\" IssueInstant=\"$now\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\">"; + $saml .= "<saml:Conditions NotBefore=\"$now\" NotOnOrAfter=\"$later\" />"; + + $saml .= "<saml:AttributeStatement>"; + $saml .= "<saml:Subject>"; + $saml .= "<saml:SubjectConfirmation>"; + $saml .= "<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:holder-of-key</saml:ConfirmationMethod>"; + + // proof key + $saml .= "<dsig:KeyInfo xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">"; + $saml .= "<dsig:X509Data>"; + $saml .= "<dsig:X509Certificate>".sspmod_InfoCard_Utils::takeCert($config['sts_crt'])."</dsig:X509Certificate>"; + $saml .= "</dsig:X509Data>"; + $saml .= "</dsig:KeyInfo>"; + + $saml .= "</saml:SubjectConfirmation>"; + $saml .= "</saml:Subject>"; + + + foreach ($claimValues as $claim=>$data) { + $saml .= "<saml:Attribute AttributeName=\"$claim\" AttributeNamespace=\"".$config['InfoCard']['schema']."/claims\">"; + $saml .= "<saml:AttributeValue>".$data['value']."</saml:AttributeValue>"; + $saml .= "</saml:Attribute>"; + } + + $saml .= "</saml:AttributeStatement>"; + + + // calculate the digest for the signature... + $canonicalbuf = sspmod_InfoCard_Utils::canonicalize($saml."</saml:Assertion>"); + $myhash = sha1($canonicalbuf,TRUE); + $samldigest = base64_encode($myhash); + + + // construct a SignedInfo block + $signedinfo = "<dsig:SignedInfo xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">"; + $signedinfo .= "<dsig:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\" />"; + $signedinfo .= "<dsig:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" />"; + $signedinfo .= "<dsig:Reference URI=\"#$assertionid\">"; + $signedinfo .= "<dsig:Transforms>"; + $signedinfo .= "<dsig:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\" />"; + $signedinfo .= "<dsig:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\" />"; + $signedinfo .= "</dsig:Transforms>"; + $signedinfo .= "<dsig:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" />"; + $signedinfo .= "<dsig:DigestValue>$samldigest</dsig:DigestValue>"; + $signedinfo .= "</dsig:Reference>"; + $signedinfo .= "</dsig:SignedInfo>"; + + // compute the signature of hte canonicalized digest + $canonicalbuf = sspmod_InfoCard_Utils::canonicalize($signedinfo); + $privkey = openssl_pkey_get_private(file_get_contents($config['sts_key'])); + $signature = ''; + openssl_sign($canonicalbuf, &$signature, $privkey); + openssl_free_key($privkey); + $samlsignature = base64_encode($signature); + + + // now put it all together + $saml .= "<dsig:Signature xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">"; + $saml .= $signedinfo; + $saml .= "<dsig:SignatureValue>$samlsignature</dsig:SignatureValue>"; + + $saml .= "<dsig:KeyInfo>"; + $saml .= "<dsig:X509Data>"; + $saml .= "<dsig:X509Certificate>".sspmod_InfoCard_Utils::takeCert($config['sts_crt'])."</dsig:X509Certificate>"; + $saml .= "</dsig:X509Data>"; + $saml .= "</dsig:KeyInfo>"; + $saml .= "</dsig:Signature>"; + + $saml .= "</saml:Assertion>"; + + + // cram the SAML assertion in a SOAP envelope + $buf = '<?xml version="1.0"?>'; + $buf .= "<soap:Envelope xmlns:ic=\"http://schemas.xmlsoap.org/ws/2005/05/identity\" xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:wsa=\"http://www.w3.org/2005/08/addressing\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wst=\"http://schemas.xmlsoap.org/ws/2005/02/trust\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">"; + if ($include_timestamp) { + $buf .= "<soap:Header>"; + $buf .= "<wsse:Security>"; + $buf .= "<wsu:Timestamp>"; + $buf .= "<wsu:Created>$now</wsu:Created>"; + $buf .= "<wsu:Expires>$later</wsu:Expires>"; + $buf .= "</wsu:Timestamp>"; + $buf .= "</wsse:Security>"; + $buf .= "</soap:Header>"; + } else + $buf .= "<soap:Header />"; + + $buf .= "<soap:Body>"; + $buf .= "<wst:RequestSecurityTokenResponse Context=\"ProcessRequestSecurityToken\">"; + $buf .= "<wst:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</wst:TokenType>"; + $buf .= "<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>"; + $buf .= "<wst:RequestedSecurityToken>"; + + $buf .= $saml; + + $buf .= "</wst:RequestedSecurityToken>"; + + // references + $buf .= "<wst:RequestedAttachedReference>"; + $buf .= "<wsse:SecurityTokenReference>"; + $buf .= "<wsse:KeyIdentifier ValueType=\"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID\">$assertionid</wsse:KeyIdentifier>"; + $buf .= "</wsse:SecurityTokenReference>"; + $buf .= "</wst:RequestedAttachedReference>"; + $buf .= "<wst:RequestedUnattachedReference>"; + $buf .= "<wsse:SecurityTokenReference>"; + $buf .= "<wsse:KeyIdentifier ValueType=\"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID\">$assertionid</wsse:KeyIdentifier>"; + $buf .= "</wsse:SecurityTokenReference>"; + $buf .= "</wst:RequestedUnattachedReference>"; + + // display token + $buf .= "<ic:RequestedDisplayToken>"; + $buf .= "<ic:DisplayToken xml:lang=\"en\">"; + + foreach ($claimValues as $claim=>$data) { + $buf .= "<ic:DisplayClaim Uri=\"".$config['InfoCard']['schema']."/claims/".$claim."\">"; + $buf .= "<ic:DisplayTag>".$data['displayTag']."</ic:DisplayTag>"; + $buf .= "<ic:DisplayValue>".$data['value']."</ic:DisplayValue>"; + $buf .= "</ic:DisplayClaim>"; + } + + $buf .= "</ic:DisplayToken>"; + $buf .= "</ic:RequestedDisplayToken>"; + + // the end + $buf .= "</wst:RequestSecurityTokenResponse>"; + $buf .= "</soap:Body>"; + $buf .= "</soap:Envelope>"; + + return $buf; +} + + + + +// grab the important parts of the token request. these are the username, +// password, and cardid. + +Header('Content-Type: application/soap+xml;charset=utf-8'); + + +$token = new DOMDocument(); +$token->loadXML($HTTP_RAW_POST_DATA); +$doc = $token->documentElement; +$username = $doc->getElementsByTagname('Username')->item(0)->nodeValue; +$password = $doc->getElementsByTagname('Password')->item(0)->nodeValue; +$cardId = $doc->getElementsByTagname('CardId')->item(0)->nodeValue; + + +if (sspmod_InfoCard_UserFunctions::validateUser($username,$password)){ + $config = SimpleSAML_Configuration::getInstance(); + $autoconfig = $config->copyFromBase('logininfocard', 'config-login-infocard.php'); + $ICconfig['InfoCard'] = $autoconfig->getValue('InfoCard'); + $ICconfig['issuer'] = $autoconfig->getValue('issuer'); + $ICconfig['sts_crt'] = $autoconfig->getValue('sts_crt'); + $ICconfig['sts_key'] = $autoconfig->getValue('sts_key'); + + $requiredClaims = sspmod_InfoCard_Utils::extractClaims($ICconfig['InfoCard']['schema'], $doc->getElementsByTagname('ClaimType')); + $claimValues = sspmod_InfoCard_UserFunctions::fillClaims($username, $ICconfig['InfoCard']['requiredClaims'], $ICconfig['InfoCard']['optionalClaims'],$requiredClaims); + $buf = create_token($claimValues,$ICconfig); + Header('Content-length: '.strlen($buf)+1); + print($buf); +}else{ + $bad = true; + print(""); +} + +?> \ No newline at end of file diff --git a/modules/InfoCard/lib/Auth/Source/ICAuth.php b/modules/InfoCard/lib/Auth/Source/ICAuth.php index b16167bd63abffa78b801e40dccf78e8b2b04019..47d85f86cb22fef9d14a5cc87a42af66b311da45 100644 --- a/modules/InfoCard/lib/Auth/Source/ICAuth.php +++ b/modules/InfoCard/lib/Auth/Source/ICAuth.php @@ -1,13 +1,16 @@ <?php + /* * AUTHOR: Samuel Muñoz Hidalgo * EMAIL: samuel.mh@gmail.com -* LAST REVISION: 1-DEC-08 +* LAST REVISION: 22-DEC-08 * DESCRIPTION: -* 'login-infocard' module. -* Auth class +* Authentication module. +* Handles the login information +* Infocard's claims are extracted passed as attributes. */ + class sspmod_InfoCard_Auth_Source_ICAuth extends SimpleSAML_Auth_Source { //The string used to identify our states. @@ -39,38 +42,49 @@ class sspmod_InfoCard_Auth_Source_ICAuth extends SimpleSAML_Auth_Source { public static function handleLogin($authStateId, $xmlToken) { - assert('is_string($authStateId)'); - - /* Retrieve the authentication state. */ - $state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID); - - /* Find authentication source. */ - assert('array_key_exists(self::AUTHID, $state)'); - $source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]); - if ($source === NULL) { - throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]); - } +SimpleSAML_Logger::debug('ENTRA en icauth'); + assert('is_string($authStateId)'); $config = SimpleSAML_Configuration::getInstance(); $autoconfig = $config->copyFromBase('logininfocard', 'config-login-infocard.php'); - $server_key = $autoconfig->getValue('server_key'); - $server_crt = $autoconfig->getValue('server_crt'); + $idp_key = $autoconfig->getValue('idp_key'); + $sts_crt = $autoconfig->getValue('sts_crt'); $Infocard = $autoconfig->getValue('InfoCard'); $infocard = new sspmod_InfoCard_RP_InfoCard(); - $infocard->addCertificatePair($server_key,$server_crt); + $infocard->addIDPKey($idp_key); + $infocard->addSTSCertificate($sts_crt); + if (!$xmlToken) + SimpleSAML_Logger::debug("XMLtoken: ".$xmlToken); + else + SimpleSAML_Logger::debug("NOXMLtoken: ".$xmlToken); $claims = $infocard->process($xmlToken); - if($claims->isValid()) { + if($claims->isValid()) { +// if(false) { $attributes = array(); foreach ($Infocard['requiredClaims'] as $claim => $data){ $attributes[$claim] = array($claims->$claim); } foreach ($Infocard['optionalClaims'] as $claim => $data){ $attributes[$claim] = array($claims->$claim); - } - $state['Attributes'] = $attributes; - SimpleSAML_Auth_Source::completeAuth($state); + } + /* Retrieve the authentication state. */ + $state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID); + /* Find authentication source. */ + assert('array_key_exists(self::AUTHID, $state)'); + $source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]); + if ($source === NULL) { + throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]); + } + $state['Attributes'] = $attributes; +SimpleSAML_Logger::debug('VALIDA'); + unset($infocard); + unset($claims); + SimpleSAML_Auth_Source::completeAuth($state); } else { +SimpleSAML_Logger::debug('NO VALIDA ERROR:'.$claims->getErrorMsg()); + unset($infocard); + unset($claims); return 'wrong_IC'; } } diff --git a/modules/InfoCard/lib/RP/InfoCard.php b/modules/InfoCard/lib/RP/InfoCard.php index 20d70bd2576bfb455821a23b339a80095a0464ec..b4331104578ea8af3fb7075d72145380c08b39d9 100644 --- a/modules/InfoCard/lib/RP/InfoCard.php +++ b/modules/InfoCard/lib/RP/InfoCard.php @@ -1,5 +1,10 @@ <?php - +/* +* COAUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: Zend Infocard libraries added sts certificate check +*/ require_once 'Zend_InfoCard_Claims.php'; class sspmod_InfoCard_RP_InfoCard @@ -45,13 +50,33 @@ class sspmod_InfoCard_RP_InfoCard } + public function addSTSCertificate($sts_crt){ $this->_sts_crt = $sts_crt; - if(!file_exists($this->_sts_crt)) { + if(!file_exists($sts_crt) && ($sts_crt!=NULL) ) { throw new Exception("STS certificate does not exists"); } + if(!is_readable($sts_crt)) { + throw new Exception("STS certificate is not readable"); + } + } + + + + public function addIDPKey($private_key_file, $password = null){ + $this->_private_key_file = $private_key_file; + $this->_password = $password; + + if(!file_exists($this->_private_key_file)) { + throw new Exception("Private key file does not exists"); + } + + if(!is_readable($this->_private_key_file)) { + throw new Exception("Private key file is not readable"); + } } +/*Function not used $public_key_file is not used*/ public function addCertificatePair($private_key_file, $public_key_file, $password = null) { $this->_private_key_file = $private_key_file; $this->_public_key_file = $public_key_file; @@ -60,25 +85,28 @@ class sspmod_InfoCard_RP_InfoCard if(!file_exists($this->_private_key_file)) { throw new Exception("Private key file does not exists"); } - - if(!file_exists($this->_public_key_file)) { - throw new Exception("Public key file does not exists"); - } - + if(!is_readable($this->_private_key_file)) { throw new Exception("Private key file is not readable"); } + if(!file_exists($this->_public_key_file)) { + throw new Exception("Public key file does not exists"); + } + if(!is_readable($this->_public_key_file)) { throw new Exception("Public key file is not readable"); } } + public function process($xmlToken) { if(strpos($xmlToken, "EncryptedData") === false ) { +SimpleSAML_Logger::debug('IC: UNsecureToken'); return self::processUnSecureToken($xmlToken); } else { +SimpleSAML_Logger::debug('IC: secureToken'); return self::processSecureToken($xmlToken); } } diff --git a/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security.php b/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security.php index 48ef389a66db7d8ccd4930b7ca48e5156bad3e75..23c1485afa6f870be160f46d7c3d21356366be95 100644 --- a/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security.php +++ b/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security.php @@ -1,4 +1,11 @@ <?php +/* +* COAUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: modified validatexmlsignature +*/ + /** * Zend Framework * @@ -84,7 +91,6 @@ class Zend_InfoCard_Xml_Security { } - /** * Validates the signature of a provided XML block * @@ -92,12 +98,63 @@ class Zend_InfoCard_Xml_Security * @return bool True if the signature validated, false otherwise * @throws Exception */ - static public function validateXMLSignature($strXMLInput, $sts_crt=NULL){ - if(!extension_loaded('openssl')) { - throw new SimpleSAML_Error_Error("You must have the openssl extension installed to use this class"); + + +static public function validateXMLSignature($strXMLInput, $sts_crt=NULL){ + if(!extension_loaded('openssl')) { + throw new Exception("You must have the openssl extension installed to use this class"); + } + + $sxe = simplexml_load_string($strXMLInput); + + if ($sts_crt != NULL){ + $sxe->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); + list($keyValue) = $sxe->xpath("//ds:Signature/ds:KeyInfo"); + $keyValue->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); + list($x509cert) = $keyValue->xpath("ds:X509Data/ds:X509Certificate"); + list($rsaKeyValue) = $keyValue->xpath("ds:KeyValue/ds:RSAKeyValue"); + //Extract the XMLToken issuer public key + switch(true) { + case isset($x509cert): + SimpleSAML_Logger::debug("Public Key: x509cert"); + $certificate = (string)$x509cert; + $cert_issuer = "-----BEGIN CERTIFICATE-----\n".wordwrap($certificate, 64, "\n", true)."\n-----END CERTIFICATE-----"; + if (!$t_key = openssl_pkey_get_public($cert_issuer)) { + throw new Exception("Wrong token certificate"); + } + $t_det = openssl_pkey_get_details($t_key); + $pem_issuer = $t_det['key']; + break; + case isset($rsaKeyValue): + $rsaKeyValue->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); + list($modulus) = $rsaKeyValue->xpath("ds:Modulus"); + list($exponent) = $rsaKeyValue->xpath("ds:Exponent"); + if(!isset($modulus) || !isset($exponent)) { + throw new Exception("RSA Key Value not in Modulus/Exponent form"); + } + $modulus = base64_decode((string)$modulus); + $exponent = base64_decode((string)$exponent); + $pem_issuer = self::_getPublicKeyFromModExp($modulus, $exponent); + break; + default: + SimpleSAML_Logger::debug("Public Key: Unknown"); + throw new Exception("Unable to determine or unsupported representation of the KeyValue block"); } + + //Check isuer public key against configured one + $checkcert = file_get_contents($sts_crt); + $check_key = openssl_pkey_get_public($checkcert); + $checkData = openssl_pkey_get_details($check_key); + $pem_local = $checkData['key']; + + if ( strcmp($pem_issuer,$pem_local)!=0 ) { + SimpleSAML_Logger::debug("Configured STS cert and received STS cert mismatch"); + openssl_free_key($check_key); + throw new Exception("Configured STS cert and received STS cert mismatch"); + } - $sxe = simplexml_load_string($strXMLInput); + //Validate XML signature + $sxe->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); list($canonMethod) = $sxe->xpath("//ds:Signature/ds:SignedInfo/ds:CanonicalizationMethod"); @@ -106,7 +163,7 @@ class Zend_InfoCard_Xml_Security $cMethod = (string)$canonMethod['Algorithm']; break; default: - throw new SimpleSAML_Error_Error("Unknown or unsupported CanonicalizationMethod Requested"); + throw new Exception("Unknown or unsupported CanonicalizationMethod Requested"); } list($signatureMethod) = $sxe->xpath("//ds:Signature/ds:SignedInfo/ds:SignatureMethod"); @@ -115,7 +172,7 @@ class Zend_InfoCard_Xml_Security $sMethod = (string)$signatureMethod['Algorithm']; break; default: - throw new SimpleSAML_Error_Error("Unknown or unsupported SignatureMethod Requested"); + throw new Exception("Unknown or unsupported SignatureMethod Requested"); } list($digestMethod) = $sxe->xpath("//ds:Signature/ds:SignedInfo/ds:Reference/ds:DigestMethod"); @@ -124,7 +181,7 @@ class Zend_InfoCard_Xml_Security $dMethod = (string)$digestMethod['Algorithm']; break; default: - throw new SimpleSAML_Error_Error("Unknown or unsupported DigestMethod Requested"); + throw new Exception("Unknown or unsupported DigestMethod Requested"); } $base64DecodeSupportsStrictParam = version_compare(PHP_VERSION, '5.2.0', '>='); @@ -136,6 +193,7 @@ class Zend_InfoCard_Xml_Security $dValue = base64_decode((string)$digestValue); } + list($signatureValueElem) = $sxe->xpath("//ds:Signature/ds:SignatureValue"); if ($base64DecodeSupportsStrictParam) { $signatureValue = base64_decode((string)$signatureValueElem, true); @@ -144,8 +202,7 @@ class Zend_InfoCard_Xml_Security } $transformer = new Zend_InfoCard_Xml_Security_Transform(); - - //need to fix this later + $transforms = $sxe->xpath("//ds:Signature/ds:SignedInfo/ds:Reference/ds:Transforms/ds:Transform"); while(list( , $transform) = each($transforms)) { $transformer->addTransform((string)$transform['Algorithm']); @@ -153,84 +210,53 @@ class Zend_InfoCard_Xml_Security $transformed_xml = $transformer->applyTransforms($strXMLInput); $transformed_xml_binhash = pack("H*", sha1($transformed_xml)); if($transformed_xml_binhash != $dValue) { - throw new SimpleSAML_Error_Error("Locally Transformed XML (".$transformed_xml_binhash.") does not match XML Document (".$dValue."). Cannot Verify Signature"); - } - - $public_key = null; - - $sxe->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); - list($keyValue) = $sxe->xpath("//ds:Signature/ds:KeyInfo"); - $keyValue->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); - list($x509cert) = $keyValue->xpath("ds:X509Data/ds:X509Certificate"); - list($rsaKeyValue) = $keyValue->xpath("ds:KeyValue/ds:RSAKeyValue"); - - switch(true) { - case isset($x509cert): - $certificate = (string)$x509cert; - - $pem = "-----BEGIN CERTIFICATE-----\n".wordwrap($certificate, 64, "\n", true)."\n-----END CERTIFICATE-----"; - $public_key = openssl_pkey_get_public($pem); - if(!$public_key) { - throw new SimpleSAML_Error_Error("Unable to extract and prcoess X509 Certificate from KeyValue"); - } - break; - case isset($rsaKeyValue): - $rsaKeyValue->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); - list($modulus) = $rsaKeyValue->xpath("ds:Modulus"); - list($exponent) = $rsaKeyValue->xpath("ds:Exponent"); - if(!isset($modulus) || !isset($exponent)) { - throw new SimpleSAML_Error_Error("RSA Key Value not in Modulus/Exponent form"); - } - $modulus = base64_decode((string)$modulus); - $exponent = base64_decode((string)$exponent); - $pem_public_key = self::_getPublicKeyFromModExp($modulus, $exponent); - $public_key = openssl_pkey_get_public ($pem_public_key); - break; - default: - throw new SimpleSAML_Error_Error("Unable to determine or unsupported representation of the KeyValue block"); - } - + throw new Exception("Locally Transformed XML (".$transformed_xml_binhash.") does not match XML Document (".$dValue."). Cannot Verify Signature"); + } + $transformer = new Zend_InfoCard_Xml_Security_Transform(); $transformer->addTransform((string)$canonMethod['Algorithm']); list($signedInfo) = $sxe->xpath("//ds:Signature/ds:SignedInfo"); + //SimpleSAML_Logger::debug + //print ("signedinfo ".$sxe->saveXML()); $signedInfoXML = self::addNamespace($signedInfo, "http://www.w3.org/2000/09/xmldsig#"); + SimpleSAML_Logger::debug("canonicalizo ".$signedInfoXML); $canonical_signedinfo = $transformer->applyTransforms($signedInfoXML); - - - //Check received public_key against configured one - if ($sts_crt!=NULL){ - $checkcert = file_get_contents($sts_crt); - $check_key = openssl_pkey_get_public($checkcert); - $checkData = openssl_pkey_get_details($check_key); - $checkData2= openssl_pkey_get_details($public_key); - } - if (($checkData2 == $checkData) || ($sts_crt==NULL)) { - if (openssl_verify($canonical_signedinfo,$signatureValue,$public_key)) { - list($reference) = $sxe->xpath("//ds:Signature/ds:SignedInfo/ds:Reference"); - return (string)$reference['URI']; - } else { - throw new SimpleSAML_Error_Error("Could not validate the XML signature"); - } + if (openssl_verify($canonical_signedinfo,$signatureValue,$check_key)) { + list($reference) = $sxe->xpath("//ds:Signature/ds:SignedInfo/ds:Reference"); + openssl_free_key($check_key); + return (string)$reference['URI']; } else { - SimpleSAML_Logger::debug("Configured STS cert and received STS cert mismatch"); - throw new SimpleSAML_Error_Error("Configured STS cert and received STS cert mismatch"); + openssl_free_key($check_key); + throw new Exception("Could not validate the XML signature"); } - return false; + } else { + $sxe->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); + list($reference) = $sxe->xpath("//ds:Signature/ds:SignedInfo/ds:Reference"); + return (string)$reference['URI']; } + return false; +} - - private function addNamespace($xmlElem, $ns) { - $xmlElem->addAttribute('DS_NS', $ns); - $xml = $xmlElem->asXML(); - if(preg_match("/<(\w+)\:\w+/", $xml, $matches)) { - $prefix = $matches[1]; - $xml = str_replace("DS_NS", "xmlns:" . $prefix, $xml); + private function addNamespace($xmlElem, $ns) { + $schema = '.*<[^<]*SignedInfo[^>]*'.$ns.'.*>.*'; + $pattern='/\//'; + $replacement='\/'; + $nspattern= '/'.preg_replace($pattern,$replacement,$schema).'/'; + if (preg_match($nspattern,$xmlElem->asXML())>0){ //M$ Cardspaces + $xml = $xmlElem->asXML(); + } + else { //Digitalme + $xmlElem->addAttribute('DS_NS', $ns); + $xml = $xmlElem->asXML(); + if(preg_match("/<(\w+)\:\w+/", $xml, $matches)) { + $prefix = $matches[1]; + $xml = str_replace("DS_NS", "xmlns:" . $prefix, $xml); + } + else { + $xml = str_replace("DS_NS", "xmlns", $xml); + } } - else { - $xml = str_replace("DS_NS", "xmlns", $xml); - } - return $xml; } @@ -292,9 +318,9 @@ class Zend_InfoCard_Xml_Security case ($len < 0x010000): return sprintf("%c%c%c%c%s", $type, 0x82, $len / 0x0100, $len % 0x0100, $data); default: - throw new SimpleSAML_Error_Error("Could not encode value"); + throw new Exception("Could not encode value"); } - throw new SimpleSAML_Error_Error("Invalid code path"); + throw new Exception("Invalid code path"); } } diff --git a/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security_Transform_XmlExcC14N.php b/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security_Transform_XmlExcC14N.php index c680dd8b7ec0ecbf28b9d93d6e120d9ddb260de4..574907f18e66c3c92d8166e9575a09e52e490262 100644 --- a/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security_Transform_XmlExcC14N.php +++ b/modules/InfoCard/lib/RP/Zend_InfoCard_Xml_Security_Transform_XmlExcC14N.php @@ -40,13 +40,16 @@ class Zend_InfoCard_Xml_Security_Transform_XmlExcC14N */ public function transform($strXMLData) { + $dom = new DOMDocument(); $dom->loadXML($strXMLData); + if ($strXMLData==NULL) SimpleSAML_Logger::debug("NOXML: ".$dom->saveXML()); + else SimpleSAML_Logger::debug("XMLcan: ".$dom->saveXML()); if(method_exists($dom, 'C14N')) { return $dom->C14N(true, false); } - SimpleSAML_Logger::debug("This transform requires the C14N() method to exist in the DOM extension"); + throw new Exception('This transform requires the C14N() method to exist in the DOM extension'); } } diff --git a/modules/InfoCard/lib/UserFunctions.php b/modules/InfoCard/lib/UserFunctions.php new file mode 100644 index 0000000000000000000000000000000000000000..4c49fff77c9d3eed43e0f5f0b9d23c5312147767 --- /dev/null +++ b/modules/InfoCard/lib/UserFunctions.php @@ -0,0 +1,74 @@ +<?php +/* +* AUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: edit this functions to fit your needs +*/ + +class sspmod_InfoCard_UserFunctions { + + /* Called by getinfocard.php and tokenservice.php + * INPUT: user and password + * OUTPUT: true if the data is correct or false in other case + */ + static public function validateUser($user,$pass){ + $status=false; + if( (strcmp($user,'usuario')==0) && (strcmp($pass,'clave')==0) ){ + $status=true; + } + return $status; + } + + + + /* Called by tokenservice.php + * INPUT: username, configured required claims, configured optional claims and requested claims + * OUTPUT: array of claims wiht value and display tag. + */ + static public function fillClaims($user, $configuredRequiredClaims, $configuredOptionalClaims, $requiredClaims){ + $claimValues = array(); + foreach ($requiredClaims as $claim){ + if (array_key_exists($claim,$configuredRequiredClaims) ){ + //The claim exists + $claimValues[$claim]['value']="value-".$claim; + $claimValues[$claim]['displayTag']=$configuredRequiredClaims[$claim]['displayTag']; + }else if (array_key_exists($claim,$configuredOptionalClaims) ){ + //The claim exists + $claimValues[$claim]['value']="value-".$claim; + $claimValues[$claim]['displayTag']=$configuredOptionalClaims[$claim]['displayTag']; + }else{ + //The claim DOES NOT exist + $claimValues[$claim]['value']="unknown-value"; + $claimValues[$claim]['displayTag']=$claim; + } + } + return $claimValues; + } + + + /* Called by getinfocard.php + * INPUT: valid username + * OUTPUT: array containing user data to create its InfoCard + */ + static public function fillICdata($user) { + $ICdata = array(); + $ICdata['CardId'] = 'urn:sts.uah.es:'.$user; + $ICdata['CardName'] = $user."-IC"; + $ICdata['CardImage'] = '/var/simplesaml/modules/InfoCard/www/resources/demoimage.png'; + $ICdata['TimeExpires'] = "9999-12-31T23:59:59Z"; + + //Credentials + $ICdata['DisplayCredentialHint'] = 'Enter your password'; + $ICdata['UserCredential'] = 'UsernamePasswordCredential'; //UsernamePasswordCredential, KerberosV5Credential, X509V3Credential, SelfIssuedCredential + $ICdata['UserName'] = 'usuario'; //UsernamePasswordCredential + $ICdata['KeyIdentifier'] = NULL; //X509V3Credential + $ICdata['PPID'] = NULL; //SelfIssuedCredential + +SimpleSAML_Logger::debug('ICDATA: '.$ICdata['CardImage']); + return $ICdata; + } + + +} +?> \ No newline at end of file diff --git a/modules/InfoCard/lib/Utils.php b/modules/InfoCard/lib/Utils.php new file mode 100644 index 0000000000000000000000000000000000000000..0df026495221018607692fbb4cac0ae6a5fbca51 --- /dev/null +++ b/modules/InfoCard/lib/Utils.php @@ -0,0 +1,108 @@ +<?php +/* +* AUTHOR: Samuel Muñoz Hidalgo +* EMAIL: samuel.mh@gmail.com +* LAST REVISION: 16-DEC-08 +* DESCRIPTION: some useful functions. +*/ + +class sspmod_InfoCard_Utils { + + /* + *INPUT: a PEM-encoded certificate + *OUTPUT: a PEM-encoded certificate without the BEGIN and END headers + */ + static public function takeCert($cert) { + $begin = "CERTIFICATE-----"; + $end = "-----END"; + $pem = file_get_contents($cert); + $pem = substr($pem, strpos($pem, $begin)+strlen($begin)); + $pem = substr($pem, 0, strpos($pem, $end)); + return str_replace("\n", "", $pem); + } + + + /* + *INPUT: a XML document + *OUTPUT: a canonicalized XML document + */ + static public function canonicalize($XMLdoc){ + $dom = new DOMDocument(); + $dom->loadXML($XMLdoc); + return ($dom->C14N(true, false)); + } + + + static public function thumbcert($cert){ + return base64_encode(sha1(base64_decode($cert), true)); + } + + + /* + *INPUT: a x509 certificate + *OUTPUT: Common Name or a self issued value if no input is given + *EXTRA: The output is used as issuer + */ + static public function getIssuer($cert){ + if ($cert==NULL){ + return 'http://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self'; + }else{ + $resource = file_get_contents($cert); + $check_cert = openssl_x509_read($resource); + $array = openssl_x509_parse($check_cert); + openssl_x509_free($check_cert); + $schema = $array['name']; + $pattern='/.*CN=/'; + $replacement=''; + $CN=preg_replace($pattern,$replacement,$schema); + return $CN; + } + } + + + + + + /* + * INPUT: claims schema (string) and a DOMNodelist with the requested claims in uri style + * OUTPUT: array of requested claims + * + */ + static public function extractClaims($ICschema, $nodeList){ + //Returns the Uri attribute from an attribute list + function getUri($attrList){ + $uri = null; + $end=false; + $i=0; + do{ + if ($i > $attrList->length){ + $end = true; + } else if (strcmp($attrList->item($i)->name,'Uri')==0){ + $end = true; + $uri = $attrList->item($i)->value; + } else { + $i++; + } + } while (!$end); + return $uri; + } + $requiredClaims = array(); + $schema = $ICschema."/claims/"; + SimpleSAML_Logger::debug("schema: ".$schema); + $pattern='/\//'; + $replacement='\/'; + $schema= '/'.preg_replace($pattern,$replacement,$schema).'/'; + for ($i=0;$i<($nodeList->length);$i++) { + $replacement=''; + $uri = getUri($nodeList->item($i)->attributes); + $claim = preg_replace($schema,$replacement,$uri); + $requiredClaims[$i]=$claim; + SimpleSAML_Logger::debug("uri: ".$uri); + SimpleSAML_Logger::debug("claim: ".$claim); + } + return $requiredClaims; +} + + +} +?> \ No newline at end of file diff --git a/modules/InfoCard/templates/default/login-infocard.php b/modules/InfoCard/templates/default/login-infocard.php index 1b439071a7bc405ccd036597c4654e8183265d33..48821e7e841e0fba545db4efdbb034596f1448b0 100644 --- a/modules/InfoCard/templates/default/login-infocard.php +++ b/modules/InfoCard/templates/default/login-infocard.php @@ -2,8 +2,8 @@ /* * AUTHOR: Samuel Muñoz Hidalgo * EMAIL: samuel.mh@gmail.com -* LAST REVISION: 1-DEC-08 -* DESCRIPTION: 'login-infocard' module template. +* LAST REVISION: 22-DEC-08 +* DESCRIPTION: InfoCard module template. */ $this->includeAtTemplateBase('includes/header.php'); if (!array_key_exists('icon', $this->data)) $this->data['icon'] = 'lock.png'; @@ -20,39 +20,67 @@ <p><?php echo $this->t('user_IC_text'); ?></p> - <form name="ctl00" id="ctl00" method="post" action="?"> - <?php foreach ($this->data['stateparams'] as $name => $value) { - echo('<input type="hidden" name="' . htmlspecialchars($name) . '" value="' . htmlspecialchars($value) . '" />'); - }?> - <ic:informationCard xmlns:ic="<?php echo $this->data['InfoCard']['schema'] ?>" name='xmlToken' + <form name="ctl00" id="ctl00" method="post" action="?AuthState=<?php echo $this->data['stateparams']['AuthState']?>"> +<!-- <ic:informationCard xmlns:ic="<?php echo $this->data['InfoCard']['schema'] ?>" name="xmlToken" issuer="<?php echo $this->data['InfoCard']['issuer']; ?>" - issuerPolicy="<?php echo $this->data['InfoCard']['issuerPolicy']; ?>" - tokenType="<?php echo $this->data['InfoCard']['tokenType']; ?>" - privacyUrl="<?php echo $this->data['InfoCard']['privacyURL']; ?>" - privacyVersion="<?php echo $this->data['InfoCard']['privacyVersion']; ?>"> + <?php + if ($this->data['InfoCard']['issuerPolicy']!='') echo 'issuerPolicy="'.$this->data['InfoCard']['issuerPolicy'].'"'; + if ($this->data['InfoCard']['tokenType']!='') echo 'tokenType="'.$this->data['InfoCard']['tokenType'].'"'; + if ($this->data['InfoCard']['privacyURL']!='') echo 'privacyUrl="'.$this->data['InfoCard']['privacyURL'].'"'; + if ($this->data['InfoCard']['privacyVersion']!='') echo 'privacyVersion="'.$this->data['InfoCard']['privacyVersion'].'"'; ?>> <?php $schema = $this->data['InfoCard']['schema']."/claims/"; foreach ($this->data['InfoCard']['requiredClaims'] as $claim=>$data) { - echo "<ic:add claimType = \"$schema".$claim."\" optional=\"false\" />\n"; + echo "<ic:add claimType = \"".$schema.$claim."\" optional=\"false\" />\n"; } foreach ($this->data['InfoCard']['optionalClaims'] as $claim=>$data) { - echo "<ic:add claimType = \"$schema".$claim."\" optional=\"true\" />\n"; + echo "<ic:add claimType = \"".$schema.$claim."\" optional=\"true\" />\n"; } unset($value);?> - </ic:informationCard> - <input type='image' src="<?php echo $this->data['IClogo']; ?>" align='center' style='cursor:pointer' /> + </ic:informationCard>--> + + <OBJECT type="application/x-informationCard" name="xmlToken"> + <?php + echo '<PARAM Name="issuer" Value="'.$this->data['InfoCard']['issuer']."\">\n"; + if ($this->data['InfoCard']['issuerPolicy']!='') echo '<PARAM Name="issuerPolicy" Value="'.$this->data['InfoCard']['issuerPolicy']."\">\n"; + if ($this->data['InfoCard']['tokenType']!='') echo '<PARAM Name="tokenType" Value="'.$this->data['InfoCard']['tokenType']."\">\n"; + if ($this->data['InfoCard']['privacyURL']!='') echo '<PARAM Name="privacyUrl" Value="'.$this->data['InfoCard']['privacyURL']."\">\n"; + if ($this->data['InfoCard']['privacyVersion']!='')echo '<PARAM Name="privacyVersion" Value="'.$this->data['InfoCard']['privacyVersion']."\">\n";?> + <PARAM Name="requiredClaims" Value="<?php + $schema = $this->data['InfoCard']['schema']."/claims/"; + foreach ($this->data['InfoCard']['requiredClaims'] as $claim=>$data) { + echo $schema.$claim." "; + }?>"> + <PARAM Name="optionalClaims" Value="<?php + $schema = $this->data['InfoCard']['schema']."/claims/"; + foreach ($this->data['InfoCard']['optionalClaims'] as $claim=>$data) { + echo $schema.$claim." "; + }?>"> + </OBJECT> + + <input type='image' src="<?php echo $this->data['IClogo']; ?>" style='cursor:pointer' /> </form> +<!-- GET INFOCARD SECTION --> <?php if (strcmp($this->data['CardGenerator'],'')>0) { - echo '<h2>Or get one</h2>'; - echo '<table border="0">'; + echo '<h2>'.$this->t('get_IC').'</h2>'; echo "<form action=\"". $this->data['CardGenerator'] ."\" method='post'>"; - echo "<tr><td>Username: </td><td><input type='text' name='username' value='usuario' /></tr></td>"; - echo "<tr><td>Password: </td><td><input type='password' name='password' value='clave' /></tr></td>"; - echo "<tr><td></td><td><input type='submit' name='Get_card' value='Get InfoCard' /></tr></td>"; - echo '</form>'; + echo '<table border="0">'; + echo "<tr><td>".$this->t('form_username').": </td><td><input type='text' name='username' value='usuario' /></td></tr>"; + echo "<tr><td>".$this->t('form_password').": </td><td><input type='password' name='password' value='clave' /></td></tr>"; + echo "<tr><td></td><td><input type='submit' name='get_button' value='".$this->t('get_button')."' /></td></tr>"; echo '</table>'; + echo '</form>'; } ?> + +<!-- HELP SECTION --> <h2><?php echo $this->t('help_header'); ?></h2> <p><?php echo $this->t('help_text'); ?></p> + <?php + if ((array_key_exists('contact_info_URL',$this->data)) && ($this->data['contact_info_URL']!=null)) + echo "<p><a href='".$this->data['contact_info_URL']."'>".$this->t('contact_info')."</a><p/>"; + if ((array_key_exists('help_desk_email_URL',$this->data)) && ($this->data['help_desk_email_URL']!=null)) + echo "<p><a href='".$this->data['help_desk_email_URL']."'>".$this->t('help_desk_email')."</a></p>"; + ?> + <?php $this->includeAtTemplateBase('includes/footer.php'); ?> \ No newline at end of file diff --git a/modules/InfoCard/www/login-infocard.php b/modules/InfoCard/www/login-infocard.php index 4989ddbbc9f91b8e9f2645e8f79e2bcb0e6988db..d33c7dbb73b0f9bab578f01f3e68c8964a650999 100644 --- a/modules/InfoCard/www/login-infocard.php +++ b/modules/InfoCard/www/login-infocard.php @@ -3,14 +3,14 @@ /* * AUTHOR: Samuel Muñoz Hidalgo * EMAIL: samuel.mh@gmail.com -* LAST REVISION: 1-DEC-08 +* LAST REVISION: 22-DEC-08 * DESCRIPTION: -* 'login-infocard' module. -* Allows an user to authenticate to the system with an Information Card. -* Infocard's claims are extracted passed as attributes. +* User flow controller. +* Displays the template and request a non null xmlToken */ + /* Load the configuration. */ $config = SimpleSAML_Configuration::getInstance(); $autoconfig = $config->copyFromBase('logininfocard', 'config-login-infocard.php'); @@ -20,6 +20,9 @@ $server_crt = $autoconfig->getValue('server_crt'); $IClogo = $autoconfig->getValue('IClogo'); $Infocard = $autoconfig->getValue('InfoCard'); $cardGenerator = $autoconfig->getValue('CardGenerator'); +$sts_crt = $autoconfig->getValue('sts_crt'); +$help_desk_email_URL = $autoconfig->getValue('help_desk_email_URL'); +$contact_info_URL = $autoconfig->getValue('contact_info_URL'); /* Load the session of the current user. */ @@ -30,24 +33,34 @@ if($session == NULL) { if (!array_key_exists('AuthState', $_REQUEST)) { +SimpleSAML_Logger::debug('NO AUTH STATE'); +SimpleSAML_Logger::debug('ERROR: NO AUTH STATE'); throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.'); +} else { + $authStateId = $_REQUEST['AuthState']; +SimpleSAML_Logger::debug('AUTH STATE: '.$authStateId); } -$authStateId = $_REQUEST['AuthState']; - if(array_key_exists('xmlToken', $_POST) && ($_POST['xmlToken']!=NULL) ) { +SimpleSAML_Logger::debug('HAY XML TOKEN'); $error = sspmod_InfoCard_Auth_Source_ICAuth::handleLogin($authStateId, $_POST['xmlToken']); }else { +SimpleSAML_Logger::debug('NO HAY XML TOKEN'); $error = NULL; } +unset($_POST); //Show the languages bar if reloaded + //Login Page $t = new SimpleSAML_XHTML_Template($config, 'InfoCard:login-infocard.php', 'InfoCard:logininfocard'); //(configuracion, template, diccionario) $t->data['header'] = 'simpleSAMLphp: Infocard login'; $t->data['stateparams'] = array('AuthState' => $authStateId); $t->data['IClogo'] = $IClogo; $t->data['InfoCard'] = $Infocard; +$t->data['InfoCard']['issuer'] = $autoconfig->getValue('tokenserviceurl');//sspmod_InfoCard_Utils::getIssuer($sts_crt); $t->data['CardGenerator'] = $cardGenerator; +$t->data['help_desk_email_URL'] = $help_desk_email_URL; +$t->data['contact_info_URL'] = $contact_info_URL; $t->data['error'] = $error; $t->show(); exit(); diff --git a/modules/InfoCard/www/resources/demoimage.png b/modules/InfoCard/www/resources/demoimage.png new file mode 100644 index 0000000000000000000000000000000000000000..8242048599b7ccf3067657330ded38cec3f92f28 Binary files /dev/null and b/modules/InfoCard/www/resources/demoimage.png differ