diff options
author | Christian Stocker <me@chregu.tv> | 2011-02-21 22:06:55 +0100 |
---|---|---|
committer | Christian Stocker <me@chregu.tv> | 2011-02-21 22:06:55 +0100 |
commit | deb9eb105fbd7705dee5d24826314c944a406a5e (patch) | |
tree | b7203b0880bc7362c3a573bebb1e3d4c058d0030 | |
parent | b17118215119b748a19c3b4066acf23a57527445 (diff) | |
download | GoogleAuthenticator.php-deb9eb105fbd7705dee5d24826314c944a406a5e.zip GoogleAuthenticator.php-deb9eb105fbd7705dee5d24826314c944a406a5e.tar.gz GoogleAuthenticator.php-deb9eb105fbd7705dee5d24826314c944a406a5e.tar.bz2 |
Added real world example (not security tested yet :))
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | tmpl/ask-for-otp.php | 11 | ||||
-rw-r--r-- | tmpl/loggedin.php | 19 | ||||
-rw-r--r-- | tmpl/login-error.php | 6 | ||||
-rw-r--r-- | tmpl/login.php | 8 | ||||
-rw-r--r-- | tmpl/show-qr.php | 12 | ||||
-rw-r--r-- | users.dat | 1 | ||||
-rw-r--r-- | web/Users.php | 134 | ||||
-rw-r--r-- | web/index.php | 86 |
9 files changed, 282 insertions, 1 deletions
@@ -7,4 +7,8 @@ PHP app (Of course, you can also create them with this). There are many real world applications for that, but noone implemented it yet. -See example.php for how to use it.
\ No newline at end of file +See example.php for how to use it. + +There's a little web app showing how it works in web/, please make users.dat +writeable for the webserver, doesn't really work otherwise (it can't save the +secret). Try to login with chregu/foobar.
\ No newline at end of file diff --git a/tmpl/ask-for-otp.php b/tmpl/ask-for-otp.php new file mode 100644 index 0000000..4d69c77 --- /dev/null +++ b/tmpl/ask-for-otp.php @@ -0,0 +1,11 @@ + +<h1>please otp</h1> +<p> +<form method="post" action="./"> +otp: <input name="otp" +value="<?php +$g = new GoogleAuthenticator(); + +echo $g->getCode($user->getSecret());?>"/><br/> +<input type="submit"/> +</form>
\ No newline at end of file diff --git a/tmpl/loggedin.php b/tmpl/loggedin.php new file mode 100644 index 0000000..661b546 --- /dev/null +++ b/tmpl/loggedin.php @@ -0,0 +1,19 @@ + +<p> +Hello <?php echo $user->getUsername(); ?> +</p> +<?php +if (!isset($_GET['showqr'])) { +?> + +<p> +<a href="?showqr=1">Show QR Code</a> +</p> + +<?php +} +?> + +<p> +<a href="?logout=1">Logout</a> +</p>
\ No newline at end of file diff --git a/tmpl/login-error.php b/tmpl/login-error.php new file mode 100644 index 0000000..a8fedfd --- /dev/null +++ b/tmpl/login-error.php @@ -0,0 +1,6 @@ +<p> +Wrong username or password or token. +</p> +<p> +<a href="./">try again</a> +</p>
\ No newline at end of file diff --git a/tmpl/login.php b/tmpl/login.php new file mode 100644 index 0000000..bbce13b --- /dev/null +++ b/tmpl/login.php @@ -0,0 +1,8 @@ + +<h1>please login</h1> +<p> +<form method="post" action="./"> +username: <input name="username"/><br/> +password: <input name="password" type="password"/><br/> +<input type="submit"/> +</form>
\ No newline at end of file diff --git a/tmpl/show-qr.php b/tmpl/show-qr.php new file mode 100644 index 0000000..bdb00a1 --- /dev/null +++ b/tmpl/show-qr.php @@ -0,0 +1,12 @@ +<h1>Please scan this </h1> + +<p> with <a href="http://www.google.com/support/a/bin/answer.py?hl=en&answer=1037451">the Google Authenticator App</a></p> + +<p> +<?php + $g = new GoogleAuthenticator(); + $link = $g->getUrl($user->getUsername(),$_SERVER['HTTP_HOST'],$secret); +?> + +<a href="<?php echo $link;?>"><img style="border: 0; padding:10px" src="<?php echo $link;?>"/></a> +</p>
\ No newline at end of file diff --git a/users.dat b/users.dat new file mode 100644 index 0000000..fdcc130 --- /dev/null +++ b/users.dat @@ -0,0 +1 @@ +{"chregu":{"password":"foobar"}}
\ No newline at end of file diff --git a/web/Users.php b/web/Users.php new file mode 100644 index 0000000..c794537 --- /dev/null +++ b/web/Users.php @@ -0,0 +1,134 @@ +<?php + +class Users { + + + function __construct($file = "../users.dat") { + $this->userFile = $file; + + $this->users = json_decode(file_get_contents($file),true); + } + function hasSession() { + session_start(); + if (isset($_SESSION['username'])) { + return $_SESSION['username']; + } + return false; + } + + + function storeData(User $user) { + $this->users[$user->getUsername()] = $user->getData(); + file_put_contents($this->userFile,json_encode($this->users)); + } + + function loadUser($name) { + if (isset($this->users[$name])) { + + return new User($name,$this->users[$name]); + } else { + return false; + } + } + + + +} + +class User { + + function __construct($user,$data) { + $this->data = $data; + $this->user = $user; + } + + function auth($pass) { + if ($this->data['password'] === $pass) { + return true; + } + + return false; + + } + + function startSession() { + + $_SESSION['username'] = $this->user; + } + + function doLogin() { + session_regenerate_id(); + $_SESSION['loggedin'] = true; + } + + function doOTP() { + $_SESSION['OTP'] = true; + } + + function isOTP() { + if (isset($_SESSION['OTP']) && $_SESSION['OTP'] == true) { + + return true; + } + return false; + + } + function isLoggedIn() { + if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true) { + + return $_SESSION['username']; + } + return false; + + } + + + function getUsername() { + return $this->user; + } + + function getSecret() { + if (isset($this->data['secret'])) { + return $this->data['secret']; + } + return false; + } + + function generateSecret() { + $g = new GoogleAuthenticator(); + $secret = $g->generateSecret(); + $this->data['secret'] = $secret; + return $secret; + + } + + function getData() { + return $this->data; + } + + function setOTPCookie() { + $time = floor(time() / (3600 * 24) ); // get day number + $cookie = $time.":".sha1($this->getUsername().":".$time.":".$this->getSecret()); + setcookie ( "otp", $cookie, time() + (30 * 24 * 3600), null,null,null,true ); + } + + function hasValidOTPCookie() { + // 0 = tomorrow it is invalid + $daysUntilInvalid = 0; + $time = (string) floor((time() / (3600 * 24))) ; // get day number + if (isset($_COOKIE['otp'])) { + list( $otpday,$hash) = explode(":",$_COOKIE['otp']); + + if ( $otpday >= $time - $daysUntilInvalid && $hash == sha1($this->getUsername().":".$otpday .":" . $this->getSecret()) + ) { + return true; + } + + + } + return false; + + } + +} +?> diff --git a/web/index.php b/web/index.php new file mode 100644 index 0000000..1a4c9e7 --- /dev/null +++ b/web/index.php @@ -0,0 +1,86 @@ +<!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"> +<head> +<meta name="generator" content= +"HTML Tidy for Mac OS X (vers 31 October 2006 - Apple Inc. build 15.3.6), see www.w3.org" /> +<title></title> +</head> +<body> +<?php +ini_set("session.cookie_httponly", 1); +include_once("../lib/GoogleAuthenticator.php"); +include_once("Users.php"); + + + +$users = new Users(); +if ($username = $users->hasSession()) { + $user = $users->loadUser($username); + if (isset($_GET['logout'])) { + session_destroy(); + header("Location: ./"); + } + if ($user->isLoggedIn()) { + include("../tmpl/loggedin.php"); + if (isset($_GET['showqr'])) { + $secret = $user->getSecret(); + include("../tmpl/show-qr.php"); + } + } else if ($user->isOTP() && isset($_POST['otp'])) { + $g = new GoogleAuthenticator(); + if ($g->checkCode($user->getSecret(),$_POST['otp'])) { + $user->doLogin(); + $user->setOTPCookie(); + include("../tmpl/loggedin.php"); + } else { + session_destroy(); + include("../tmpl/login-error.php"); + } + + } else { + session_destroy(); + } + + + + die(); +} else if (isset($_POST['username'])) { + $user = $users->loadUser($_POST['username']); + + if ($user) { + if ($user->auth($_POST['password'])) { + $user->startSession(); + if ($user->hasValidOTPCookie()) { + include("../tmpl/loggedin.php"); + $user->doLogin(); + + } else if (!$user->getSecret()) { + include("../tmpl/loggedin.php"); + + $secret = $user->generateSecret(); + $users->storeData($user); + $user->doLogin(); + include("../tmpl/show-qr.php"); + + } else { + $user->doOTP(); + include("../tmpl/ask-for-otp.php"); + } + + + die(); + } + } + session_destroy(); + + include("../tmpl/login-error.php"); + die(); +} + +include("../tmpl/login.php"); + + +?> +</body> +</html>
\ No newline at end of file |