| 
<?php
 /*
 * AUTHOR: Samuel Muñoz Hidalgo
 * EMAIL: [email protected]
 * LAST REVISION: 24-APR-09
 * DESCRIPTION:
 *        Will send cards to other applications via web.
 *        Symmetric cryptography and IP filtering are available.
 */
 
 
 /*
 * DESCRIPTION: used to encode the data attribute sent GET method
 * TAKEN FROM:  http://es2.php.net/manual/es/function.base64-encode.php#63543
 */
 function urlsafe_b64encode($string) {
 $data = base64_encode($string);
 $data = str_replace(array('+','/','='),array('-','_',''),$data);
 return $data;
 }
 
 
 /*
 * DESCRIPTION: used to decode the data attribute sent GET method
 * TAKEN FROM:  http://es2.php.net/manual/es/function.base64-encode.php#63543
 */
 function urlsafe_b64decode($string) {
 $data = str_replace(array('-','_'),array('+','/'),$string);
 $mod4 = strlen($data) % 4;
 if ($mod4) {
 $data .= substr('====', $mod4);
 }
 return base64_decode($data);
 }
 
 
 /*CASE 1 AND 2
 * -Has Organization
 * -And chains to a trusted root CA
 * -NOTE: Based on V1.0, written for compatibility with DigitalMe PPID calculation
 */
 function calculate_RP_PPID_Seed_2_2007 ($certs) {
 $check_cert = openssl_x509_read(file_get_contents($certs[0]));
 $array = openssl_x509_parse($check_cert);
 openssl_x509_free($check_cert);
 $OrgIdString = ('|O="'.$array['subject']['O'].'"|L="'.$array['subject']['L'].'"|S="'.$array['subject']['ST'].'"|C="'.$array['subject']['C'].'"|');
 $numcerts = sizeof($certs);
 for($i=1;$i<$numcerts;$i++){
 $check_cert = openssl_x509_read(file_get_contents($certs[$i]));
 $array = openssl_x509_parse($check_cert);
 openssl_x509_free($check_cert);
 $tmpstring = '|ChainElement="CN='.$array['subject']['CN'].', OU='.$array['subject']['OU'].', O='.$array['subject']['O'].', L='.$array['subject']['L'].', S='.$array['subject']['ST'].', C='.$array['subject']['C'].'"';
 $OrgIdString = $tmpstring.$OrgIdString;
 }
 $OrgIdBytes = iconv("UTF-8", "UTF-16LE", $OrgIdString);
 $RPPPIDSeed = hash('sha256', $OrgIdBytes,TRUE);
 return $RPPPIDSeed;
 }
 
 
 /*
 * DESCRIPTION: Calculate the PPID for a card
 * INPUT: card ID, and RP certificates
 * OUTPUT: PPID asociated to a Relying Party
 */
 function calculate_PPID($cardid, $rp_cert) {
 $CardIdBytes = iconv("ISO-8859-1", "UTF-16LE", $cardid);
 $CanonicalCardId = hash('sha256', $CardIdBytes,TRUE);
 $RPPPIDSeed = calculate_RP_PPID_Seed_2_2007($rp_cert);
 $PPID = hash('sha256', $RPPPIDSeed.$CanonicalCardId,TRUE);
 return $PPID;
 }
 
 
 /*
 *
 * INPUT: VOID
 * OUPUT: String with the invoked URL
 */
 function curPageURL() {
 $pageURL = 'http';
 if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
 $pageURL .= "://";
 if ($_SERVER["SERVER_PORT"] != "80") {
 $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
 } else {
 $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
 }
 return $pageURL;
 }
 
 
 
 
 //TAD
 
 /*
 * INPUT: String (attribute length + attribute not begginning with a number) n times , number of attributes
 * OUPUT: Array with attributes in order
 */
 function parse_attributes($parsing_string, $num_attrs){
 for ($i=0 ; $i<$num_attrs ; $i++) {
 if (preg_match('/^[\d]*/', $parsing_string, $res)){
 if (!($output[$i] = substr($parsing_string,strlen($res[0]),$res[0]))){
 return null;
 }
 $parsing_string = substr($parsing_string, strlen($res[0])+strlen($output[$i]));
 } else {
 return null;
 }
 }
 return $output;
 }
 
 
 /*
 * Enable downloading an specific card, store Radius request
 * INPUT: username, cardid, and radius request time
 * OUTPUT; uuid of the stored request
 */
 function enable_download($username, $cardid){
 //almacenar existencia
 
 //Add Timestamp to response
 $time = 'x'.time(); //Cannot start with a number
 
 $uuid = uniqid();
 $handle = fopen(SimpleSAML_Utilities::getTempDir() . "/$uuid",'w');
 if ($handle) {
 fwrite($handle, strlen($username).$username.strlen($cardid).$cardid.strlen($time).$time);
 fclose ($handle);
 return $uuid;
 } else {
 return false;
 }
 }
 
 
 /*
 * Disable downloading an specific card, should be called when ending a request = Infocard is Issued
 *
 */
 function disable_download($uuid){
 unlink("/tmp/$uuid");
 }
 
 
 /*
 * ¿Should I generate a card?
 *
 */
 function is_card_enabled($uuid, $delivery_time){
 $now = time();
 $filename = SimpleSAML_Utilities::getTempDir() . "/$uuid";
 
 //File check
 if (!file_exists($filename)) return false; //File doesn't exist
 
 //Time check
 $handle = fopen($filename,'r');
 if ($handle) {
 $data = fread($handle, filesize($filename));
 fclose ($handle);
 
 $parsed_data = parse_attributes($data, 3);
 $parsed_data[2] = substr($parsed_data[2],1); //Extracting numeric value
 
 $time = $parsed_data[2];
 $endtime = $time + $delivery_time;
 if (($now<=$time)||($now>$endtime)) return false; //Incorrect time
 return $parsed_data;
 } else {
 return false; //Could not read the file
 }
 
 }
 
 
 /*
 * Check if the user is in the connected table
 * Update the row with the created Infocard card_ID
 */
 function DB_update_connected_user ($username, $DB_params){
 $card_id = sspmod_InfoCard_UserFunctions::generate_card_ID($username);;
 $dbconn = pg_connect('host='.$DB_params['DB_host'].'  port='.$DB_params['DB_port'].'  dbname='.$DB_params['DB_dbname'].' user='.$DB_params['DB_user'].'  password='.$DB_params['DB_password']);
 $result = pg_fetch_all(pg_query_params($dbconn, 'SELECT * FROM connected_users WHERE name = $1', array("$username")));
 if ($result[0]){
 pg_update($dbconn, 'connected_users', array('card_id'=>$card_id), array('name'=>$username));
 return true;
 } else {
 return false;
 }
 }
 
 
 
 $config = SimpleSAML_Configuration::getInstance();
 $autoconfig = $config->copyFromBase('logininfocard', 'config-login-infocard.php');
 $configuredIP =   $autoconfig->getValue('configuredIP');
 
 
 //RADIUS Request - Send One Time URL
 if ( (strcmp($_GET['ident'],'RADIUS')==0) && (($configuredIP == null) || ($_SERVER['REMOTE_ADDR'] == $configuredIP)) ){
 
 /* Load the configuration. */
 $key =   $autoconfig->getValue('symmetric_key');
 $internalkey = hash('sha256', $autoconfig->getValue('internal_key'));
 
 $encrequest = urlsafe_b64decode($_GET['data']);
 if (!$encrequest) throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
 
 // Encryption
 if ($key!=null) {
 $iv = urlsafe_b64decode($_GET['iv']);
 if (!$iv)  throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
 $enckey = hash('sha256', $key);
 $request = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, pack("H*",$enckey), $encrequest, MCRYPT_MODE_CBC, $iv);
 } else {
 $request = $encrequest;
 }
 
 //Parse Attributes (username lenght + username + cardid length + cardid)
 $parsed_request = parse_attributes($request, 2);
 
 
 //Enable card for downloading (username+cardid+time)
 $response = enable_download($parsed_request[0],$parsed_request[1]);
 if(!$response) throw new SimpleSAML_Error_NotFound('FUNCTION enable_download, error accessing directory');
 
 
 // Encrypt response for myself
 $response = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, pack("H*",$internalkey), $response, MCRYPT_MODE_CBC, $iv);
 $response = preg_replace('/\?.*/','',curPageURL()).'?data='.urlsafe_b64encode($response).'&iv='.urlsafe_b64encode($iv);
 
 
 // Encrypt response for RADIUS
 if ($key!=null){
 $encresponse  = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, pack("H*",$enckey), $response, MCRYPT_MODE_CBC, $iv);
 } else {
 $encresponse = $response;
 }
 
 // Send URL
 print base64_encode($encresponse);
 
 } else {  //Client Resquest- Send InfoCard
 //Get Attributes
 $encrequest = urlsafe_b64decode($_GET['data']);
 $iv = urlsafe_b64decode($_GET['iv']);
 if ((!$encrequest)||(!$iv)) throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
 
 /* Load the configuration. */
 $internalkey = hash('sha256', $autoconfig->getValue('internal_key'));
 $certificates =   $autoconfig->getValue('certificates');
 $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');
 $ICconfig['UserCredential'] = $autoconfig->getValue('UserCredential');
 $IC_lifetime_delivery = $autoconfig->getValue('IC_lifetime_delivery');
 $DB_params = $autoconfig->getValue('DB_params');
 
 // Encryption
 $request = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, pack("H*",$internalkey), $encrequest, MCRYPT_MODE_CBC, $iv);
 
 $parsed_request = is_card_enabled($request, $IC_lifetime_delivery);
 if ($parsed_request && DB_update_connected_user($parsed_request[0], $DB_params)) {
 // Calculate PPID
 $ppid = base64_encode(calculate_PPID($parsed_request[1], $certificates));
 
 // Create InfoCard
 $ICdata = sspmod_InfoCard_UserFunctions::fillICdata($parsed_request[0],$ICconfig['UserCredential'],$ppid);
 $IC = sspmod_InfoCard_STS::createCard($ICdata,$ICconfig);
 
 disable_download($request);
 
 //Send Infocard
 print ($IC);
 } else {
 throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
 }
 }
 
 
 ?>
 
 |