Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions admin/addUserForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
<br>
<div class="checkbox text-center">
<label><input type="checkbox" name="isAdmin" value="1">Give admin rights</label>
</div>
<div class="checkbox text-center">
<label><input type="checkbox" name="passthrough" value="1">Give passthrough ip loggin</label>
</div>
<div class="text-center"><button id="submit" type="submit" name="action" value="addUser" class="btn btn-sm btn-primary">OK <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span></button></div>
</form>
Expand Down
8 changes: 5 additions & 3 deletions admin/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@
$gauth = new GoogleAuthenticator();

isset($_POST['isAdmin']) ? $isAdmin = 1 : $isAdmin = 0;

isset($_POST['passthrough']) ? $passthrough = 1 : $passthrough = 0;
// Generate a random secret
$secret = $gauth->createSecret();

// Add user to the database
if ($dbManager->addUser($userName,$_POST["password"],$secret,$isAdmin)) {
if ($dbManager->addUser($userName,$_POST["password"],$secret,$isAdmin,$passthrough)) {
// Create the QRCode as PNG image
$randomString = bin2hex(openssl_random_pseudo_bytes (15));
$qrcodeimg = QRCODE_TEMP_DIR.$randomString.".png";
Expand Down Expand Up @@ -188,7 +188,7 @@
<body>
<div class="container" style="margin-top: 10px">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div class="">
<div class="panel panel-default">
<div class="panel-heading" style="text-align: center">
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
Expand All @@ -206,6 +206,8 @@
<tr>
<th class="text-center">USERNAME</th>
<th class="text-center">ADMIN</th>
<th class="text-center">PASSTHROUGH IP</th>
<th class="text-center">IP</th>
<th class="text-center">ACTIONS</th>
</tr>
</thead>
Expand Down
6 changes: 4 additions & 2 deletions admin/showUserList.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
else {
//--------------------------------------------------------
// Create the list of users as a table content
foreach ($userList as $userName => $isAdmin) {
foreach ($userList as $userName => $params) {
echo "<tr>";
echo "<td style=\"vertical-align: middle;\">".$userName."</td>";
echo "<td style=\"vertical-align: middle;\" class=\"text-center\">".(($isAdmin === 0)? "No" : "Yes")."</td>";
echo "<td style=\"vertical-align: middle;\" class=\"text-center\">".(($params['ISADMIN'] === 0)? "No" : "Yes")."</td>";
echo "<td style=\"vertical-align: middle;\" class=\"text-center\">".(($params['PASSTHROUGH'] === 0)? "No" : "Yes")."</td>";
echo "<td style=\"vertical-align: middle;\" class=\"text-center\">".$params['IP']."</td>";
echo "<td class=\"text-center\">";
echo "<form id=\"userAction\" action=\"admin.php\" method=\"post\">";
echo "<input type=\"hidden\" name=\"csrf_token\" value=\"".$token."\">";
Expand Down
2 changes: 2 additions & 0 deletions install/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
USERNAME VARCHAR(255) UNIQUE NOT NULL,
PASSWORDHASH VARCHAR(255) NOT NULL,
GAUTHSECRET VARCHAR(255) NOT NULL,
PASSTHROUGH TINYINT DEFAULT 0,
IP VARCHAR(255),
ISADMIN TINYINT NOT NULL);
EOF;

Expand Down
45 changes: 40 additions & 5 deletions lib/dbManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ function __construct ($dbFilename, $flags = SQLITE3_OPEN_READWRITE) {
// @param gauthSecret: the user's Gauth secret to add
// @param isAdmin: optionnal, specifies if the user is an admin. Defaults to 0.
// @return bool : TRUE if no error, FALSE otherwise
public function addUser ($username, $password, $gauthSecret, $isAdmin = 0) {
public function addUser ($username, $password, $gauthSecret, $isAdmin = 0, $passthrough = 0) {

// Prepare variables before the query
$passwordHash = hash('sha256',$password);

// Prepare SQL query
$sqlQuery = "INSERT INTO USERS (USERNAME ,PASSWORDHASH ,GAUTHSECRET ,ISADMIN) ";
$sqlQuery .= "VALUES (:username, :passwordhash, :secret, :isadmin);";
$sqlQuery = "INSERT INTO USERS (USERNAME ,PASSWORDHASH ,GAUTHSECRET ,ISADMIN, PASSTHROUGH) ";
$sqlQuery .= "VALUES (:username, :passwordhash, :secret, :isadmin, :passthrough);";

$stmt = $this->prepare($sqlQuery);

Expand All @@ -42,6 +42,7 @@ public function addUser ($username, $password, $gauthSecret, $isAdmin = 0) {
$stmt->bindValue(':passwordhash', $passwordHash, SQLITE3_TEXT);
$stmt->bindValue(':secret', $gauthSecret, SQLITE3_TEXT);
$stmt->bindValue(':isadmin', $isAdmin, SQLITE3_INTEGER);
$stmt->bindValue(':passthrough', $passthrough, SQLITE3_INTEGER);

if ($stmt->execute()) {
return true;
Expand Down Expand Up @@ -98,7 +99,26 @@ public function getPasswordHash ($username) {

return $this->getUserData('PASSWORDHASH', $username);
}
//--------------------------------------------------------
// Get the list of IP in the database
// @return array : an array of IP
public function getIpList () {

// Prepare SQL query
$sqlQuery = "SELECT DISTINCT IP from USERS where PASSTHROUGH = 1 AND IP != '' AND IP IS NOT NULL";

// Perform SQL query
if(!($ret = $this->query($sqlQuery))) {
return false;
}
else {
$result = array();
while ($row = $ret->fetchArray(SQLITE3_ASSOC)) {
$result[$row["IP"]] = true;
}
return $result;
}
}
//--------------------------------------------------------
// Get a specific column of a given user
// @param column : The column
Expand Down Expand Up @@ -169,7 +189,7 @@ public function getAdminStatus ($username) {
public function getUserList () {

// Prepare SQL query
$sqlQuery = "SELECT USERNAME,ISADMIN from USERS;";
$sqlQuery = "SELECT USERNAME,ISADMIN,PASSTHROUGH,IP from USERS;";

// Perform SQL query
if(!($ret = $this->query($sqlQuery))) {
Expand All @@ -178,7 +198,11 @@ public function getUserList () {
else {
$result = array();
while ($row = $ret->fetchArray(SQLITE3_ASSOC)) {
$result[$row["USERNAME"]] = $row["ISADMIN"];
foreach($row as $key => $value) {
if ($key !== 'USERNAME') {
$result[$row["USERNAME"]][$key] = $value;
}
}
}
return $result;
}
Expand Down Expand Up @@ -218,6 +242,7 @@ protected function updateUserData ($column, $value, $username) {
case 'PASSWORDHASH':
case 'GAUTHSECRET':
case 'ISADMIN':
case 'IP':
break;

default:
Expand Down Expand Up @@ -248,6 +273,16 @@ protected function updateUserData ($column, $value, $username) {
public function updateGauthSecret ($username, $gauthSecret) {

return $this->updateUserData('GAUTHSECRET', $gauthSecret, $username);
}

//--------------------------------------------------------
// Updates the IP of a user
// @param username : the username
// @param IP; the IP of the user
// @return bool : TRUE if the IP was updated, FALSE otherwise
public function updateIpAddress ($username, $IP) {

return $this->updateUserData('IP', $IP, $username);
}

//--------------------------------------------------------
Expand Down
9 changes: 6 additions & 3 deletions login/login.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@
}
}

$dbManager->close();

//--------------------------------------------------
// Login successful - let's proceed
if (!isset($error)) {
// Save the IP address
$dbManager->updateIpAddress($username, $_SERVER['REMOTE_ADDR']);
//--------------------------------------------------
// Creating a session to persist the authentication
session_name(SESSION_NAME);
Expand Down Expand Up @@ -100,7 +100,10 @@
else {
http_response_code(403);
require_once("loginForm.php");
}
}

$dbManager->close();

} catch (Exception $e) {
$error = "[ERROR] Cannot open user database file";
require_once("loginForm.php");
Expand Down
11 changes: 10 additions & 1 deletion nginx/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,19 @@
// Restore an existing session
session_name(SESSION_NAME);
session_start();
require_once(DBMANAGER_LIB);
$dbManager = new DBManager(USER_SQL_DATABASE_FILE);
$ListOfIpAddress = $dbManager->getIpList();
$dbManager->close();

//====================================================
// Check if we need passthrue ip address
if (isset($ListOfIpAddress[$_SERVER [ "REMOTE_ADDR" ]]) === true) {
http_response_code(200);
}
//====================================================
// Check if the authentication has been completed
if (isset($_SESSION["authenticated"]) && $_SESSION["authenticated"] === true) {
elseif (isset($_SESSION["authenticated"]) && $_SESSION["authenticated"] === true) {
http_response_code(200);
}
else {
Expand Down
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ Adding a user :

![addUser page](http://i.imgur.com/TwzUSvl.jpg)

New option check box passthrough IP

How does it work ?
-----------------

Expand Down Expand Up @@ -130,6 +132,7 @@ TwoFactorAuth provides such a script: **/twofactorauth/nginx/auth.php**.

You'll have to edit your Nginx configuration file. Assuming the TwoFactorAuth application was deployed in a location named /twofactorauth/ on your webserver, add the following line under the "server" directive:

If on creation user was added option passthrough IP, nginx will allowed to pass 2 factor authentication for IP address that was used to login. After pass 2 factor authentication, it will allow to pass through non browser based applications, such as git, that can't login with session based on IP source address

auth_request /twofactorauth/nginx/auth.php;

Expand Down