Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added real world example (not security tested yet :))

  • Loading branch information...
commit deb9eb105fbd7705dee5d24826314c944a406a5e 1 parent b171182
@chregu authored
View
6 README
@@ -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.
+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.
View
11 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>
View
19 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>
View
6 tmpl/login-error.php
@@ -0,0 +1,6 @@
+<p>
+Wrong username or password or token.
+</p>
+<p>
+<a href="./">try again</a>
+</p>
View
8 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>
View
12 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>
View
1  users.dat
@@ -0,0 +1 @@
+{"chregu":{"password":"foobar"}}
View
134 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;
+
+ }
+
+}
+?>
View
86 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>
Please sign in to comment.
Something went wrong with that request. Please try again.