Location: PHPKode > projects > phpMyOrdering > phpMyOrdering-0.1.7-alpha/phpMyPurchasing-0.1.2-alpha/scripts/classes/class.authentication.php
<?PHP
/*
 * phpMyAuth
 * Jason Gerfen [hide@address.com]
 *
 * class.authentication.php - Handle user authentication
 */

class Authenticate
{

 function DecideAuth( $token, $user, $pass, $server )
 { //echo "<pre>"; print_r( func_get_args() ); echo "</pre>";
  global $defined;
  if( isset( $token ) ) {
   return $this->ReAuthenticate( $token, $server );
  } else {
   return $this->PrimaryAuthentication( $user, $pass, $server );
  }
 }

 function checkLDAP( $user, $pass )
 {
  global $defined;
  global $handles;

  // are we configured to use ldap?
  if( ( !empty( $defined['ldapuser'] ) ) && ( !empty( $defined['ldappass'] ) ) && ( !empty( $defined['ldapdomain'] ) ) && ( !empty( $defined['ldapserv'] ) ) && ( !empty( $defined['ldapport'] ) ) && ( !empty( $defined['binddn'] ) ) && ( !empty( $defined['basedn'] ) ) ) {
   // attempt to bind for this user as long as there is at least a username
   // found in the local mysql database
   $data = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] );
   $query = "SELECT * FROM `users` WHERE `txtUserName` = \"" . $user . "\"";
   if( ( $value = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $data ), $data ) ) !== -1 ) {
    if( $handles['db']->dbNumRows( $value ) > 0 ) {
     // proceed to bind because a user was found locally
     if( $handles['ldap']->auth( $user, $pass, $defined['ldapserv'], $defined['ldapport'] ) === 0 ) {
      // a good bind? lets propogate the user/pass to the database to limit ldap queries /cached
      $sql = "UPDATE `users` SET `txtUserPassword1` = sha1( \"" . $pass . "\" ) WHERE `txtUserName` = \"" . $user . "\" LIMIT 1";
      if( ( $value = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $sql, $data ), $data ) ) !== -1 ) {
       if( $handles['db']->dbNumRowsAffected( $data ) === 1 ) {
        $ret = 0;
       } else {
        $ret = 1;
       }
      } else {
       $ret = 2;
      }
     } else {
      $ret = 3;
     }
    } else {
     $ret = 4;
    }
   } else {
    $ret = 5;
   }
  } else {
   $ret = 6;
  }
  $handles['ldap']->closeConn();
  return $ret;
 }

 function PrimaryAuthentication( $user, $pass, $server )
 {
  global $defined;
  global $handles;

  // ensure our data is present
  if( ( empty( $user ) ) || ( empty( $pass ) ) || ( count( $server ) < 0 ) ) {
   $ret = 1;
  } else {
   // validate user credentials
   if( ( $handles['val']->ValidateAlphaChar( $user ) === -1 ) || ( $handles['val']->ValidatePassword( $pass ) === -1 ) ) {
    $ret = 2;
   } else {
    // ok now we need to look the user up
    $data = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] );
    $query = "SELECT * FROM `users` WHERE `txtUserName` = \"" . $user . "\" AND `txtUserPassword1` = sha1( \"$pass\" )";
    if( ( $value = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $data ), $data ) ) === -1 ) {
     $ret = 3;
    } else {
     if( $handles['db']->dbNumRows( $value ) <= 0 ) {
      // check ldap real quick...
      if( $this->checkLDAP( $user, $pass ) === 0 ) {
       $ret = 0;
      } else {
       $ret = 4;
      }
     } else {
      $array = $handles['db']->dbArrayResultsAssoc( $value );
      $array[0]['password'] = $pass;
      // reassign $array[0]['password'] hash to submitted password
      // since we have a valid user we need to perform the following:
      //  + Create a private, and public encryption key pair
      //  + Update the user record to store the private key
      //  + Generate a re-usable encrypted token we can pass
      //    back and forth between applications
      $privatekey = $handles['encrypt']->EncodePrivToHex( $handles['encrypt']->GeneratePrivateKey( $defined['enckeygen'] ) );
      $publickey = $handles['encrypt']->GeneratePublicKey( $privatekey );
      // since we are going to store the session private key iv data in the database we
      // must initialize the encryption class (if the mcrypt libs are present)
      if( function_exists( "mcrypt_encrypt" ) ) {
       $cipher = new Cipher(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
       $cipher->setIV();
       $sessioniv = $cipher->getIV();
      } else {
       // since this php configuration does not
       // utilize the mcrypt libs we need to generate
       // a spoofed iv
       $sessioniv = rand( microtime(), microtime() );
      }
      // create some time stamp data
      $access_date = $handles['misc']->GenDate();
      $access_time = $handles['misc']->GenTimeRead();
      $time = $handles['misc']->GenTime();

      // destroy any existing sessions for this user
      $query = "UPDATE `users` SET `ip` = '', `referrer` = '', `agent` = '', `session` = '', `iv` = '' WHERE `id` = \"" . $array[0]['id'] . "\" LIMIT 1";
      $value = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $data ), $data );

      // update user record with session requirements
      $query = "UPDATE `users` SET `ip` = \"" . md5($server['REMOTE_ADDR']) . "\", `referrer` = \"" . $server['HTTP_REFERER'] . "\", `agent` = \"" . md5($server['HTTP_USER_AGENT']) . "\", `access_date` = \"" . $access_date . "\", `access_time` = \"" . $access_time . "\", `session` = \"" . $privatekey . "\", `iv` = \"" . $sessioniv . "\" WHERE `id` = \"" . $array[0]['id'] . "\"";
      if( ( $value = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $data ), $data ) ) === -1 ) {
       $ret = 5;
      } else {
       if( ( $token = $handles['encrypt']->EncodeAuthTokenHeavy( $array, $sessioniv, $time, $publickey, $server ) ) === -1 ) {
        $ret = 6;
       } else {
        $ret = 0;
       }
      }
     }
    }
   }
  }
  if( $ret === 0 ) {
   $handles['session']->regen( true );
   $_SESSION['token'] = $token;
  }
  $handles['db']->dbFixTable( "sessions", $dbconn );
  $handles['db']->dbFixTable( "users", $dbconn );
  return $ret;
 }

 /*
  * During the PrimaryAuthentication function we created a private and public key
  * The private key gets placed in the users record for later use
  *
  * The private key is passed to the encode function and is used to encrypt and base64_encode
  * the various user attributes we require during the Re-Authentication function.
  *
  * The process takes the following steps during re-authentication
  * 1. Ensure we have a registered and valid session token
  * 2. Split the token apart and use the base64_decode function to decode each element
  * 3. Use the last element of the session token (the public key) to unencrypt each element
  * 4. Pass the array of unencrypted elements to check the following:
  *  + Ensure the remote IP address is the same as the one registered during the primary authentication
  *  + Ensure the referring page is coming from something located on the $defined['server'] ie. http://server.com/page.php is from server.com
  *  + Ensure the browser agent string has not changed as well
  *  + Make sure the user has not been timed out based on the authenticated time stamp vs. the defined timeout variable
  *  + Do a lookup on the decoded username and password to ensure they are indeed a valid user in the database
  *  + Regenerate the session id, destroy everything and let the user continue about their business
  */
 function ReAuthenticate( $token, $server )
 {
  global $defined;
  global $handles;

  // set a flag depending on the referer (SSO referer fix)
  $sso = ( !eregi( $defined['hostname'], $server['HTTP_REFERER'] ) ) ? $sso = true : $sso = false;

  // this next step will give us plaintext of the base64_encoded / encrypted token elements
  if(isset($token)) {
   if(($array = $handles['encrypt']->DecodeAuthTokenHeavy($token))===1) {
    return ( $sso === true ) ? "7" : 7;
   }
  } else {
   return ( $sso === true ) ? "7" : 7;
  }
  if( count( $array ) < 10 ) {
   return ( $sso === true ) ? "8" : 8;
  } else {
   // do a lookup based on the username
   $sql = "SELECT * FROM `users` WHERE `txtUserName` = \"" . $array[0] . "\" LIMIT 1";
   $dbconn = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] );
   if( ( $value = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $sql, $dbconn ), $dbconn ) ) === -1 ) {
    return ( $sso === true ) ? "9" : 9;
   } else {
    if( count( $handles['db']->dbNumRows( $value ) ) <= 0 ) {
     return ( $sso === true ) ? "10" : 10;
    } else {
     $user_data = $handles['db']->dbArrayResultsAssoc( $value );
     // perform our verifications by first checking that the public key and iv data matches up with the stored private key and iv
     if( ( md5( $user_data[0]['session'] ) !== $array[9] ) || ( md5( $user_data[0]['iv'] ) !== $array[8] ) ) {
      return ( $sso === true ) ? "11" : 11;
     } else {
      // reassign referer check if necessary for SSO functionality
      if( eregi( $defined['hostname'], $server['HTTP_REFERER'] ) ) { $serv[0] = $defined['hostname']; } else { $serv = preg_split( '/\?/', $server['HTTP_REFERER'] ); }
      // do comparisons on ip, referer and browser agent
      if( ( $user_data[0]['ip'] !== $array[5] ) || ( !strstr( $user_data[0]['referrer'], $serv[0] ) ) || ( $user_data[0]['agent'] !== $array[7] ) ) {
       return ( $sso === true ) ? "12" : 12;
      } else {
       // make sure they haven't expired their session
       if( ( $this->AuthTimeOut( $defined['timeout'], $array[4], $handles['misc']->GenTime() ) ) === -1 ) {
        return ( $sso === true ) ? "13" : 13;
       } else {
        // all right, make sure the username, password within decrypted token info is
        // valid and let the user proceed
        $sql = "SELECT * FROM `users` WHERE `txtUserName` = \"" . $array[0] . "\" AND `txtUserPassword1` = \"" . sha1( $array[1] ) . "\" LIMIT 1";
        if( ( $value = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $sql, $dbconn ), $dbconn ) ) === -1 ) {
         return ( $sso === true ) ? "14" : 14;
        } else {
         if( count( $handles['db']->dbNumRows( $value ) ) !== 1 ) {
          return ( $sso === true ) ? "15" : 15;
         } else {
          // fix for json ajax requests expecting string where an integer is returned
          if( $sso === false ) { $handles['session']->regen( true ); }
          return ( $sso === true ) ? "0" : 0;
         }
        }
       }
      }
     }
    }
   }
  }
 }

 function logout( $token, $id )
 {
  global $handles;
  global $defined;

  $array = $handles['encrypt']->DecodeAuthTokenHeavy( $token );

  $dbconn = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] );
  $sql = "UPDATE `users` SET `ip` = '', `referrer` = '', `agent` = '', `session` = '', `iv` = '' WHERE `txtUserName` = \"" . $array[0] . "\" LIMIT 1";
  $handles['db']->dbQuery( $handles['val']->ValidateSQL( $sql, $dbconn ), $dbconn );

  return session_destroy();
 }

 function AuthTimeOut( $constant, $time, $current )
 {
  if( ( $current - $time ) > $constant ) {
   $data->value = -1;
  } else {
   $data->value = 0;
  }
  return $data->value;
 }

} 

?>
Return current item: phpMyOrdering