Merge pull request #450 from wrongecho/misc

Assorted changes/commits
This commit is contained in:
Johnny
2022-04-25 11:29:39 -04:00
committed by GitHub
15 changed files with 1189 additions and 1123 deletions
+11
View File
@@ -9,6 +9,7 @@
include("config.php"); include("config.php");
include("functions.php"); include("functions.php");
include("check_login.php"); include("check_login.php");
require_once("rfc6238.php");
/* /*
* Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key) * Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key)
@@ -305,3 +306,13 @@ if(isset($_GET['scheduled_ticket_get_json_details'])){
echo json_encode($response); echo json_encode($response);
} }
/*
* Dynamic TOTP for client login page
* When provided with a TOTP secret, returns a 6-digit code
*/
if(isset($_GET['get_totp_token'])){
$otp = TokenAuth6238::getTokenCode($_GET['totp_secret']);
echo json_encode($otp);
}
+3 -13
View File
@@ -43,7 +43,7 @@
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div> </div>
<input type="text" class="form-control" name="name" placeholder="Name the asset" value="<?php echo $asset_name; ?>" <?php if(!empty($asset_meshcentral_id)){echo "disabled";} ?> required> <input type="text" class="form-control" name="name" placeholder="Name the asset" value="<?php echo $asset_name; ?>" required>
</div> </div>
</div> </div>
@@ -101,7 +101,7 @@
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fab fa-fw fa-windows"></i></span> <span class="input-group-text"><i class="fab fa-fw fa-windows"></i></span>
</div> </div>
<input type="text" class="form-control" name="os" placeholder="ex Windows 10 Pro" <?php if(!empty($asset_meshcentral_id)){echo "disabled";} ?> value="<?php echo $asset_os; ?>"> <input type="text" class="form-control" name="os" placeholder="ex Windows 10 Pro" value="<?php echo $asset_os; ?>">
</div> </div>
</div> </div>
<?php } ?> <?php } ?>
@@ -206,16 +206,6 @@
</div> </div>
</div> </div>
<div class="form-group">
<label>MeshCentral Node ID</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-sync"></i></span>
</div>
<input type="text" class="form-control" name="mesh_id" value="<?php echo $asset_meshcentral_id; ?>" placeholder="MeshCentral ID">
</div>
</div>
</div> </div>
<div class="tab-pane fade" id="pillsPurchaseCopy<?php echo $asset_id; ?>"> <div class="tab-pane fade" id="pillsPurchaseCopy<?php echo $asset_id; ?>">
@@ -305,7 +295,7 @@
<div class="tab-pane fade" id="pillsNotesCopy<?php echo $asset_id; ?>"> <div class="tab-pane fade" id="pillsNotesCopy<?php echo $asset_id; ?>">
<div class="form-group"> <div class="form-group">
<textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes" <?php if(!empty($asset_meshcentral_id)){echo "disabled";} ?>><?php echo $asset_notes; ?></textarea> <textarea class="form-control" rows="8" placeholder="Enter some notes" name="notes"><?php echo $asset_notes; ?></textarea>
</div> </div>
</div> </div>
+4 -1
View File
@@ -55,10 +55,13 @@
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div> </div>
<input type="password" class="form-control" data-toggle="password" name="password" placeholder="Password" required autocomplete="new-password"> <input type="password" class="form-control" data-toggle="password" id="password" name="password" placeholder="Password" required autocomplete="new-password">
<div class="input-group-append"> <div class="input-group-append">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div> </div>
<div class="input-group-append">
<span class="btn btn-default"><i class="fa fa-fw fa-question" onclick="generatePassword()"></i></span>
</div>
</div> </div>
</div> </div>
+25 -6
View File
@@ -1,7 +1,5 @@
<?php <?php
require_once("rfc6238.php");
if(!empty($_GET['sb'])){ if(!empty($_GET['sb'])){
$sb = mysqli_real_escape_string($mysqli,$_GET['sb']); $sb = mysqli_real_escape_string($mysqli,$_GET['sb']);
}else{ }else{
@@ -20,7 +18,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-key"></i> Logins</h3> <h3 class="card-title mt-2"><i class="fa fa-fw fa-key"></i> Logins</h3>
<div class="card-tools"> <div class="card-tools">
@@ -84,11 +82,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
} }
$login_password = htmlentities(decryptLoginEntry($row['login_password'])); $login_password = htmlentities(decryptLoginEntry($row['login_password']));
$login_otp_secret = $row['login_otp_secret']; $login_otp_secret = $row['login_otp_secret'];
$login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"';
if(empty($login_otp_secret)){ if(empty($login_otp_secret)){
$otp_display = "-"; $otp_display = "-";
}else{ }else{
$otp = TokenAuth6238::getTokenCode($login_otp_secret,$rangein30s = 3); $otp_display = "<span onmouseenter='showOTP($login_id_with_secret)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>";
$otp_display = "<i class='far fa-clock text-secondary'></i> $otp<button class='btn btn-sm clipboardjs' data-clipboard-text='$otp'><i class='far fa-copy text-secondary'></i></button>";
} }
$login_note = $row['login_note']; $login_note = $row['login_note'];
$login_contact_id = $row['login_contact_id']; $login_contact_id = $row['login_contact_id'];
@@ -139,7 +137,28 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
</div> </div>
<?php include("pagination.php"); ?> <?php include("pagination.php"); ?>
</div> </div>
</div> </div>
<script>
function showOTP(id, secret){
//Send a GET request to ajax.php as ajax.php?get_totp_token=true&totp_secret=SECRET
jQuery.get(
"ajax.php",
{get_totp_token: 'true', totp_secret: secret},
function(data){
//If we get a response from post.php, parse it as JSON
const token = JSON.parse(data);
document.getElementById("otp_" + id).innerText = token
}
);
}
function generatePassword(){
document.getElementById("password").value = "<?php echo keygen() ?>"
}
</script>
<?php <?php
include("client_login_add_modal.php"); include("client_login_add_modal.php");
+4 -2
View File
@@ -15,6 +15,7 @@ $sql_logins = mysqli_query($mysqli,"SELECT * FROM logins WHERE login_client_id =
// Get Domains Expiring // Get Domains Expiring
$sql_domains_expiring = mysqli_query($mysqli,"SELECT * FROM domains $sql_domains_expiring = mysqli_query($mysqli,"SELECT * FROM domains
WHERE domain_client_id = $client_id WHERE domain_client_id = $client_id
AND domain_expire != '0000-00-00'
AND domain_expire < CURRENT_DATE + INTERVAL 30 DAY AND domain_expire < CURRENT_DATE + INTERVAL 30 DAY
AND company_id = $session_company_id ORDER BY domain_expire DESC" AND company_id = $session_company_id ORDER BY domain_expire DESC"
); );
@@ -22,6 +23,7 @@ $sql_domains_expiring = mysqli_query($mysqli,"SELECT * FROM domains
// Get Asset Warranties Expiring // Get Asset Warranties Expiring
$sql_asset_warranties_expiring = mysqli_query($mysqli,"SELECT * FROM assets $sql_asset_warranties_expiring = mysqli_query($mysqli,"SELECT * FROM assets
WHERE asset_client_id = $client_id WHERE asset_client_id = $client_id
AND asset_warranty_expire != '0000-00-00'
AND asset_warranty_expire < CURRENT_DATE + INTERVAL 90 DAY AND asset_warranty_expire < CURRENT_DATE + INTERVAL 90 DAY
AND company_id = $session_company_id ORDER BY asset_warranty_expire DESC" AND company_id = $session_company_id ORDER BY asset_warranty_expire DESC"
); );
@@ -29,8 +31,8 @@ $sql_asset_warranties_expiring = mysqli_query($mysqli,"SELECT * FROM assets
// Get Stale Tickets // Get Stale Tickets
$sql_tickets_stale = mysqli_query($mysqli,"SELECT * FROM tickets $sql_tickets_stale = mysqli_query($mysqli,"SELECT * FROM tickets
WHERE ticket_client_id = $client_id WHERE ticket_client_id = $client_id
AND ticket_created_at < CURRENT_DATE + INTERVAL 14 DAY AND ticket_created_at < CURRENT_DATE - INTERVAL 14 DAY
AND ticket_status = 'Open' AND ticket_status != 'Closed'
AND company_id = $session_company_id ORDER BY ticket_created_at DESC" AND company_id = $session_company_id ORDER BY ticket_created_at DESC"
); );
+20 -12
View File
@@ -88,17 +88,6 @@
</div> </div>
</div> </div>
<!-- TODO: We need a way of adding multiple (optional) URLs? Ideas? -->
<!-- <div class="form-group">
<label>URL</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
</div>
<input type="text" class="form-control" name="url" placeholder="URL" autofocus>
</div>
</div> -->
<div class="form-group"> <div class="form-group">
<label>Notes</label> <label>Notes</label>
<textarea class="form-control" rows="3" placeholder="Enter some notes" name="note"></textarea> <textarea class="form-control" rows="3" placeholder="Enter some notes" name="note"></textarea>
@@ -160,6 +149,10 @@
<div class="tab-pane fade" id="pills-assets"> <div class="tab-pane fade" id="pills-assets">
<div class="row">
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="assets">Assets</label> <label for="assets">Assets</label>
<p></p> <p></p>
@@ -175,10 +168,12 @@
?> ?>
</select> </select>
</div> </div>
</div>
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="logins">Logins</label> <label for="logins">Logins</label>
<p class="text-muted">Logins associated to related assets will show as related automatically</p> <p></p>
<select class="form-select" id="logins" name="logins[]" multiple="multiple"> <select class="form-select" id="logins" name="logins[]" multiple="multiple">
<option value="">- Logins -</option> <option value="">- Logins -</option>
<?php <?php
@@ -191,7 +186,14 @@
?> ?>
</select> </select>
</div> </div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="domains">Domains</label> <label for="domains">Domains</label>
<p></p> <p></p>
@@ -207,7 +209,9 @@
?> ?>
</select> </select>
</div> </div>
</div>
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="certificates">Certificates</label> <label for="certificates">Certificates</label>
<p></p> <p></p>
@@ -227,6 +231,10 @@
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+18 -1
View File
@@ -179,6 +179,10 @@
<div class="tab-pane fade" id="pills-assets<?php echo $service_id ?>"> <div class="tab-pane fade" id="pills-assets<?php echo $service_id ?>">
<div class="row">
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="assets">Assets</label> <label for="assets">Assets</label>
<p></p> <p></p>
@@ -202,10 +206,12 @@
?> ?>
</select> </select>
</div> </div>
</div>
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="logins">Logins</label> <label for="logins">Logins</label>
<p class="text-muted">Logins associated to related assets will show as related automatically</p> <p></p>
<select class="form-select" id="logins" name="logins[]" multiple="multiple"> <select class="form-select" id="logins" name="logins[]" multiple="multiple">
<option value="">- Logins -</option> <option value="">- Logins -</option>
<?php <?php
@@ -225,9 +231,15 @@
} }
?> ?>
</select> </select>
</div>
</div>
</div> </div>
<div class="row">
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="domains">Domains</label> <label for="domains">Domains</label>
<p></p> <p></p>
@@ -251,7 +263,9 @@
?> ?>
</select> </select>
</div> </div>
</div>
<div class="col">
<div class="form-group"> <div class="form-group">
<label for="certificates">Certificates</label> <label for="certificates">Certificates</label>
<p></p> <p></p>
@@ -275,6 +289,9 @@
?> ?>
</select> </select>
</div> </div>
</div>
</div>
</div> </div>
+20 -3
View File
@@ -1,14 +1,28 @@
<?php <?php
if(!empty($_GET['sb'])){
$sb = mysqli_real_escape_string($mysqli,$_GET['sb']);
}else{
$sb = "service_name";
}
// Current tab // Current tab
$tab = htmlentities($_GET['tab']); $tab = htmlentities($_GET['tab']);
//Rebuild URL
$url_query_strings_sb = http_build_query(array_merge($_GET,array('sb' => $sb, 'o' => $o)));
// Overview SQL query // Overview SQL query
$sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS * FROM services WHERE service_client_id = '$client_id' AND (service_name LIKE '%$q%' OR service_description LIKE '%$q%')"); $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS * FROM services
WHERE service_client_id = '$client_id'
AND (service_name LIKE '%$q%' OR service_description LIKE '%$q%' OR service_category LIKE '%$q%')
ORDER BY $sb $o LIMIT $record_from, $record_to"
);
$num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()")); $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
?> ?>
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header py-2"> <div class="card-header py-2">
<h3 class="card-title mt-2"><i class="fa fa-fw fa-stream"></i> Services</h3> <h3 class="card-title mt-2"><i class="fa fa-fw fa-stream"></i> Services</h3>
<div class="card-tools"> <div class="card-tools">
@@ -155,7 +169,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
</tbody> </tbody>
</table> </table>
</div> </div>
<?php
include ('pagination.php');
?>
</div>
</div> </div>
</div>
<?php include("client_service_add_modal.php"); ?> <?php include("client_service_add_modal.php"); ?>
+2 -6
View File
@@ -333,15 +333,11 @@ function generateUserSessionKey($site_encryption_master_key){
$_SESSION['user_encryption_session_ciphertext'] = $user_encryption_session_ciphertext; $_SESSION['user_encryption_session_ciphertext'] = $user_encryption_session_ciphertext;
$_SESSION['user_encryption_session_iv'] = $user_encryption_session_iv; $_SESSION['user_encryption_session_iv'] = $user_encryption_session_iv;
//Give the user "their" key as a cookie // Give the user "their" key as a cookie
//By default, this should be HTTPS but we can change to HTTP for development via the config.php file (note that the extension won't work without HTTPS)
include('config.php'); include('config.php');
if($config_https_only){ if($config_https_only){
//setcookie("user_encryption_session_key", $user_encryption_session_key, 0, "/", "", "true", "true", ['samesite' => 'None']);
setcookie("user_encryption_session_key", "$user_encryption_session_key", ['path' => '/','secure' => true,'httponly' => true,'samesite' => 'None']); setcookie("user_encryption_session_key", "$user_encryption_session_key", ['path' => '/','secure' => true,'httponly' => true,'samesite' => 'None']);
} else{
}
else{
setcookie("user_encryption_session_key", $user_encryption_session_key, 0, "/"); setcookie("user_encryption_session_key", $user_encryption_session_key, 0, "/");
$_SESSION['alert_message'] = "Unencrypted connection flag set: Using non-secure cookies."; $_SESSION['alert_message'] = "Unencrypted connection flag set: Using non-secure cookies.";
} }
+40 -37
View File
@@ -1,11 +1,27 @@
<?php <?php
/*
* ITFlow browser extension
*
* Fills login forms, matching on the site URL:
* After installation and configuration of the extension, users can simply click the key to fill the form on the page
* If the URL of the page matches a configured login URL in ITFlow, the username and password is filled.
*
* Technical details:-
* First, review how ITFlow handles password encryption: https://itflow.org/docs.php?doc=logins
* Users must enable the extension via their profile/settings.
* An extension key is generated and stored in the users table, and provided to the user as a cookie every time they log in. Additionally, their PHP Session ID is also stored in the users table.
* The extension passes this cookie on all requests it makes (to this page). We use the cookie/key to identify/verify the user.
* We can then access the users PHP session data. This, alongside the user_encryption_session_key cookie they provide, allows login passwords to be decrypted.
*
*/
// Headers to allow extensions access (CORS) // Headers to allow extensions access (CORS)
$chrome_id = "chrome-extension://afgpakhonllnmnomchjhidealcpmnegc"; $chrome_id = "chrome-extension://afgpakhonllnmnomchjhidealcpmnegc";
$firefox_id = "moz-extension://857479e9-3992-4e99-9a5e-b514d2ad0a82"; //$firefox_id = "moz-extension://857479e9-3992-4e99-9a5e-b514d2ad0a82"; // Firefox rejected the extension. They are still using manifest v2 so will just focus on Chrome/Edge with v3 for now until Mozilla catches up
if (isset($_SERVER['HTTP_ORIGIN'])) { if (isset($_SERVER['HTTP_ORIGIN'])) {
if($_SERVER['HTTP_ORIGIN'] == $chrome_id || $_SERVER['HTTP_ORIGIN'] == $firefox_id){ if($_SERVER['HTTP_ORIGIN'] == $chrome_id){
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true'); header('Access-Control-Allow-Credentials: true');
} }
@@ -14,21 +30,24 @@ if (isset($_SERVER['HTTP_ORIGIN'])) {
include("config.php"); include("config.php");
include("functions.php"); include("functions.php");
//SESSION FINGERPRINT // IP & User Agent for logging
$ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip())); $ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip()));
$os = strip_tags(mysqli_real_escape_string($mysqli,get_os())); $user_agent = strip_tags(mysqli_real_escape_string($mysqli,$_SERVER['HTTP_USER_AGENT']));
$browser = strip_tags(mysqli_real_escape_string($mysqli,get_web_browser()));
$user_agent = "$os - $browser"; // Define wording for the user
DEFINE("WORDING_ROLECHECK_FAILED", "ITFlow - You are not permitted to use this application!");
DEFINE("WORDING_BAD_EXT_COOKIE_KEY", "ITFlow - You are not logged into ITFlow, do not have, or did not send the correct extension key cookie.");
// Check user is logged in & has extension access // Check user is logged in & has extension access
// We're not using the PHP session as we don't want to potentially expose the session cookie with SameSite None // We're not using the PHP session as we don't want to potentially expose the session cookie with SameSite None
if(!isset($_COOKIE['user_extension_key'])){ if(!isset($_COOKIE['user_extension_key'])){
$data['found'] = "FALSE"; $data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not logged into ITFlow, do not have, or did not send the correct extension key cookie."; $data['message'] = WORDING_BAD_EXT_COOKIE_KEY;
echo(json_encode($data)); echo(json_encode($data));
//Logging //Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()"); mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent'");
exit(); exit();
} }
@@ -39,11 +58,11 @@ $user_extension_key = $_COOKIE['user_extension_key'];
// Check the key isn't empty, less than 17 characters or the word "disabled". // Check the key isn't empty, less than 17 characters or the word "disabled".
if(empty($user_extension_key) || strlen($user_extension_key) < 16 || strtolower($user_extension_key) == "disabled"){ if(empty($user_extension_key) || strlen($user_extension_key) < 16 || strtolower($user_extension_key) == "disabled"){
$data['found'] = "FALSE"; $data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not logged into ITFlow, do not have, or did not send the correct extension key cookie."; $data['message'] = WORDING_BAD_EXT_COOKIE_KEY;
echo(json_encode($data)); echo(json_encode($data));
//Logging //Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()"); mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent'");
exit(); exit();
} }
@@ -57,11 +76,11 @@ $row = mysqli_fetch_array($auth_user);
// Check SQL query state // Check SQL query state
if(mysqli_num_rows($auth_user) < 1 || !$auth_user){ if(mysqli_num_rows($auth_user) < 1 || !$auth_user){
$data['found'] = "FALSE"; $data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not logged into ITFlow, do not have, or did not send the correct extension key cookie."; $data['message'] = WORDING_BAD_EXT_COOKIE_KEY;
echo(json_encode($data)); echo(json_encode($data));
//Logging //Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()"); mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent'");
exit(); exit();
} }
@@ -69,51 +88,36 @@ if(mysqli_num_rows($auth_user) < 1 || !$auth_user){
// Sanity check // Sanity check
if(hash('sha256', $row['user_extension_key']) !== hash('sha256', $_COOKIE['user_extension_key'])){ if(hash('sha256', $row['user_extension_key']) !== hash('sha256', $_COOKIE['user_extension_key'])){
$data['found'] = "FALSE"; $data['found'] = "FALSE";
$data['message'] = "ITFlow - Validation failed."; $data['message'] = WORDING_BAD_EXT_COOKIE_KEY;
echo(json_encode($data)); echo(json_encode($data));
//Logging //Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()"); mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent'");
exit(); exit();
} }
// Success - validated user cookie // Success - validated user cookie
// Get the current session from the database so we can decrypt passwords // Get the current session from the database, so we can decrypt passwords
session_id($row['user_php_session']); session_id($row['user_php_session']);
session_start(); session_start();
$session_user_id = $row['user_id']; $session_user_id = $row['user_id'];
$session_name = $row['user_name']; $session_name = $row['user_name'];
$session_email = $row['user_email']; $session_email = $row['user_email'];
$session_avatar = $row['user_avatar'];
$session_token = $row['user_token'];
$session_company_id = $row['user_default_company']; $session_company_id = $row['user_default_company'];
$session_user_role = $row['user_role']; $session_user_role = $row['user_role'];
if($session_user_role == 6){
$session_user_role_display = "Global Administrator";
}elseif($session_user_role == 5){
$session_user_role_display = "Administrator";
}elseif($session_user_role == 4){
$session_user_role_display = "Technician";
}elseif($session_user_role == 3){
$session_user_role_display = "IT Contractor";
}elseif($session_user_role == 2){
$session_user_role_display = "Client";
}else{
$session_user_role_display = "Accountant";
}
// Check user access level is correct // Check user access level is correct (not an accountant)
if($session_user_role < 4){ if($session_user_role < 1){
$data['found'] = "FALSE"; $data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not authorised to use this application."; $data['message'] = WORDING_ROLECHECK_FAILED;
echo(json_encode($data)); echo(json_encode($data));
//Logging //Logging
$user_name = mysqli_real_escape_string($mysqli, $session_name); $user_name = mysqli_real_escape_string($mysqli, $session_name);
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = '$user_name not authorised to use extension', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_user_id = $session_user_id"); mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = '$user_name not authorised to use extension', log_ip = '$ip', log_user_agent = '$user_agent', log_user_id = $session_user_id");
exit(); exit();
} }
@@ -131,18 +135,17 @@ if(isset($_GET['host'])){
$row = mysqli_fetch_array($sql_logins); $row = mysqli_fetch_array($sql_logins);
$data['found'] = "TRUE"; $data['found'] = "TRUE";
$data['username'] = htmlentities($row['login_username']); $data['username'] = htmlentities($row['login_username']);
$data['password'] = decryptLoginEntry($row['login_password']); $data['password'] = decryptLoginEntry($row['login_password']); // Uses the PHP Session info and the session key cookie
echo json_encode($data); echo json_encode($data);
// Logging // Logging
$login_name = mysqli_real_escape_string($mysqli, $row['login_name']); $login_name = mysqli_real_escape_string($mysqli, $row['login_name']);
$login_user = mysqli_real_escape_string($mysqli, $row['login_username']); $login_user = mysqli_real_escape_string($mysqli, $row['login_username']);
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Extension requested', log_description = 'Credential $login_name, username $login_user', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), company_id = $session_company_id, log_user_id = $session_user_id"); mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Extension requested', log_description = 'Credential $login_name, username $login_user', log_ip = '$ip', log_user_agent = '$user_agent', company_id = $session_company_id, log_user_id = $session_user_id");
} }
} }
} }
//TODO: Future work:- //TODO: Future work:-
// - Check user has permission to this client
// - Showing multiple logins for a single URL // - Showing multiple logins for a single URL
+10 -13
View File
@@ -8,14 +8,11 @@ if(!file_exists('config.php')){
include("config.php"); include("config.php");
include("functions.php"); include("functions.php");
// SESSION FINGERPRINT // IP & User Agent for logging
$ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip())); $ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip()));
$os = strip_tags(mysqli_real_escape_string($mysqli,get_os()));
// User agent
$user_agent = strip_tags(mysqli_real_escape_string($mysqli,$_SERVER['HTTP_USER_AGENT'])); $user_agent = strip_tags(mysqli_real_escape_string($mysqli,$_SERVER['HTTP_USER_AGENT']));
// HTTP Only cookies // HTTP-Only cookies
ini_set("session.cookie_httponly", True); ini_set("session.cookie_httponly", True);
// Tell client to only send cookie(s) over HTTPS // Tell client to only send cookie(s) over HTTPS
@@ -23,6 +20,7 @@ if($config_https_only){
ini_set("session.cookie_secure", True); ini_set("session.cookie_secure", True);
} }
// Handle POST login request
if(isset($_POST['login'])){ if(isset($_POST['login'])){
// Sessions should start after the user has POSTed data // Sessions should start after the user has POSTed data
@@ -37,11 +35,11 @@ if(isset($_POST['login'])){
if($failed_login_count >= 10){ if($failed_login_count >= 10){
// Logging // Logging
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Failed', log_description = 'Failed login attempt due to IP lockout', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()"); mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Failed', log_description = 'Failed login attempt due to IP lockout', log_ip = '$ip', log_user_agent = '$user_agent'");
// Send an alert only count hits 10 to reduce flooding alerts (using 1 as "default" company) // Send an alert only count hits 10 to reduce flooding alerts (using 1 as "default" company)
if($failed_login_count == 10){ if($failed_login_count == 10){
mysqli_query($mysqli,"INSERT INTO alerts SET alert_type = 'Lockout', alert_message = '$ip was locked out for repeated failed login attempts.', alert_date = NOW(), company_id = '1'"); mysqli_query($mysqli,"INSERT INTO notifications SET notification_type = 'Lockout', notification = '$ip was locked out for repeated failed login attempts.', notification_timestamp = NOW() company_id = '1'");
} }
// Inform user // Inform user
@@ -55,8 +53,8 @@ if(isset($_POST['login'])){
if(isset($_POST['current_code'])){ if(isset($_POST['current_code'])){
$current_code = strip_tags(mysqli_real_escape_string($mysqli, $_POST['current_code'])); $current_code = strip_tags(mysqli_real_escape_string($mysqli, $_POST['current_code']));
} }
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_email = '$email' AND user_archived_at IS NULL");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_email = '$email' AND user_archived_at IS NULL"));
if (password_verify($password, $row['user_password'])) { if (password_verify($password, $row['user_password'])) {
$token = $row['user_token']; $token = $row['user_token'];
@@ -66,11 +64,10 @@ if(isset($_POST['login'])){
$user_id = $row['user_id']; $user_id = $row['user_id'];
// Setup encryption session key // Setup encryption session key
if (isset($row['user_specific_encryption_ciphertext'])) { if (isset($row['user_specific_encryption_ciphertext']) && $row['user_role'] > 1) {
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext']; $user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];
$site_encryption_master_key = decryptUserSpecificKey($user_encryption_ciphertext, $password); $site_encryption_master_key = decryptUserSpecificKey($user_encryption_ciphertext, $password);
generateUserSessionKey($site_encryption_master_key); generateUserSessionKey($site_encryption_master_key);
}
// Setup extension // Setup extension
if (isset($row['user_extension_key']) && !empty($row['user_extension_key'])) { if (isset($row['user_extension_key']) && !empty($row['user_extension_key'])) {
@@ -81,12 +78,12 @@ if(isset($_POST['login'])){
// Set PHP session in DB so we can access the session encryption data (above) // Set PHP session in DB so we can access the session encryption data (above)
$user_php_session = session_id(); $user_php_session = session_id();
mysqli_query($mysqli, "UPDATE users SET user_php_session = '$user_php_session' WHERE user_id = '$user_id'"); mysqli_query($mysqli, "UPDATE users SET user_php_session = '$user_php_session' WHERE user_id = '$user_id'");
}
} }
if (empty($token)) { if (empty($token)) {
$_SESSION['logged'] = TRUE; $_SESSION['logged'] = TRUE;
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Success', log_description = '$user_name successfully logged in', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_user_id = $user_id"); mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Success', log_description = '$user_name successfully logged in', log_ip = '$ip', log_user_agent = '$user_agent', log_user_id = $user_id");
header("Location: dashboard_financial.php"); header("Location: dashboard_financial.php");
} else { } else {
+283 -283
View File
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -24,18 +24,17 @@
} }
return false; return false;
} }
public static function getTokenCode($secretkey,$rangein30s = 3) { public static function getTokenCode($secretkey) {
$result = ""; $result = "";
$key = base32static::decode($secretkey); $key = base32static::decode($secretkey);
$unixtimestamp = time()/30; $unixtimestamp = time()/30;
for($i=-($rangein30s); $i<=$rangein30s; $i++) { $checktime = (int)($unixtimestamp);
$checktime = (int)($unixtimestamp+$i);
$thiskey = self::oath_hotp($key, $checktime); $thiskey = self::oath_hotp($key, $checktime);
$result = $result." # ".self::oath_truncate($thiskey,6); $result = $result . self::oath_truncate($thiskey,6);
}
return $result; $result = "000000" . $result;
return substr($result, -6);
} }
public static function getTokenCodeDebug($secretkey,$rangein30s = 3) { public static function getTokenCodeDebug($secretkey,$rangein30s = 3) {
$result = ""; $result = "";
+4
View File
@@ -73,6 +73,8 @@ $sql_recent_logs = mysqli_query($mysqli,"SELECT * FROM logs
<input type="file" class="form-control-file" accept="image/*;capture=camera" name="file"> <input type="file" class="form-control-file" accept="image/*;capture=camera" name="file">
</div> </div>
<?php if($session_user_role > 1){ ?>
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="form-check">
<input type="checkbox" class="form-check-input" name="extension" id="extension" value="Yes" <?php if(isset($_COOKIE['user_extension_key'])) {echo "checked";} ?>> <input type="checkbox" class="form-check-input" name="extension" id="extension" value="Yes" <?php if(isset($_COOKIE['user_extension_key'])) {echo "checked";} ?>>
@@ -81,6 +83,8 @@ $sql_recent_logs = mysqli_query($mysqli,"SELECT * FROM logs
</div> </div>
</div> </div>
<?php } ?>
<button type="submit" name="edit_profile" class="btn btn-primary mt-3"><i class="fa fa-fw fa-check"></i> Save</button> <button type="submit" name="edit_profile" class="btn btn-primary mt-3"><i class="fa fa-fw fa-check"></i> Save</button>
+1 -1
View File
@@ -70,7 +70,7 @@
<option value="0">Not Assigned</option> <option value="0">Not Assigned</option>
<?php <?php
$sql = mysqli_query($mysqli,"SELECT * FROM users, user_companies WHERE users.user_id = user_companies.user_id AND user_companies.company_id = $session_company_id ORDER BY user_name ASC"); $sql = mysqli_query($mysqli,"SELECT * FROM users, user_companies WHERE users.user_id = user_companies.user_id AND user_archived_at IS NULL AND user_companies.company_id = $session_company_id ORDER BY user_name ASC");
while($row = mysqli_fetch_array($sql)){ while($row = mysqli_fetch_array($sql)){
$user_id = $row['user_id']; $user_id = $row['user_id'];
$user_name = $row['user_name']; $user_name = $row['user_name'];