diff --git a/admin/addUserForm.php b/admin/addUserForm.php index 75776a7..7379c82 100644 --- a/admin/addUserForm.php +++ b/admin/addUserForm.php @@ -49,6 +49,9 @@
+
+
+
diff --git a/admin/admin.php b/admin/admin.php index fd7dd90..fbe929a 100644 --- a/admin/admin.php +++ b/admin/admin.php @@ -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"; @@ -188,7 +188,7 @@
-
+
@@ -206,6 +206,8 @@ USERNAME ADMIN + PASSTHROUGH IP + IP ACTIONS diff --git a/admin/showUserList.php b/admin/showUserList.php index bfcff2e..ad1049d 100644 --- a/admin/showUserList.php +++ b/admin/showUserList.php @@ -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 ""; echo "".$userName.""; - echo "".(($isAdmin === 0)? "No" : "Yes").""; + echo "".(($params['ISADMIN'] === 0)? "No" : "Yes").""; + echo "".(($params['PASSTHROUGH'] === 0)? "No" : "Yes").""; + echo "".$params['IP'].""; echo ""; echo "
"; echo ""; diff --git a/install/install.php b/install/install.php index 6b95082..46008e4 100644 --- a/install/install.php +++ b/install/install.php @@ -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; diff --git a/lib/dbManager.php b/lib/dbManager.php index df3c479..4da8151 100644 --- a/lib/dbManager.php +++ b/lib/dbManager.php @@ -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); @@ -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; @@ -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 @@ -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))) { @@ -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; } @@ -218,6 +242,7 @@ protected function updateUserData ($column, $value, $username) { case 'PASSWORDHASH': case 'GAUTHSECRET': case 'ISADMIN': + case 'IP': break; default: @@ -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); } //-------------------------------------------------------- diff --git a/login/login.php b/login/login.php index 5c0b439..0b7f88c 100644 --- a/login/login.php +++ b/login/login.php @@ -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); @@ -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"); diff --git a/nginx/auth.php b/nginx/auth.php index 58efc06..964d7d4 100644 --- a/nginx/auth.php +++ b/nginx/auth.php @@ -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 { diff --git a/readme.md b/readme.md index 13132f3..bba0d1a 100644 --- a/readme.md +++ b/readme.md @@ -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 ? ----------------- @@ -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;