Skip to content

Commit

Permalink
- added security audit menu and fixed a mailer parameter bug
Browse files Browse the repository at this point in the history
  • Loading branch information
softcoder committed Feb 10, 2024
1 parent 77b4985 commit 8ff9982
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 2 deletions.
6 changes: 6 additions & 0 deletions php/config-default.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@

);

$config = new \riprunner\ConfigManager();

$php_session_save_path = $config->getSystemConfigValue('session.save_path');
if(strlen($php_session_save_path ?? '') > 0) {
ini_set('session.save_path', $php_session_save_path);
}

// =============================================================================================
// ===--------------EDIT BLOCKS BELOW TO COMPLETE THE SETUP FOR YOUR SITE--------------------===
Expand Down
33 changes: 33 additions & 0 deletions php/controllers/security-menu-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
// ==============================================================
// Copyright (C) 2024 Mark Vejvoda
// Under GNU GPL v3.0
// ==============================================================
namespace riprunner;

define( 'INCLUSION_PERMITTED', true );

if(defined('__RIPRUNNER_ROOT__') === false) {
define('__RIPRUNNER_ROOT__', dirname(dirname(__FILE__)));
}

require_once __RIPRUNNER_ROOT__ . '/template.php';
require_once __RIPRUNNER_ROOT__ . '/authentication/authentication.php';
require_once __RIPRUNNER_ROOT__ . '/models/global-model.php';
require_once __RIPRUNNER_ROOT__ . '/models/live-callout-warning-model.php';
require_once __RIPRUNNER_ROOT__ . '/models/security-menu-model.php';
require_once __RIPRUNNER_ROOT__ . '/logging.php';

// Register our view and variables for the template
Authentication::setJWTCookie();
Authentication::sec_session_start();
new LiveCalloutWarningViewModel($global_vm, $view_template_vars);
$securitymenu_mv = new SecurityMenuViewModel($global_vm, $view_template_vars);

// Load out template
$template = $twig->resolveTemplate(
array('@custom/security-menu-custom.twig.html',
'security-menu.twig.html'));

// Output our template
echo $template->render($view_template_vars);
4 changes: 2 additions & 2 deletions php/email_polling.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ public function imap_headers($imap_stream) {
}

public function imap_headerinfo($imap_stream, $msg_number, $fromlength = null, $subjectlength = null, $defaulthost = null) {
return \imap_headerinfo($imap_stream, $msg_number, $fromlength, $subjectlength, $defaulthost);
return \imap_headerinfo($imap_stream, $msg_number, $fromlength ?? 0, $subjectlength ?? 0);
}

public function imap_expunge($imap_stream) {
return \imap_expunge($imap_stream);
}

public function imap_close($imap_stream, $flag = null) {
return \imap_close($imap_stream, $flag);
return \imap_close($imap_stream, $flag ?? 0);
}

public function imap_fetchstructure($imap_stream, $msg_number, $options = null) {
Expand Down
82 changes: 82 additions & 0 deletions php/models/security-menu-model.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
// ==============================================================
// Copyright (C) 2014 Mark Vejvoda
// Under GNU GPL v3.0
// ==============================================================
namespace riprunner;

require_once __RIPRUNNER_ROOT__ . '/config.php';
require_once __RIPRUNNER_ROOT__ . '/authentication/authentication.php';
require_once __RIPRUNNER_ROOT__ . '/functions.php';
require_once __RIPRUNNER_ROOT__ . '/models/base-model.php';
require_once __RIPRUNNER_ROOT__ . '/authentication/auth-notification.php';

// The model class handling variable requests dynamically
class SecurityMenuViewModel extends BaseViewModel {

protected function getVarContainerName() {
return "securitymenu_vm";
}

public function __get($name) {
if('audit_list' === $name) {
return $this->getAuditList();
}

return parent::__get($name);
}

public function __isset($name) {
if(in_array($name,
array('audit_list')) === true) {
return true;
}
return parent::__isset($name);
}

private function getAuditList() {
global $log;


$sql_statement = new SqlStatement($this->getGvm()->RR_DB_CONN);
$sql = $sql_statement->getSqlStatement('login_audit_by_date_recent');
$qry_bind = $this->getGvm()->RR_DB_CONN->prepare($sql);

$qry_bind->execute();

$rows = $qry_bind->fetchAll(\PDO::FETCH_ASSOC);
$qry_bind->closeCursor();

$log->trace("About to display audit list for sql [$sql] result count: " . safe_count($rows));

$firehall = $this->getGvm()->firehall;
$db_connection = $this->getGvm()->RR_DB_CONN;
$auth_notification = new \riprunner\AuthNotification($firehall,$db_connection);
$geo_location_cache = array();

$resultArray = array();
foreach($rows as $row){
// Add any custom fields with values here
$ip = $row['login_ip'];
if (preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $ip, $ip_match)) {
$ip = $ip_match[0];

if(in_array($ip,$geo_location_cache)) {
$ip_location = array_search($ip,$geo_location_cache);
}
else {
$ip_location = $auth_notification->getIpLocation($ip);
$geo_location_cache[$ip] = $ip_location;
}
}
else {
$ip_location = '???';
}
$row['geo_location'] = $ip_location;
$resultArray[] = $row;
}

return $resultArray;
}

}
46 changes: 46 additions & 0 deletions php/sql/sql_mysql.ini
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,12 @@ login_audit_insert = "INSERT INTO login_audit (useracctid, username, status, log
login_audit_by_user = "SELECT * FROM login_audit
WHERE useracctid = :useracctid AND status < 100"

login_audit_by_date_recent = "SELECT a.id,a.username,b.name,a.login_agent,a.login_ip,a.updatetime
FROM login_audit a
left join login_audit_types b on a.status = b.id
WHERE a.updatetime >= CURRENT_DATE() - INTERVAL 3 MONTH
ORDER BY a.updatetime DESC;"

schema_version_get = "SELECT keyvalue from config WHERE firehall_id = -1 AND keyname = 'DB_SCHEMA_VERSION' AND keyindex = 0;"

schema_upgrade_1_1 = "CREATE TABLE IF NOT EXISTS `config` (
Expand Down Expand Up @@ -845,3 +851,43 @@ schema_upgrade_6_4_skip_error = true

schema_upgrade_6_5 = "UPDATE config
SET keyvalue= '6.5' WHERE firehall_id = -1 AND keyname = 'DB_SCHEMA_VERSION' AND keyindex = 0;"

schema_upgrade_6_6 = "CREATE TABLE IF NOT EXISTS `login_audit_types` (
`id` int(11) NOT NULL PRIMARY KEY,
`firehall_id` varchar(80) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`updatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"
schema_upgrade_6_6_skip_error = true

schema_upgrade_6_7 = "INSERT IGNORE INTO login_audit_types
SET id=0, firehall_id = -1, name = 'login success with password';"
schema_upgrade_6_7_skip_error = true

schema_upgrade_6_8 = "INSERT IGNORE INTO login_audit_types
SET id=1, firehall_id = -1, name = 'login success with two factor';"
schema_upgrade_6_8_skip_error = true

schema_upgrade_6_9 = "INSERT IGNORE INTO login_audit_types
SET id=10, firehall_id = -1, name = 'changed password';"
schema_upgrade_6_9_skip_error = true

schema_upgrade_7_0 = "INSERT IGNORE INTO login_audit_types
SET id=100, firehall_id = -1, name = 'invalid username';"
schema_upgrade_7_0_skip_error = true

schema_upgrade_7_1 = "INSERT IGNORE INTO login_audit_types
SET id=101, firehall_id = -1, name = 'invalid password';"
schema_upgrade_7_1_skip_error = true

schema_upgrade_7_2 = "INSERT IGNORE INTO login_audit_types
SET id=102, firehall_id = -1, name = 'invalid two factor';"
schema_upgrade_7_2_skip_error = true

schema_upgrade_7_3 = "INSERT IGNORE INTO login_audit_types
SET id=103, firehall_id = -1, name = 'account locked';"
schema_upgrade_7_3_skip_error = true

schema_upgrade_7_4 = "UPDATE config
SET keyvalue= '7.4' WHERE firehall_id = -1 AND keyname = 'DB_SCHEMA_VERSION' AND keyindex = 0;"

1 change: 1 addition & 0 deletions php/views/main-menu.twig.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<li><a href="{{ gvm.RR_DOC_ROOT }}/controllers/address-override-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM }}">Callout Address Overrides</a></li>
<li><a href="{{ gvm.RR_DOC_ROOT }}/controllers/system-config-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM }}">System Settings</a></li>
<li><a href="{{ gvm.RR_DOC_ROOT }}/controllers/system-info-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM }}">System Information</a></li>
<li><a href="{{ gvm.RR_DOC_ROOT }}/controllers/security-menu-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM }}">Security Information</a></li>
<li><a href="{{ gvm.RR_DOC_ROOT }}/controllers/system-test-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM }}">System Testing</a></li>
<li><a href="{{ gvm.RR_DOC_ROOT }}/controllers/view-logs-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM }}">View Logs</a></li>
</ul>
Expand Down
109 changes: 109 additions & 0 deletions php/views/security-menu.twig.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Secure Login: Protected Page</title>
{% if gvm.isMobile %}
<link rel="stylesheet" href="{{ gvm.RR_DOC_ROOT }}/styles/mobile.css?version=1" />
<link rel="stylesheet" href="{{ gvm.RR_DOC_ROOT }}/styles/table-styles-mobile.css" />
{% else %}
<link rel="stylesheet" href="{{ gvm.RR_DOC_ROOT }}/styles/main.css?version=1" />
<link rel="stylesheet" href="{{ gvm.RR_DOC_ROOT }}/styles/table-styles.css" />
{% endif %}
<script type="text/JavaScript" src="{{ gvm.RR_DOC_ROOT }}/js/jquery-2.1.1.min.js"></script>
<link rel="stylesheet" href="{{ gvm.RR_DOC_ROOT }}/styles/freeze-header.css" />
<script type="text/JavaScript" src="{{ gvm.RR_DOC_ROOT }}/js/forms.js"></script>
</head>
<body>
<div class="container_center">
{% if gvm.auth.isAuth and gvm.auth.isAdmin %}

{% include 'user-welcome.twig.html' %}
{% include 'live-callout-warning.twig.html' %}

<div class="menudiv_wrapper">
<nav class="vertical">
<ul>
<li>
<label for="main_page">Return to ..</label>
<input type="radio" name="verticalMenu" id="main_page" />
<div>
<ul>
<li><a href="{{ gvm.RR_DOC_ROOT }}/controllers/main-menu-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM|raw }}">Main Menu</a></li>
</ul>
</div>
</li>
<li>
<label for="logout">Exit</label>
<input type="radio" name="verticalMenu" id="logout" />
<div>
<ul>
<li><a href="{{ gvm.RR_DOC_ROOT }}/logout.php">Logout</a></li>
</ul>
</div>
</li>
</ul>
</nav>
</div>

<h3>Recent Login Audit</h3>
<form action="{{ gvm.RR_DOC_ROOT }}/controllers/security-menu-controller.php?{{ gvm.RR_JWT_TOKEN_PARAM|raw }}"
method="post" name="security_form">

<center>

<table id="box-table-a">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">User Name</th>
<th scope="col">Audit Status</th>
<th scope="col">User Agent</th>
<th scope="col">IP Address</th>
<th scope="col">GEO Location</th>
<th scope="col">Date/Time</th>
<tr>
</thead>



{% for audit in securitymenu_vm.audit_list %}

<tr>
<td>
{{ audit.id }}
</td>

<td>
{{ audit.username }}
</td>

<td class="column_nowrap">
{{ audit.name }}
</td>
<td class="column_nowrap">
{{ audit.login_agent }}
</td>

<td class="column_nowrap">
{{ audit.login_ip }}
</td>
<td class="column_nowrap">
{{ audit.geo_location }}
</td>
<td class="column_nowrap">
{{ audit.updatetime }}
</td>
</tr>
{% endfor %}

</table>
</center>
</form>

{% else %}
{% include 'access-denied.twig.html' %}
{% endif %}
</div>
</body>
</html>

0 comments on commit 8ff9982

Please sign in to comment.