Local.inc :
class TwoPhase_Challenge_Crypt_Auth extends Auth {
var $classname
= "TwoPhase_Challenge_Crypt_Auth";
var $lifetime = 15;
var $magic = "ADFGTKL4Q"; ## Challenge seed
var $database_class = "DB_CLASS";
var $database_table = "auth_user_md5";
function auth_preauth() {
global $username, $password, $challenge, $response;
return $this->auth_validatelogin();
}
function auth_loginform() {
global $sess;
global $challenge;
global $_PHPLIB;
global $HTTP_HOST;
global $TP_remember;
global $TP_login;
$challenge = md5(uniqid($this->magic));
$sess->register("challenge");
include($_PHPLIB
["libdir"] . "twophase_loginform.ihtml");
}
function generate_password($nb_char)
{
srand ((double) microtime() * 1000000);
$autorized_char = "9&FV/DAn[1Yp_UCw4#Tl=iL+Bz0W}
XKg3(EvrS-Jo5R2IM*xkH]Qu8~dqN6mtPaj7Z{hsyOf)Gcbe";
$pass = "";
while(strlen($pass)<$nb_char)
{
$pass .= substr($autorized_char,(rand()%(strlen
($autorized_char))),1);
}
return($pass);
}
function auth_validatelogin() {
global $username, $password, $challenge,
$response, $remember;
$this->auth["uname"]=stripslashes
($username); ## This provides access
for "loginform.ihtml"
$this->db->query(sprintf("select
user_id,perms,password ".
"from %s where username = '%s'",
$this->database_table,
addslashes(stripslashes
($username))));
while($this->db->next_record()) {
$uid = $this->db->f("user_id");
$perm = $this->db->f("perms");
$pass = $this->db->f("password"); ## Password
is stored as a md5 hash
}
$exspected_response = md5(stripslashes
($username).":$pass:$challenge");
switch($remember)
{
case "yes":
setcookie("twophase_remember", "yes", time()
+315360000);
setcookie("twophase_login", trim($username),
time()+315360000);
break;
case "no":
setcookie("twophase_remember", "no", time()
+315360000);
setcookie("twophase_login");
break;
}
if ($response == "") { ##
True when JS is disabled
if (md5($password) != $pass) { ##
md5 hash for non-JavaScript browsers
return false;
}
} elseif ($exspected_response != $response) { ##
Response is set, JS is enabled
return false;
}
## If perm is referenced then reset password to
force unique usage
if (strstr($perm, "referenced")) {
$fake_password = md5($this->generate_password
(10));
$this->db->query(sprintf("update %s set password
= '%s' where user_id = '%s'",
$this->database_table,
$fake_password,
$uid));
}
$this->auth["perm"] = $perm;
return $uid;
}
}
class TwoPhase_Default_Challenge_Crypt_Auth extends
TwoPhase_Challenge_Crypt_Auth {
var $classname
= "TwoPhase_Default_Challenge_Crypt_Auth";
var $nobody = true;
}
class TwoPhase_Perm extends Perm {
var $classname = "TwoPhase_Perm";
var $permissions = array(
"referenced" => 1,
"user" => 2,
"admin" => 4
);
function perm_invalid($does_have, $must_have) {
global $perm, $auth, $sess;
global $_PHPLIB;
include($_PHPLIB
["libdir"] . "twophase_perminvalid.ihtml");
}
}
twophase_loginform.ihtml :
<script language="JavaScript">
<!--
function check_email(emailStr)
{
var supported = 0;
if (window.RegExp)
{
var tempStr = "a";
var tempReg = new RegExp(tempStr);
if (tempReg.test(tempStr)) supported =
1;
}
if (!supported)
{
var newstr = "";
var at = false;
var dot = false;
if (emailStr.indexOf("@") != -1) {
at = true;
} else if (emailStr.indexOf(".") != -1) {
dot = true;
}
for (var i = 0; i < emailStr.length; i++) {
ch = emailStr.substring(i, i +
1)
if ((ch >= "A" && ch <= "Z")
|| (ch >= "a" && ch <= "z")
|| (ch == "@")
|| (ch == ".") || (ch == "_")
|| (ch == "-")
|| (ch >= "0" && ch <= "9")) {
newstr += ch;
if (ch == "@")
{
at=true;
}
if (ch == ".")
{
dot=true;
}
}
}
if ((at == true) && (dot == true)) {
return true;
}
else {
alert ("<? echo $msg_59 ?>");
return false;
}
}
else
{
var emailPat=new RegExp("^(.+)@(.+)$");
var specialChars="\\(\\)
<>@,;:\\\\\\\&quot;\\.\\[\\]";
var validChars="\[^\\s" + specialChars
+ "\]";
var quotedUser="(\&quot;[^\&quot;]*\&quot;)";
var ipDomainPat=new RegExp("^([0-9]
{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$");
var atom=validChars + '+';
var word="(" + atom + "|" + quotedUser
+ ")";
var userPat=new RegExp("^" + word
+ "(\\." + word + ")*$");
var domainPat=new RegExp("^" + atom
+ "(\\." + atom +")*$");
var matchArray=emailStr.match
(emailPat);
if (matchArray==null)
{
alert("<? echo $msg_59 ?>");
return false;
}
var user=matchArray[1];
var domain=matchArray[2];
if (user.match(userPat)==null)
{
alert("<? echo $msg_59 ?>");
return false;
}
var IPArray=domain.match(ipDomainPat);
if (IPArray!=null)
{
for (var i=1;i<=4;i++)
{
if (IPArray[i]>255)
{
alert("<? echo
$msg_59 ?>");
return false;
}
}
return true;
}
var domainArray=domain.match
(domainPat);
if (domainArray==null)
{
alert("<? echo $msg_59 ?>");
return false;
}
var atomPat=new RegExp(atom,"g");
var domArr=domain.match(atomPat);
var len=domArr.length;
if (domArr[domArr.length-1].length<2
|| domArr[domArr.length-1].length>3)
{
alert("<? echo $msg_59 ?>");
return false;
}
if (len<2)
{
var errStr="<? echo $msg_59 ?
>";
alert(errStr);
return false;
}
return true;
}
}
var flag = true;
function field_clear(my_obj)
{
if(flag)
my_obj.value = '';
flag = false;
}
function check_form(my_obj)
{
if(my_obj.password.value.length > 5)
{
if(check_email(my_obj.username.value))
{
doChallengeResponse();
return true;
}
else
return false;
}
else
{
alert("<? echo $msg_44?>");
return false;
}
}
//-->
</script>
<p>
<? if ( isset
($username) ): ?>
<!-- failed login
code -->
Either :<br>
<ul>
<li>You have not yet registered : then <a
href="user_insert.php">Try it</a>
<li>or your email or password are invalid
<li><a href="password_forget.php?email=<? echo
urlencode($this->auth["uname"]) ?>">or you have lost
your password</a></font>";
</ul>
</font>
</td>
</tr>
</table>
<? endif ?>
<form name="login"
action="<?php print $this->url() ?>" method="post"
onSubmit="return check_form(this);">
<tr>
<td colspan=2>
<table
border="0" cellspacing="0" cellpadding="2">
<tr>
<td valign="top">
<table border="0" cellspacing="0"
cellpadding="2">
<tr>
<td>Email&nbsp;:&nbsp;</b></font></td>
<? if($twophase_remember
== "yes") {
if(trim($this->auth
["uname"]) != "") { ?>
<td><input
type="text" name="username" size="25" maxlength=255
value="<? echo $this->auth["uname"] ?>"></td>
<? } else { ?>
<td><input
type="text" name="username" size="25" maxlength=255
value="<? echo $twophase_login ?>"></td>
<? } ?>
<? } else { ?>
<td><input type="text"
name="username" size="25" maxlength=255 value="<?
print ((trim($this->auth["uname"]) != "") ? $this->auth
["uname"] : "your email") ?>" onfocus="field_clear
(this);"></td>
<? } ?>
<td></td>
</tr>
<tr>
<td>Password&nbsp;:&nbsp;</b></font></td>
<td><input type="password"
name="password" size="25" value="" maxlength=32></td>
<td></td>
</tr>
<tr>
<td colspan="2">
<? if
($twophase_remember == "yes") { ?>
Remember my
email&nbsp;:&nbsp;<input type="radio" name="remember"
value="yes" checked>yes&nbsp;&nbsp;&nbsp;<input
type="radio" name="remember" value="no">no
<? } else { ?>
<? echo
Remember my email&nbsp;:&nbsp;<input type="radio"
name="remember"
value="yes">yes&nbsp;&nbsp;&nbsp;<input type="radio"
name="remember" value="non" checked>no
<? } ?>
</td>
<td><input type="submit"
value=" OK "></td>
</tr>
</table>
<p>
<p>Do you have
forgotten your password ? <a
href="password_forgotten.php">Click here</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
<p>
</td>
</tr>
<input type="hidden"
name="challenge" value="<?php print $challenge ?>">
<input type="hidden"
name="response" value="">
</form>
</table>
page_close();
?>
and in
twophase_perminvalid() :
<?
header("Location: password_update.php");
?>
Then in all the scripts that need "true" authenticated
user just put : $perm->check("user"); just after the
page_open()...
I've cut'n paste only the "interesting" part of my
scripts, so, if you have trouble to use it send me
email...