I have really very strange problem and need help

We have for example 2 domains: ny.com and la.com. In google they are
seperate accounts. In our db they are stored like [EMAIL PROTECTED],
[EMAIL PROTECTED] etc

We are using php sample for sso (not the latest version.

Problem Case: User have 2 valid mailboxes in both domains:
[EMAIL PROTECTED] and [EMAIL PROTECTED] All users logins to both domains
from one web form

1. User logins to [EMAIL PROTECTED] and goes to its mailbox
2. User doesn't press signout button and returns back to login page
3. User logins to [EMAIL PROTECTED] and goes to its mailbox
4. User again doesn't press signout button and returns back to login
page
5. (!!!) And now user try to login to somebody else's mailbox
[EMAIL PROTECTED] with any password and he logins successfuly to the
mailbox he doesn't own!

I can imagine that here are problems with saml requests and sessions.
Our programmer is several months is a former programmer and I don't
have enouph php knowledge to fix it quickly.

Can anybody suggets what goes wrong? Belong my process_response.php
code (modified by former programmer slightly)

Sorry code is too long for reading :) but I hope that a professional
can find what is wrong quickly...


<?php
session_set_cookie_params (0, '/', '.mydomain.com');
if (session_id() == "") {
  session_start();
  #  setcookie('PHPSESSID', session_id(), 0, '/');
}

require_once 'saml_util.php';

$domains = array(
        'ny.com' => 'ny.com',
        'la.com' => 'la.com',
        );

$services = array (
    'mail'      => 'mail',
    'calendar'  => 'calendar',
    'docs'      => 'docs'
);

/**
 * The login method should either return null if the user is not
 * successfully authenticated, or the user's username if the user is
 * successfully authenticated.
 * @param string $username
 * @param string $password
 * @return string
 */
function login($username, $password, $domain) {
  // Stage II: Update this method to call your authentication
mechanism.
  // Return username for successful authentication. Return null
  // for failed authentication.
    $link = @mysql_connect('111.111.111.111', 'xxx', 'xxxxxxxxx');
    mysql_select_db('namedb', $link);
    $query = sprintf("SELECT Account FROM UserSession WHERE
Account='%s' AND Password='%s'",
    mysql_real_escape_string("[EMAIL PROTECTED]"),
    mysql_real_escape_string($password));
    $result = mysql_query($query, $link);
    if (!$result) {
        return '';
    }
    $rows = mysql_num_rows($result);
    if ($rows == 1) {
        return $username;
    } else {
        return '';
    }
}

/**
 * Returns a SAML response with various elements filled in.
 * @param string $authenticatedUser The Google Apps username of the
                 authenticated user
 * @param string $notBefore The ISO 8601 formatted date before which
the
                 response is invalid
 * @param string $notOnOrAfter The ISO 8601 formatted data after which
the
                 response is invalid
 * @param string $rsadsa 'rsa' if the response will be signed with RSA
keys,
                 'dsa' for DSA keys
 * @param string $requestID The ID of the request we're responding to
 * @param string $destination The ACS URL that the response is
submitted to
 * @return string XML SAML response.
 */
function createSamlResponse($authenticatedUser, $notBefore,
$notOnOrAfter,
                            $rsadsa, $requestID, $destination) {
  global $domainName;

  $samlResponse = file_get_contents('templates/
SamlResponseTemplate.xml');
  $samlResponse = str_replace('<USERNAME_STRING>',
$authenticatedUser,
                                  $samlResponse);
  $samlResponse = str_replace('<RESPONSE_ID>', samlCreateId(),
$samlResponse);
  $samlResponse = str_replace('<ISSUE_INSTANT>',
samlGetDateTime(time()),
                                  $samlResponse);
  $samlResponse = str_replace('<AUTHN_INSTANT>',
samlGetDateTime(time()),
                                  $samlResponse);
  $samlResponse = str_replace('<NOT_BEFORE>', $notBefore,
$samlResponse);
  $samlResponse = str_replace('<NOT_ON_OR_AFTER>', $notOnOrAfter,
                                  $samlResponse);
  $samlResponse = str_replace('<ASSERTION_ID>', samlCreateId(),
$samlResponse);
  $samlResponse = str_replace('<RSADSA>', strtolower($rsadsa),
$samlResponse);
  $samlResponse = str_replace('<REQUEST_ID>', $requestID,
$samlResponse);
  $samlResponse = str_replace('<DESTINATION>', $destination,
$samlResponse);
  $samlResponse = str_replace('<ISSUER_DOMAIN>', $domainName,
$samlResponse);

  return $samlResponse;
}

/**
 * Signs a SAML response with the given private key, and embeds the
public key.
 * @param string $responseXmlString
 * @param string $pubKey
 * @param string $privKey
 * @return string
 */
function signResponse($responseXmlString, $pubKey, $privKey) {
  // NOTE: You may want to point this function to a directory on your
  // web server that is suitable for temporary files and is not in
your
  // web server path.
  global $error;

  // generate unique temporary filename
  $tempFileName = '/tmp/saml-response-' . samlCreateId() . '.xml';
  while (file_exists($tempFileName))
             $tempFileName = 'saml-response-' . samlCreateId() . '.xml';

  if (!$handle = fopen($tempFileName, 'w')) {
    echo 'Cannot open temporary file (' . $tempFileName . ')';
    exit;
  }

  if (fwrite($handle, $responseXmlString) === FALSE) {
    echo 'Cannot write to temporary file (' . $tempFileName . ')';
    exit;
  }

  fclose($handle);

  // The path to xmlsec/xmlsec1 may need to be adjusted here.
  // xmlsec supports many key types, which can be selected
  // by using other command-line parameters.
  $cmd = '/usr/local/bin/xmlsec1 --sign --privkey-pem ' . $privKey .
             ' --pubkey-der ' . $pubKey . ' --output ' . $tempFileName .
             '.out ' . $tempFileName;
  exec($cmd, $resp);
  unlink($tempFileName);

  $xmlResult = @file_get_contents($tempFileName . '.out');
  if (!$xmlResult) {
    $error = 'Unable to sign XML response. Please ensure that xmlsec
is ' .
                 'installed, and check your keys.';
    return false;
  } else {
    unlink($tempFileName . '.out');
    return $xmlResult;
  }
}

if ($_POST['username']) {
  $user = $_POST['username'];
  $pass = $_POST['password'];
  $domain = $_POST['domain'];
  $service = $_POST['service'];
  if (!isset($service) || $service == '') {
      $service = 'mail';
  }
  $_SESSION['username'] = $user;
  $_SESSION['password'] = $pass;
  $_SESSION['domain'] = $domain;
  $_SESSION['service'] = $service;
  session_write_close();
  header("Location: http://$service.google.com/a/"; .
$domains[$domain]);
  exit();
} else if($_GET['SAMLRequest'] != '') {
  $SAMLRequest =$_GET['SAMLRequest'];
  $username = $_SESSION['username'];
  $password = $_SESSION['password'];
  $domain = $_SESSION['domain'];
  $service = $_SESSION['service'];
  $relayStateURL = "http://$service.google.com/a/"; .
$domains[$domain];
  if ($SAMLRequest == '') {
    $error = 'Error: Unspecified SAML parameters.';
  } else {
    $requestXmlString = samlDecodeMessage($SAMLRequest);
    if (($requestXmlString == '')||($requestXmlString === FALSE)) {
      $error = 'Unable to decode SAML Request.';
    } else {
      $samlAttr = getRequestAttributes($requestXmlString);
      $issueInstant = $samlAttr['issueInstant'];
      $acsURL = $samlAttr['acsURL'];
      $providerName = $samlAttr['providerName'];
      $requestID = $samlAttr['requestID'];

      $login = login($username, $password, $domain);
      if ($login == '') {
        $error = 'Login Failed: Invalid user.';
      } else {
        // Acquire public and private DSA keys

         /*
        * Stage III: Update the DSA filenames to identify the
locations of
        * the DSA/RSA keys that digitally sign SAML responses for your
        * domain. The keys included in the reference implementation
sign SAML
        * responses for the psosamldemo.net domain.
        */

        $pubKey = 'keys/dsapubkey.der';
        $privKey = 'keys/dsaprivkey.pem';
        $keyType = 'dsa';

        // generate NotBefore and NotOnOrAfter dates
        $notBefore = samlGetDateTime(strtotime('-5 minutes'));
        $notOnOrAfter = samlGetDateTime(strtotime('+10 minutes'));

        // Sign XML containing user name with specified keys
        $responseXmlString = createSamlResponse($login, $notBefore,
                                                            $notOnOrAfter, 
$keyType,
                                                            $requestID, 
$acsURL);
        $samlResponse = signResponse($responseXmlString, $pubKey,
$privKey);
      }
    }
  }
  if ($error != '') {
      if ($error == 'Login Failed: Invalid user.') {
          $error = 'error';
      } else {
          $error = 'error';
      }
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://
www.w3.or
g/TR/xhtml1/loose.dtd">
<html><head><title>Mysite</title><meta content="text/html;
charset=utf-8" http-equiv=Content-Type /><meta http-equiv= "pragma"
content="no-cache" />

<meta http-equiv="Cache-Control" content="no-store" /><link
rel="alternate" type="application/rss+xml" title="RSS 2.0" href="/rss/
index.rss" />

<style type="text/css" media="screen">@import url("/css/
main.css");@import url("/css/in.css");.error {color: #a00;}</style></
head>

<body class="signup"><div id="minWidth"><div id="middle">

<table class="tbl"><tr>
<td id="leftCol"></td>
<td id="centerCol"><div id="hot-news">
<div class="topic_stories"><div id="main"><h1>Login</h1><form
action="" method="post"><input type="hidden" name="service" value="<?
echo htmlspecialchars($service) ?>">

<table>
        <tr>
        <td><label for="username">Username:</label></td>
        <td><input name="username" id="username" value="<? echo
htmlspecialchars($username) ?>" />

@ <select class="select" name="domain"><? foreach (array('ny.com',
'la.com') as $host) { ?>
        <option value="<? echo $host ?>"<? if ($domain == $host) { ?>
selected="selected"<? } ?>><? echo $host ?></option>
        <? } ?></select>

    <div class="error"><? if ($error) { ?><p><? echo $error ?></
p><? } ?></div>
        </td>\
    </tr>
    <tr>
        <td><label for="password">Password:</label></td>
        <td><input id="password" name="password" type="password"></td>
    </tr>
    <tr>
        <td colspan="2"><input name="Login" value="Login" type="submit"></
td>
    </tr>
</table>
</form>
</div>
</div>
</div>
</td>

</div></body></html>
<?
  } else if ($samlResponse != '') {
?>
<html>
<head>
</head>
<body onload="document.acsForm.submit()">

<form name="acsForm" action="<?php echo $acsURL; ?>" method="post">

<div style="display: none">

<textarea rows=10 cols=80 name="SAMLResponse"><?php echo
$samlResponse; ?></textarea>
<textarea rows=10 cols=80 name="RelayState"><?php echo
$relayStateURL; ?></textarea>
</div>

<noscript><input type="submit" value="Continue"></noscript></form></
body></html>

<?
  }
} else {
}
?>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Apps APIs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/google-apps-apis?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to