461 lines
16 KiB
PHP
461 lines
16 KiB
PHP
<?php
|
|
// ---------- General Helpers ----------
|
|
function instr($string, $search){
|
|
return str_contains($string, $search);
|
|
}
|
|
function PostJson($url, $content){
|
|
$curl = curl_init($url);
|
|
curl_setopt($curl, CURLOPT_HEADER, false);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($curl, CURLOPT_HTTPHEADER, ["Content-type: application/json","charset=utf-8"]);
|
|
curl_setopt($curl, CURLOPT_POST, true);
|
|
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
|
|
curl_setopt($curl, CURLOPT_USERNAME, "test");
|
|
$retour = curl_exec($curl);
|
|
curl_close($curl);
|
|
return $retour;
|
|
}
|
|
function Read_HTML($url){
|
|
$curl = curl_init($url);
|
|
curl_setopt($curl, CURLOPT_HEADER, false);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
$retour = curl_exec($curl);
|
|
curl_close($curl);
|
|
return $retour;
|
|
}
|
|
function getSourceInfo(): string {
|
|
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN_IP';
|
|
$remoteUser = $_SERVER['REMOTE_USER'] ?? '';
|
|
$hostname = @gethostbyaddr($remoteAddr);
|
|
$sourceMachine = ($hostname && $hostname !== $remoteAddr) ? explode('.', $hostname)[0] : $remoteAddr;
|
|
$sourceUser = '';
|
|
if (!empty($remoteUser)) {
|
|
$userParts = explode('\\', $remoteUser);
|
|
$sourceUser = end($userParts);
|
|
}
|
|
return !empty($sourceUser) ? "$sourceUser on $sourceMachine" : $sourceMachine;
|
|
}
|
|
function decypher(string $name): ?string {
|
|
$openssl = 'C:\Program Files\FireDaemon OpenSSL 3\bin\openssl.exe';
|
|
$cmsFile = "F:\\Include\\dat\\$name.p7m";
|
|
$certPem = "F:\\Include\\certs\\cert_only.pem";
|
|
$keyPem = "F:\\Include\\certs\\key_only.pem";
|
|
|
|
foreach ([$openssl,$cmsFile,$certPem,$keyPem] as $p) {
|
|
if (!is_file($p)) { error_log("Missing file: $p"); return null; }
|
|
}
|
|
|
|
$cmd = '"' . $openssl . '" cms -decrypt -inform PEM'
|
|
. ' -in ' . escapeshellarg($cmsFile)
|
|
. ' -recip ' . escapeshellarg($certPem)
|
|
. ' -inkey ' . escapeshellarg($keyPem)
|
|
. ' -out -';
|
|
|
|
$spec = [
|
|
0 => ['pipe','r'],
|
|
1 => ['pipe','w'],
|
|
2 => ['pipe','w'],
|
|
];
|
|
$proc = proc_open($cmd, $spec, $pipes);
|
|
if (!is_resource($proc)) { error_log('proc_open failed'); return null; }
|
|
fclose($pipes[0]);
|
|
|
|
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
|
|
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
|
|
$code = proc_close($proc);
|
|
|
|
if ($code !== 0) {
|
|
error_log("OpenSSL failed (code $code): $stderr");
|
|
return null;
|
|
}
|
|
return $stdout;
|
|
}
|
|
|
|
// ---------- DB logging ----------
|
|
function log2DB(){
|
|
global $input, $done, $rc, $stdout, $SourceUser, $actor;
|
|
|
|
// Table name
|
|
$parts = explode("/", ltrim($_SERVER['SCRIPT_NAME'], '/'));
|
|
$ws = strtoupper($parts[0]) . "_" . strtolower($parts[count($parts)-1]);
|
|
$ws = str_replace(".php", "", $ws);
|
|
$ws = preg_replace('/[^A-Za-z0-9_]/', '_', $ws);
|
|
$table = "[dbo].[" . str_replace(']', ']]', $ws) . "]";
|
|
|
|
// Create table if missing
|
|
$create = "
|
|
IF OBJECT_ID(N'$table', N'U') IS NULL
|
|
BEGIN
|
|
CREATE TABLE $table (
|
|
idx INT IDENTITY PRIMARY KEY,
|
|
ts NVARCHAR(20),
|
|
source NVARCHAR(256),
|
|
input NVARCHAR(MAX),
|
|
actor NVARCHAR(64),
|
|
done INT,
|
|
rc INT,
|
|
stdout NVARCHAR(MAX)
|
|
);
|
|
END";
|
|
Invoke_WSinfra($create);
|
|
|
|
// Prepare insertion
|
|
$ts = date("Y-m-d H:i:s");
|
|
$cutmp = $GLOBALS['CURRENT_USER'] ?? (defined('CURRENT_USER') ? CURRENT_USER : 'Anonymous');
|
|
$cu = $SourceUser ?? $cutmp;
|
|
$ci = $GLOBALS['CURRENT_IP'] ?? (defined('CURRENT_IP') ? CURRENT_IP : ($_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN'));
|
|
$s = @gethostbyaddr($ci);
|
|
if ($s && $s !== ($_SERVER['X_FORWARDED_FOR'] ?? '')) {
|
|
if (!filter_var($s, FILTER_VALIDATE_IP)) {$s = explode('.', $s)[0];}
|
|
}
|
|
$source = str_replace('\\','_', $cu) . " on " . ($s ?: $ci);
|
|
|
|
$esc = function($v){ return str_replace("'", "''", (string)$v); };
|
|
|
|
$ts_e = $esc($ts);
|
|
$source_e = $esc($source);
|
|
$input_e = $esc($input ?? '');
|
|
$stdout_e = $esc($stdout ?? '');
|
|
$actor_e = $esc($actor ?? '');
|
|
|
|
// Insert
|
|
$sqlIns = "
|
|
INSERT INTO $table (ts, source, input, actor, done, rc, stdout)
|
|
VALUES (N'$ts_e', N'$source_e', N'$input_e', N'$actor_e', $done, $rc, N'$stdout_e')";
|
|
Invoke_WSinfra($sqlIns);
|
|
}
|
|
|
|
// ---------- DB connections ----------
|
|
function Invoke_WebSelfInfra($request){
|
|
$user = "Scom-Write";
|
|
$pwd = decypher("web-self-infra");
|
|
$server = "DUN-PRD-R1SCOM.armony.net\OPS";
|
|
$database = "web-self-infra";
|
|
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
|
|
$rs = odbc_exec($conn, $request);
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = odbc_fetch_array($rs)) {
|
|
$answer[] = $row;
|
|
}
|
|
}
|
|
if (isset($answer)) {
|
|
return $answer;
|
|
}
|
|
}
|
|
function Invoke_SCOMInfra($request){
|
|
$user = "Scom-Write";
|
|
$pwd = decypher("scom-infra");
|
|
$server = "DUN-PRD-R1SCOM.armony.net\OPS";
|
|
$database = "infra";
|
|
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database", $user, $pwd);
|
|
if (!($conn)) { echo "Pas de connexion"; }
|
|
$rs = odbc_exec($conn, $request);
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = odbc_fetch_array($rs)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
}
|
|
function Invoke_Entry01($request){
|
|
$user = "infra";
|
|
$pwd = decypher("entry01");
|
|
$server = "dun-sup-entry01:3306";
|
|
$database = "infra";
|
|
$conn = new mysqli($server, $user, $pwd, $database);
|
|
$rs = $conn->query($request);
|
|
$answer = [];
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = mysqli_fetch_array($rs, MYSQLI_ASSOC)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
}
|
|
function Invoke_WebInfraTools($request){
|
|
$user = "admin";
|
|
$pwd = decypher("web-infra-tools");
|
|
$server = "dun-sup-s2entry.armony.net:3306";
|
|
$database = "webinfratools";
|
|
$conn = new mysqli($server, $user, $pwd, $database);
|
|
$rs = $conn->query($request);
|
|
$answer = [];
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = mysqli_fetch_array($rs, MYSQLI_ASSOC)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
}
|
|
function Invoke_Infra($request){
|
|
error_reporting(E_ALL ^ E_WARNING);
|
|
$user = "INFRA_dbo";
|
|
$pwd = decypher("infra");
|
|
$server = "DUN-PRD-R1MSSQL.armony.net\PRD";
|
|
$database = "INFRA";
|
|
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
|
|
if (!($conn)) { echo "Pas de connexion"; }
|
|
$rs = odbc_exec($conn, $request);
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = odbc_fetch_array($rs)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
else {
|
|
if ($rs) { return "OK"; }
|
|
else { error_reporting(E_ALL); return "ERROR : " . odbc_errormsg($conn); }
|
|
}
|
|
}
|
|
function Invoke_WSinfra($request){
|
|
error_reporting(E_ALL ^ E_WARNING);
|
|
$user = "WSINFRA_ADMIN";
|
|
$pwd = decypher("wsinfraDB");
|
|
$server = "DUN-PRD-R1MSSQL.armony.net\PRD";
|
|
$database = "WSINFRA";
|
|
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
|
|
if (!($conn)) { echo "Pas de connexion"; }
|
|
$rs = odbc_exec($conn, $request);
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = odbc_fetch_array($rs)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
else {
|
|
if ($rs) { return "OK"; }
|
|
else { error_reporting(E_ALL); return "ERROR : " . odbc_errormsg($conn); }
|
|
}
|
|
}
|
|
function Invoke_aixcmdb($request){
|
|
error_reporting(E_ALL ^ E_WARNING);
|
|
$conn_string = "DRIVER={IBM DB2 ODBC DRIVER};"
|
|
. "DATABASE=AIXCMDB; "
|
|
. "HOSTNAME=db2_aixcmdb.appliarmony.net;"
|
|
. "PORT=50000; "
|
|
. "PROTOCOL=TCPIP; "
|
|
. "UID=aixcmdb;"
|
|
. "AUTHENTICATION=SERVER;"
|
|
. "PWD=" . decypher('aixcmdb') . ";";
|
|
$conn = odbc_connect($conn_string, "", "");
|
|
if (!($conn)) { echo "Pas de connexion"; }
|
|
$rs = odbc_exec($conn, $request);
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = odbc_fetch_array($rs)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
else {
|
|
if ($rs) { return "OK"; }
|
|
else { error_reporting(E_ALL); return "ERROR : " . odbc_errormsg($conn); }
|
|
}
|
|
}
|
|
function Invoke_zabbix($request){
|
|
$user = "patrick";
|
|
$pwd = decypher("zabbix");
|
|
$server = "aztprdzabbix52.armony.net:3306";
|
|
$database = "zabbix";
|
|
$conn = new mysqli($server, $user, $pwd, $database);
|
|
$rs = $conn->query($request);
|
|
$answer = [];
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = mysqli_fetch_array($rs, MYSQLI_ASSOC)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
}
|
|
function Invoke_glpi($request){
|
|
$user = "glpi_lect_seule";
|
|
$pwd = decypher("glpi");
|
|
$server = "mys_glpi_prod.appliarmony.net:3306";
|
|
$database = "glpi";
|
|
$conn = new mysqli($server, $user, $pwd, $database);
|
|
$rs = $conn->query($request);
|
|
$answer = [];
|
|
if (instr(strtoupper($request), "SELECT")) {
|
|
while ($row = mysqli_fetch_array($rs, MYSQLI_ASSOC)) { $answer[] = $row; }
|
|
}
|
|
if (isset($answer)) { return $answer; }
|
|
}
|
|
|
|
// ---------- CONSTANTS & common ----------
|
|
$BaseUrl = "https://".$_SERVER['SERVER_NAME'];
|
|
$root = $_SERVER['DOCUMENT_ROOT'];
|
|
$bdnuss = "http://web-bdnuss-sys-dev.appliarmony.net";
|
|
$opwsinf = "https://wsopinf.appliarmony.net";
|
|
$zabbixOTUrl = 'https://web-zabbix.process.dkm/zabbix/api_jsonrpc.php';
|
|
$zabbixITUrl = 'https://web-zabbix02.appliarmony.net/zabbix/api_jsonrpc.php';
|
|
$glpiUrl = 'https://web-glpi-aim.process.dkm/glpi/apirest.php';
|
|
|
|
// Servers
|
|
$dcArmony = "dun-dom-s1dcb";
|
|
$dcADArmony = "dun-dom-s1adinf.adarmony.net";
|
|
$uxDNS = "dun-com-uxdns01";
|
|
$sSCOM = "dun-prd-x1scom";
|
|
$sVMM = "dun-sup-s1vmmsv";
|
|
|
|
// Credentials
|
|
$ILOcreds = "Administrator:".decypher("ilo");
|
|
$zabbixOTToken = '697132149e1e17058abe455cce7d45e18759539962185a5ea689445b271328ed';
|
|
$zabbixITToken = '0551c017d82b00abcf7e0222867731c9a6fb82a276f16cab9a38f077d61d4ebd';
|
|
$glpiAppToken = '0Cearpj5pRyCVj4hE7muZmaEgJp8uwbq84fYKlHa';
|
|
$glpiUserToken = 'iorbtVjXpwKoo2woYBu1UmZmGTq2xp64CdLtfgkn';
|
|
|
|
// Identity & Cookie
|
|
/* ---------- Detect client ---------- */
|
|
function detect_client_name(): string
|
|
{
|
|
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
|
|
$ua_l = strtolower($ua);
|
|
|
|
// Tokens explicites
|
|
$map = [
|
|
'powershell' => ['powershell', 'windowspowershell', 'invoke-webrequest'],
|
|
'curl' => ['curl/'],
|
|
'wget' => ['wget/'],
|
|
'python' => ['python-requests', 'urllib', 'python/'],
|
|
'postman' => ['postmanruntime'],
|
|
'go' => ['go-http-client'],
|
|
'nodejs' => ['node-fetch', 'axios/', 'undici', 'node.js', 'nodejs'],
|
|
'java' => ['java/', 'apache-httpclient/'],
|
|
'php' => ['php/', 'guzzlehttp/'],
|
|
];
|
|
foreach ($map as $name => $needles) {
|
|
foreach ($needles as $n) {
|
|
if ($n !== '' && str_contains($ua_l, $n)) return $name;
|
|
}
|
|
}
|
|
|
|
// Heuristique “script Mozilla sans en-têtes modernes”
|
|
$hasMozilla = stripos($ua, 'Mozilla/') !== false;
|
|
$hasSecFetch = isset($_SERVER['HTTP_SEC_FETCH_MODE']) || isset($_SERVER['HTTP_SEC_FETCH_SITE']) || isset($_SERVER['HTTP_SEC_FETCH_DEST']);
|
|
$hasSecCH = isset($_SERVER['HTTP_SEC_CH_UA']) || isset($_SERVER['HTTP_SEC_CH_UA_PLATFORM']);
|
|
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
|
|
$looksLikeScriptAccept = (trim($accept) === '' || $accept === '*/*');
|
|
if ($hasMozilla && !$hasSecFetch && !$hasSecCH && $looksLikeScriptAccept) return 'powershell';
|
|
|
|
return ($ua === '') ? 'shell' : 'browser';
|
|
}
|
|
function isBrowser(): bool
|
|
{
|
|
$client = detect_client_name();
|
|
if ($client !== 'browser') return false;
|
|
$hasSecFetch = isset($_SERVER['HTTP_SEC_FETCH_MODE']) || isset($_SERVER['HTTP_SEC_FETCH_SITE']) || isset($_SERVER['HTTP_SEC_FETCH_DEST']);
|
|
$hasSecCH = isset($_SERVER['HTTP_SEC_CH_UA']) || isset($_SERVER['HTTP_SEC_CH_UA_PLATFORM']);
|
|
return $hasSecFetch || $hasSecCH;
|
|
}
|
|
|
|
/* ---------- Identity & cookie ---------- */
|
|
function Set_Cookie() {
|
|
$cookieName = 'UserInfo';
|
|
$cookieLife = 86400 * 365;
|
|
$cookieDomain = '.appliarmony.net';
|
|
$secureFlag = true;
|
|
$httpOnly = true;
|
|
$sameSite = 'Lax';
|
|
|
|
$now = date('Y-m-d H:i:s');
|
|
|
|
// IP client (XFF -> fallback REMOTE_ADDR)
|
|
$ip = '';
|
|
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
|
$parts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
|
$cand = trim($parts[0]);
|
|
if (filter_var($cand, FILTER_VALIDATE_IP)) $ip = $cand;
|
|
}
|
|
if (!$ip && !empty($_SERVER['REMOTE_ADDR'])) $ip = $_SERVER['REMOTE_ADDR'];
|
|
|
|
// REMOTE_USER ?
|
|
$user = $_SERVER['REMOTE_USER'] ?? null;
|
|
$hasUser = !empty($user);
|
|
|
|
// Cookie existant
|
|
$cookie = [];
|
|
if (!empty($_COOKIE[$cookieName])) {
|
|
$decoded = json_decode($_COOKIE[$cookieName], true);
|
|
if (is_array($decoded)) $cookie = $decoded;
|
|
}
|
|
|
|
// Si pas d'user → classer le client (curl/pwsh/…/Anonymous)
|
|
if (!$hasUser) {
|
|
// même logique que detect_client_name() pour rester cohérent
|
|
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
|
|
$ua_l = strtolower($ua);
|
|
|
|
$map = [
|
|
'powershell' => ['powershell','windowspowershell','invoke-webrequest'],
|
|
'curl' => ['curl/'],
|
|
'wget' => ['wget/'],
|
|
'python' => ['python-requests','urllib','python/'],
|
|
'postman' => ['postmanruntime'],
|
|
'go' => ['go-http-client'],
|
|
'nodejs' => ['node-fetch','axios/','undici','node.js','nodejs'],
|
|
'java' => ['java/','apache-httpclient/'],
|
|
'php' => ['php/','guzzlehttp/'],
|
|
];
|
|
$user = 'Anonymous';
|
|
foreach ($map as $name => $needles) {
|
|
foreach ($needles as $n) { if ($n !== '' && str_contains($ua_l, $n)) { $user = $name; break 2; } }
|
|
}
|
|
if ($user === 'Anonymous') {
|
|
$hasMozilla = stripos($ua, 'Mozilla/') !== false;
|
|
$hasSecFetch = isset($_SERVER['HTTP_SEC_FETCH_MODE']) || isset($_SERVER['HTTP_SEC_FETCH_SITE']) || isset($_SERVER['HTTP_SEC_FETCH_DEST']);
|
|
$hasSecCH = isset($_SERVER['HTTP_SEC_CH_UA']) || isset($_SERVER['HTTP_SEC_CH_UA_PLATFORM']);
|
|
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
|
|
$looksLikeScriptAccept = (trim($accept) === '' || $accept === '*/*');
|
|
if ($hasMozilla && !$hasSecFetch && !$hasSecCH && $looksLikeScriptAccept) {
|
|
$user = 'powershell';
|
|
} elseif ($ua === '') {
|
|
$user = 'shell';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Écriture du cookie UNIQUEMENT si vrai REMOTE_USER
|
|
if ($hasUser) {
|
|
if (empty($cookie) || ($cookie['user'] ?? null) !== $user) {
|
|
$cookie = [ 'user'=>$user, 'ip'=>$ip, 'created'=>$now, 'last'=>$now ];
|
|
} else {
|
|
$cookie['ip'] = $ip ?: ($cookie['ip'] ?? '');
|
|
$cookie['last'] = $now;
|
|
}
|
|
if (!headers_sent()) {
|
|
setcookie($cookieName, json_encode($cookie), [
|
|
'expires' => time() + $cookieLife,
|
|
'path' => '/',
|
|
'domain' => $cookieDomain,
|
|
'secure' => $secureFlag,
|
|
'httponly' => $httpOnly,
|
|
'samesite' => $sameSite
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Publier VARIABLES (mutables) + constantes (compat)
|
|
$GLOBALS['CURRENT_USER'] = $user ?? 'Anonymous';
|
|
$GLOBALS['CURRENT_IP'] = $ip ?: ($_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN');
|
|
if (!defined('CURRENT_USER')) define('CURRENT_USER', $GLOBALS['CURRENT_USER']);
|
|
if (!defined('CURRENT_IP')) define('CURRENT_IP', $GLOBALS['CURRENT_IP']);
|
|
if (!defined('COOKIE_INFO')) define('COOKIE_INFO', $cookie);
|
|
}
|
|
|
|
/* ----- IMPORTANT : Call Set_Cookie() Now ----- */
|
|
Set_Cookie();
|
|
|
|
/* ----- If still Anonymous and real browser → try silent SSO ----- */
|
|
if (($GLOBALS['CURRENT_USER'] ?? 'Anonymous') === 'Anonymous' && isBrowser()) {
|
|
echo <<<HTML
|
|
<script>
|
|
(async function(){
|
|
try {
|
|
const res = await fetch('/auth/whoami.php', { method: 'GET', credentials: 'include' });
|
|
if (res.ok) {
|
|
const j = await res.json();
|
|
if (j && j.user) {
|
|
await fetch('/auth/set-whoami.php', {
|
|
method:'POST',
|
|
credentials:'include',
|
|
headers:{'Content-Type':'application/json'},
|
|
body: JSON.stringify({user:j.user})
|
|
});
|
|
}
|
|
}
|
|
} catch(e){}
|
|
})();
|
|
</script>
|
|
HTML;
|
|
}
|
|
|