Skip to content
Snippets Groups Projects
Commit 60ccaaea authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

update mfa client

parent a3f65c25
No related branches found
No related tags found
1 merge request!468133 small fixes
...@@ -3,22 +3,15 @@ ...@@ -3,22 +3,15 @@
* mfa-ensure.php * mfa-ensure.php
* *
* @author Axel Hahn <axel.hahn@unibe> * @author Axel Hahn <axel.hahn@unibe>
* @package IML-Appmonitor
* *
*/ */
if(!($_SERVER['REMOTE_USER']??false)){
return true;
}
$aConfig = @include "mfaconfig.php";
if(!($aConfig['api']??false)){
return true;
}
require_once __DIR__.'/mfaclient.class.php'; require_once __DIR__.'/mfaclient.class.php';
$mfa = new mfaclient($aConfig, ($_SERVER['REMOTE_USER']??'')); $mfa = new mfaclient();
$mfa->debug($aConfig['debug']??false); $mfa->debug($aConfig['debug']??false);
$iHttpStatus=$mfa->ensure(); $iHttpStatus=$mfa->ensure();
// mfa was skipped? Enable this line to see the reason
// echo $mfa->showStatus();
\ No newline at end of file
<?php <?php
/**
*
* MFA CLIENT CLASS
*
* Connect a web app with MFA server
*
* Source: https://git-repo.iml.unibe.ch/iml-open-source/
* Docs: https://os-docs.iml.unibe.ch/mfa-client/index.html
* License: GNU GPL 3.0
*
* 2025-06-11 <axel.hahn@unibe.ch> initial version
* 2025-06-30 <axel.hahn@unibe.ch> set version 1.0.1 in user agenmt in http requests
*/
class mfaclient class mfaclient
{ {
protected string $_sVersion = "1.0.1";
protected array $aConfig = []; protected array $aConfig = [];
// protected string $sSessionvarname = "mfaclient"; // protected string $sSessionvarname = "mfaclient";
...@@ -13,6 +28,8 @@ class mfaclient ...@@ -13,6 +28,8 @@ class mfaclient
protected bool $bDebug = false; protected bool $bDebug = false;
protected array $aStatus = [];
/** /**
* Intialize mfa client - optional set config and user * Intialize mfa client - optional set config and user
* *
...@@ -20,17 +37,14 @@ class mfaclient ...@@ -20,17 +37,14 @@ class mfaclient
* @see setUser * @see setUser
* *
* @param array $aConfig optional: configuration with app id and base url * @param array $aConfig optional: configuration with app id and base url
* @param string $sUser optional: user id that was logged in
*/ */
public function __construct(array $aConfig = [], string $sUser = "") public function __construct(array $aConfig = [])
{ {
$this->loadConfig(); $this->loadConfig();
if ($aConfig) { if ($aConfig) {
$this->setConfig($aConfig); $this->setConfig($aConfig);
} }
if ($sUser) { $this->setUser($this->aConfig['user']??'');
$this->setUser($sUser);
}
} }
...@@ -77,7 +91,7 @@ class mfaclient ...@@ -77,7 +91,7 @@ class mfaclient
// } // }
curl_setopt($ch, CURLOPT_TIMEOUT, $iTimeout); curl_setopt($ch, CURLOPT_TIMEOUT, $iTimeout);
curl_setopt($ch, CURLOPT_USERAGENT, 'IML MFA client' . __CLASS__); curl_setopt($ch, CURLOPT_USERAGENT, "IML MFA client PHP v$this->_sVersion");
curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
...@@ -274,7 +288,6 @@ class mfaclient ...@@ -274,7 +288,6 @@ class mfaclient
if (file_exists($sCfgfile)) { if (file_exists($sCfgfile)) {
$aTmp = include $sCfgfile; $aTmp = include $sCfgfile;
$this->aConfig = $aTmp??[]; $this->aConfig = $aTmp??[];
$this->setUser($aTmp['user']??'');
} }
} }
/** /**
...@@ -300,7 +313,8 @@ class mfaclient ...@@ -300,7 +313,8 @@ class mfaclient
} }
/** /**
* Logout * Logout; unset user in session scope
*
* @return void * @return void
*/ */
public function logout() public function logout()
...@@ -362,11 +376,24 @@ class mfaclient ...@@ -362,11 +376,24 @@ class mfaclient
session_start(); session_start();
} }
if (($_SESSION['mfa']['user'] ?? '') == $this->sUser) { if (($_SESSION['mfa']['user'] ?? '') == $this->sUser) {
$this->aStatus[] = 'User still has a valid session after solving a challenge.';
return 200; return 200;
} else { } else {
$this->logout(); $this->logout();
} }
foreach(['api', 'appid', 'shared_secret', 'user'] as $sKey){
if(!isset($this->aConfig[$sKey])){
$this->aStatus[] = "Skip: Key '$sKey' was not set in config.";
return 200;
}
if(!$this->aConfig[$sKey]){
$this->aStatus[] = "Skip: Key '$sKey' is empty in config.";
return 200;
}
}
$aMfaReturn = $this->check(); $aMfaReturn = $this->check();
$this->_wd(__METHOD__ . "<br>Http request to mfa api<pre>" . print_r($aMfaReturn, 1) . "</pre>"); $this->_wd(__METHOD__ . "<br>Http request to mfa api<pre>" . print_r($aMfaReturn, 1) . "</pre>");
$aBody = json_decode($aMfaReturn['response']['body'] ?? '', 1); $aBody = json_decode($aMfaReturn['response']['body'] ?? '', 1);
...@@ -393,6 +420,8 @@ class mfaclient ...@@ -393,6 +420,8 @@ class mfaclient
); );
} }
$this->aStatus[] = 'User solved the session now.';
$_SESSION['mfa']['user'] = $this->sUser; $_SESSION['mfa']['user'] = $this->sUser;
session_write_close(); session_write_close();
...@@ -403,7 +432,8 @@ class mfaclient ...@@ -403,7 +432,8 @@ class mfaclient
/** /**
* Get an html button to open mfa setup page * Get an html button to open mfa setup page
* *
* @param string $sSubmitBtn * @param string $sSubmitBtn optional: html code for a submit button; default: '<button>MFA Setup</button>'
* @param string $sBackUrl optional: url to return from mfa server to the application; default: current url
* @return void * @return void
*/ */
public function getButtonSetup(string $sSubmitBtn = '<button>MFA Setup</button>', $sBackUrl = ''): string public function getButtonSetup(string $sSubmitBtn = '<button>MFA Setup</button>', $sBackUrl = ''): string
...@@ -412,7 +442,7 @@ class mfaclient ...@@ -412,7 +442,7 @@ class mfaclient
// print_r($aBody); // print_r($aBody);
$sUrl = $aBody['setup'] ?? ''; $sUrl = $aBody['setup'] ?? '';
if ($sUrl) { if ($sUrl) {
$sBackUrl = $sBackUrl ?: $_SERVER['HTTP_REFERER']; $sBackUrl = $sBackUrl ?: ( "http".(($_SERVER['HTTPS']??'') === 'on' ? "s" : "")."://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
return $this->jumpform($sUrl, $sSubmitBtn, $sBackUrl); return $this->jumpform($sUrl, $sSubmitBtn, $sBackUrl);
} else { } else {
return $aBody['message']??''; return $aBody['message']??'';
...@@ -423,10 +453,9 @@ class mfaclient ...@@ -423,10 +453,9 @@ class mfaclient
/** /**
* Open User settings to setup mfa methods * Open User settings to setup mfa methods
* *
* @param string $sUrl * @param string $sUrl url to open
* @param string $sSubmitBtn * @param string $sSubmitBtn html code for a submit button
* @return void * @return void
*/
public function openSetup(string $sUrl = '', string $sSubmitBtn = '<button>MFA Setup</button>', $sBackUrl = '') public function openSetup(string $sUrl = '', string $sSubmitBtn = '<button>MFA Setup</button>', $sBackUrl = '')
{ {
if (!$sUrl) { if (!$sUrl) {
...@@ -438,6 +467,7 @@ class mfaclient ...@@ -438,6 +467,7 @@ class mfaclient
$this->_jump($sUrl, $sSubmitBtn, $sBackUrl); $this->_jump($sUrl, $sSubmitBtn, $sBackUrl);
} }
} }
*/
/** /**
* Get IP of current client (to be sent to MFA server) * Get IP of current client (to be sent to MFA server)
...@@ -464,6 +494,24 @@ class mfaclient ...@@ -464,6 +494,24 @@ class mfaclient
return $ipaddress; return $ipaddress;
} }
/**
* return current config
* @return array
*/
public function getConfig(): array
{
return $this->aConfig;
}
/**
* return current status
* @return array
*/
public function getStatus(): array
{
return $this->aStatus;
}
/** /**
* get list of urls from MFA server * get list of urls from MFA server
* *
...@@ -474,5 +522,16 @@ class mfaclient ...@@ -474,5 +522,16 @@ class mfaclient
return $this->_api("urls"); return $this->_api("urls");
} }
/**
* show current status if you want to find out why mfa was skipped
* @example <code>echo $mfa->showStatus();</code>
* @return string
*/
public function showStatus(): string
{
return 'MFA status: <ul><li>'
. implode('</li><li>', $this->aStatus)
.'</li></ul>'
;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment