From 4abb94b88c36393cb0d40ae0122feee638376bd7 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Thu, 23 Jul 2026 14:48:30 +0200 Subject: [PATCH] Started integrating external systems --- about.php | 2 +- asset.php | 32 ++++++++-- config.php-sample | 4 +- import.php | 133 ++++++++++++++++++++++++++++++++++++++++++ includes.php | 3 +- install/mysql.sql | 3 +- lang/de.php | 2 + lang/en.php | 2 + lib.php | 34 ++++++++--- lib/checkbox.js | 6 ++ lib/ext/cdb.php | 6 ++ lib/ext/logi.php | 6 ++ lib/ext/topdesk.php | 38 ++++++++++++ lib/ext/zabbix.php | 36 ++++++++++++ lib/extsys.php | 59 +++++++++++++++++++ lib/functions.php | 13 +---- login.php | 7 ++- tpl/about.tpl | 10 +++- tpl/assetview.tpl | 32 ++++++++++ tpl/import.tpl | 35 +++++++++++ tpl/importpfsense.tpl | 55 +++++++++++++++++ 21 files changed, 485 insertions(+), 33 deletions(-) create mode 100644 import.php create mode 100644 lib/checkbox.js create mode 100644 lib/ext/cdb.php create mode 100644 lib/ext/logi.php create mode 100644 lib/ext/topdesk.php create mode 100644 lib/ext/zabbix.php create mode 100644 lib/extsys.php create mode 100644 tpl/import.tpl create mode 100644 tpl/importpfsense.tpl diff --git a/about.php b/about.php index 94b98c9..e9f92c2 100644 --- a/about.php +++ b/about.php @@ -2,7 +2,7 @@ /***************************************************************************** IP Reg, a PHP/MySQL IPAM tool Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5) -Copyright (C) 2011-2023 Thomas Hooge +Copyright (C) 2011-2026 Thomas Hooge SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ diff --git a/asset.php b/asset.php index 7c7fd89..7f305c4 100644 --- a/asset.php +++ b/asset.php @@ -141,6 +141,7 @@ $sth = $dbh->prepare($sql); $sth->execute($p); $smarty->assign("assets", $sth->fetchAll()); +$smarty->assign("extlink", extlink_enabled()); $smarty->display("asset.tpl"); elseif ($action == ACT_ADD): @@ -192,24 +193,45 @@ $smarty->assign("nodes", $sth->fetchAll(PDO::FETCH_ASSOC)); // external systems // extlink_id // asset_id -// Type: enum('cdb','zabbix','topdesk', osticket +// Type: enum('cdb','zabbix','topdesk', osticket, loginventory // ID: extlink_refid int // extlink_uid string +// $smarty->assign('zabbix', print_r($config_ext['zabbix']['host'],true)); if ($config_ext['zabbix']['enabled']) { $smarty->assign("zabbix", true); $sql = "SELECT extlink_refid FROM extlink WHERE extlink_type='zabbix' AND asset_id=?"; $sth = $dbh->prepare($sql); $sth->execute([$id]); $refid = $sth->fetchColumn(); + // TODO fetch ext data here - //$zbx = new PDO('mysql:host='.$config_ext['zabbix']['host'].';dbname='.$config_ext['zabbix']['db'].';', $config_ext['zabbix']['user'], $config_ext['zabbix']['pass']); - //$zbx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - //$zbx->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + $zbxconn = false; + try { + $zbx = new PDO('mysql:host='.$config_ext['zabbix']['host'].';dbname='.$config_ext['zabbix']['db'].';', $config_ext['zabbix']['user'], $config_ext['zabbix']['pass']); + $zbx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $zbx->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + $zbxconn = true; + } catch (Exception $e) { + $refid = "not_connected:" . $e->getMessage(); + } + + if ($zbxconn) { + $sql = "SELECT host FROM hosts WHERE hostid=?"; + $sth = $zbx->prepare($sql); + $sth->execute([$refid]); + $zbx_hostname = $sth->fetchColumn(); + if ($zbx_hostname === false) { + $zbx_hostname = 'not found'; + } + $smarty->assign('zbx_hostname', $zbx_hostname); + $zbx = NULL; // close + } + $smarty->assign('refid', $refid); } - +$smarty->assign("extlink", extlink_enabled()); $smarty->display("assetview.tpl"); elseif ($action == ACT_EDIT): diff --git a/config.php-sample b/config.php-sample index 7934b6e..f28a8f9 100644 --- a/config.php-sample +++ b/config.php-sample @@ -2,7 +2,7 @@ /***************************************************************************** IP Reg, a PHP/MySQL IPAM tool Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5) -Copyright (C) 2011-2023 Thomas Hooge +Copyright (C) 2011-2026 Thomas Hooge SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ @@ -27,6 +27,7 @@ $config_lang_default = 'en'; // auth $config_auth_ldap = false; $config_ldap_host = array('localhost', 'otherhost.example.com'); +$config_ldap_scheme = 'ldap://' $config_ldap_port = 389; $config_ldap_v3 = true; $config_ldap_base_dn = 'ou=organizationalunit,dc=example,dc=com'; @@ -40,6 +41,7 @@ $config_ldap_bind_pass = 'secret'; $config_ext[] = [ 'zabbix' => ['enabled' => false, 'host' => 'localhost', + 'port' => 3306, 'db' => 'zabbix', 'user' => 'ipreg', 'pass' => 'topsecret'] diff --git a/import.php b/import.php new file mode 100644 index 0000000..00d3ff0 --- /dev/null +++ b/import.php @@ -0,0 +1,133 @@ +Add(print_r($_SESSION['pfimport'], true)); + unset($_SESSION['pfimport']); + $action = ACT_DEFAULT; + break; + + default: + $g_error->Add(submit_error($submit)); + $valid = FALSE; +} + +// ========== ACTIONS END ===================================================== + +$smarty->assign("scripts", 'checkbox.js'); +include("header.php"); + +if ($action == ACT_DEFAULT): +// ========== VARIANT: default behavior ======================================= + +$smarty->display("import.tpl"); + +elseif ($action == ACT_EDIT): +// ========== VARIANT: edit display options =================================== + +$smarty->assign("xmlfile",$_FILES['xmlfile']['name']); +$smarty->assign("xmlfiletype", $_FILES['xmlfile']['type']); +$smarty->assign("xmltmp", $_FILES['xmlfile']['tmp_name']); + +$uploadfile = '/var/www/html/ipreg/import/'. basename($_FILES['xmlfile']['tmp_name']); +if (! move_uploaded_file($_FILES['xmlfile']['tmp_name'], $uploadfile)) { + $smarty->display("import.tpl"); + $smarty->display('footer.tpl'); + exit; +} + +$xml = simplexml_load_file($uploadfile); +$conf_alias = $xml->xpath('/pfsense/aliases/alias'); +$alias = array(); +foreach ($conf_alias as $a) { + if ($a->type == 'host') { + $host = explode(' ', $a->address); + if (count($host) == 1) { + $alias[(string) $a->name] = $host[0]; + } + } +} + +$wanip = (string) $xml->xpath('/pfsense/interfaces/wan/ipaddr')[0]; + +$nat = $xml->xpath('/pfsense/nat/rule'); +$res = array(); +$ruleid = 0; +// for database checks +$sql = "SELECT COUNT(*) + FROM nat + JOIN node AS n1 ON nat.nat_ext=n1.node_id + JOIN node AS n2 ON nat.nat_int=n2.node_id + WHERE n1.node_ip=? AND n2.node_ip=?"; +$sth = $dbh->prepare($sql); +foreach ($nat as $n) { + if (! $n->destination->address) { + if ($n->destination->network == 'wanip') { + $nat_ext = ip2long($wanip); + } else { + $nat_ext = ip2long((string) $n->destination->network); + } + } else { + $nat_ext = ip2long((string) $n->destination->address); + }; + $nat_ext_port = (int) $n->destination->port; + $tgt = (string) $n->target; + if (array_key_exists($tgt, $alias)) { + $tgt = $alias[$tgt]; + } + $nat_int = ip2long($tgt); + $nat_int_port = (int) $n->{'local-port'}; + $description = (string) $n->descr; + + // check if data already exists + $sth->execute([long2ip($nat_ext), long2ip($nat_int)]); + $dupe = $sth->fetchColumn() == 0; + + $ruleid += 1; + $res[] = ['id' => $ruleid, + 'ext' => $nat_ext, + 'ext_port' => $nat_ext_port, + 'int' => $nat_int, + 'int_port' => $nat_int_port, + 'description' => $description, + 'dupe' => $dupe]; +} + +// store importdata for next selection step +$_SESSION['pfimport'] = $res; + +$smarty->assign("natlist", $res); + +$smarty->display("importpfsense.tpl"); + +else: +// ========== ERROR UNKNOWN VARIANT =========================================== + +echo "

Unknown function call: Please report to system development!

\n"; + +endif; // $action == ... +// ========== END OF VARIANTS ================================================= + +$smarty->display('footer.tpl'); diff --git a/includes.php b/includes.php index 5a0cee3..8c9bfb1 100644 --- a/includes.php +++ b/includes.php @@ -23,13 +23,12 @@ if (empty($_SESSION['suser_id'])) { // required config vars, may be overwritten later $config_auth_ldap = false; -$config_ext = array(); // connect to database $dbh = new PDO("mysql:host=$config_mysql_host;dbname=$config_mysql_dbname;charset=utf8", $config_mysql_username, $config_mysql_password); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); -include("lib.php"); +include('lib.php'); // $language = lang_getfrombrowser($config_lang, $config_lang_default); diff --git a/install/mysql.sql b/install/mysql.sql index b4fa5c1..3c2d530 100644 --- a/install/mysql.sql +++ b/install/mysql.sql @@ -54,10 +54,11 @@ CREATE TABLE cablevlan ( -- WIP -- Reference to external systems -- class 1=asset; per ext type different class-ids possible +-- TODO unique: asset_id, extlink_type, extlink_class CREATE TABLE extlink ( extlink_id int(10) NOT NULL AUTO_INCREMENT, asset_id int(10) NOT NULL, - extlink_type enum('cdb','zabbix', 'topdesk') NOT NULL DEFAULT 'cdb', + extlink_type enum('cdb','zabbix', 'topdesk', 'logi') NOT NULL DEFAULT 'cdb', extlink_class tinyint(4) NOT NULL DEFAULT 1, extlink_refid int(10) DEFAULT NULL, extlink_uid varchar(65) DEFAULT NULL, diff --git a/lang/de.php b/lang/de.php index dfe317d..461d4b0 100644 --- a/lang/de.php +++ b/lang/de.php @@ -243,6 +243,8 @@ $lang = array( 'lang_about_license_ext' => 'Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5)
Copyright (C) 2011-2023 Thomas Hooge

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.', 'lang_about_changelog' => 'Changelog (major changes only)', + 'lang_about_changelog_v10' => 'v0.10 (jul 2026)', + 'lang_about_changelog_v10_ext' => '- Switched to Smarty v4
- LDAP configuration for PHP v8', 'lang_about_changelog_v09' => 'v0.9 (mar 2023)', 'lang_about_changelog_v09_ext' => '- Changed database interface to PDO / prepared statements
- LDAP authentication
- User rights
- Improved internal menu system', 'lang_about_changelog_v08' => 'v0.8 (feb 2023)', diff --git a/lang/en.php b/lang/en.php index e654402..b30608c 100644 --- a/lang/en.php +++ b/lang/en.php @@ -243,6 +243,8 @@ $lang = array( 'lang_about_license_ext' => 'Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5)
Copyright (C) 2011-2023 Thomas Hooge

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.', 'lang_about_changelog' => 'Changelog (major changes only)', + 'lang_about_changelog_v10' => 'v0.10 (jul 2026)', + 'lang_about_changelog_v10_ext' => '- Switched to Smarty v4
- LDAP configuration for PHP v8', 'lang_about_changelog_v09' => 'v0.9 (mar 2023)', 'lang_about_changelog_v09_ext' => '- Changed database interface to PDO / prepared statements
- LDAP authentication
- User rights
- Improved internal menu system', 'lang_about_changelog_v08' => 'v0.8 (feb 2023)', diff --git a/lib.php b/lib.php index 91e2211..aed885d 100644 --- a/lib.php +++ b/lib.php @@ -2,7 +2,7 @@ /***************************************************************************** IP Reg, a PHP/MySQL IPAM tool Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5) -Copyright (C) 2011-2023 Thomas Hooge +Copyright (C) 2011-2026 Thomas Hooge SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ @@ -30,14 +30,14 @@ define ('ACT_PASSWORD', 14); // ========== GLOBAL PAGE START CODE ========================================== // global version string -$config_version = 'v0.9.1'; +$config_version = 'v0.10'; // available languages $config_lang = array('de', 'en'); include("lib/functions.php"); -require_once('smarty3/Smarty.class.php'); +require_once('smarty4/Smarty.class.php'); $smarty = new Smarty(); $smarty->template_dir = 'tpl'; $smarty->compile_dir = 'tpl_c'; @@ -205,7 +205,7 @@ function submit_error($action) { return sprintf('The action "%s" is unknown. It is probably a program error.
Please inform your administrator of the exact circumstances of how this situation came about.', strtoupper($action)); } -// ========== DATABASE FUCTIONS =============================================== +// ========== DATABASE FUNCTIONS ============================================== function db_load_enum($table, $column) { // returns array of enum-values as defined in database @@ -305,7 +305,13 @@ function db_get_options_zone($default = NULL) { return $options; } -// ========== MISC FUCTIONS =================================================== +// ========== MISC FUNCTIONS ================================================== + +function header_location($location) { + // redirect page + header('location:' . $location); + exit; +} function strip_mac($mac, $caps=true) { // strip mac address to 12 char string @@ -347,8 +353,18 @@ function write_mac($mac, $user_mac='xx:xx:xx:xx:xx:xx') { return $user_mac; } -function header_location($location) { - // redirect page - header('location:' . $location); - exit; +function extlink_enabled() { + // check if any link to external system is enabled + global $config_ext; + foreach ($config_ext as $xcfg) { + if (!array_key_exists('enabled', $xcfg)) { + // invalid configuration + // TODO Throw warning! + continue; + } + if ($xcfg['enabled']) { + return true; + } + } + return false; } diff --git a/lib/checkbox.js b/lib/checkbox.js new file mode 100644 index 0000000..3554084 --- /dev/null +++ b/lib/checkbox.js @@ -0,0 +1,6 @@ +function toggle(source) { + checkboxes = document.getElementsByName('rule'); + for(var i=0, n=checkboxes.length; iassign('zabbix', print_r($config_ext['zabbix']['host'],true)); +if ($config_ext['zabbix']['enabled']) { + $smarty->assign("zabbix", true); + $sql = "SELECT extlink_refid FROM extlink WHERE extlink_type='zabbix' AND asset_id=?"; + $sth = $dbh->prepare($sql); + $sth->execute([$id]); + $refid = $sth->fetchColumn(); + + // TODO fetch ext data here + $zbxconn = false; + try { + $zbx = new PDO('mysql:host='.$config_ext['zabbix']['host'].';dbname='.$config_ext['zabbix']['db'].';', $config_ext['zabbix']['user'], $config_ext['zabbix']['pass']); + $zbx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $zbx->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + $zbxconn = true; + } catch (Exception $e) { + $refid = "not_connected:" . $e->getMessage(); + } + + if ($zbxconn) { + $sql = "SELECT host FROM hosts WHERE hostid=?"; + $sth = $zbx->prepare($sql); + $sth->execute([$refid]); + $zbx_hostname = $sth->fetchColumn(); + $smarty->assign('zbx_hostname', $zbx_hostname); + $zbx = NULL; // close + } + +} diff --git a/lib/extsys.php b/lib/extsys.php new file mode 100644 index 0000000..7eeff2d --- /dev/null +++ b/lib/extsys.php @@ -0,0 +1,59 @@ +name = 'Computerdatenbank'; + cdb_init($dbconfig); + break; + 'logi': + $this->name = 'Loginventory'; + logi_init($dbconfig); + break; + 'topdesk': + $this->name = 'Topdesk'; + tdesk_init($dbconfig); + break; + 'zabbix': + $this->name = 'Zabbix'; + zbx_init($dbconfig); + break; + default: + throw new Exception('Invalid xtype'); + } + } + + private function mariadb_connect() { + return false; + } + + private function mssql_connect() { + return false; + } + + private function cdb_init() { + mariadb_connect(); + } + + private function logi_init() { + mssql_connect(); + } + + private function tdesk_init() { + mssql_connect(); + } + + private function zbx_init() { + mariadb_connect(); + } + +} diff --git a/lib/functions.php b/lib/functions.php index 1f6dafe..0158f01 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -2,7 +2,7 @@ /***************************************************************************** IP Reg, a PHP/MySQL IPAM tool Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5) -Copyright (C) 2011-2023 Thomas Hooge +Copyright (C) 2011-2026 Thomas Hooge SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ @@ -11,22 +11,15 @@ SPDX-License-Identifier: GPL-3.0-or-later function sanitize($input) { global $dblink; - // trim whitespaces $input = @trim($input); - - // magic quotes enabled? - if(get_magic_quotes_gpc()) { - // strip slashes - $input = stripslashes($input); - } + $input = stripslashes($input); // convert to utf-8 iconv("UTF-8", "UTF-8", $input); // convert special chars - $input = htmlentities($input,ENT_QUOTES,'UTF-8'); + $input = htmlentities($input, ENT_QUOTES, 'UTF-8'); - // and return return $input; } diff --git a/login.php b/login.php index 4315fc8..544048a 100644 --- a/login.php +++ b/login.php @@ -2,7 +2,7 @@ /***************************************************************************** IP Reg, a PHP/MySQL IPAM tool Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5) -Copyright (C) 2011-2023 Thomas Hooge +Copyright (C) 2011-2026 Thomas Hooge SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ @@ -25,11 +25,11 @@ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); include("lib.php"); // for smarty e.g. - // ========== LOGIN FUNCTIONS ================================================= function check_ldap_bind($user_name, $user_pass) { global $config_ldap_host; + global $config_ldap_scheme; global $config_ldap_port; global $config_ldap_base_dn; global $config_ldap_bind_dn; @@ -37,7 +37,8 @@ function check_ldap_bind($user_name, $user_pass) { global $config_ldap_login_attr; $ldap_conn = NULL; foreach ($config_ldap_host as $server) { - if ($ldap_conn = ldap_connect($server, $config_ldap_port)) { + $ldap_uri = $config_ldap_scheme . $server . ':' . $config_ldap_port; + if ($ldap_conn = ldap_connect($ldap_uri)) { if ($res = ldap_bind($ldap_conn, $config_ldap_bind_dn, $config_ldap_bind_pass)) { ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, 0); ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3); diff --git a/tpl/about.tpl b/tpl/about.tpl index a066407..9f46a06 100644 --- a/tpl/about.tpl +++ b/tpl/about.tpl @@ -20,7 +20,7 @@ {$lang_about_projectpage} - https://git.piratenpartei-sh.de/thooge/ipreg + https://git.hoogi.de/thooge/ipreg @@ -83,6 +83,14 @@   + + + {$lang_about_changelog_v10} + + + {$lang_about_changelog_v10_ext} + + {$lang_about_changelog_v09} diff --git a/tpl/assetview.tpl b/tpl/assetview.tpl index a4a417a..aaa9306 100644 --- a/tpl/assetview.tpl +++ b/tpl/assetview.tpl @@ -119,3 +119,35 @@ + +{if $extlink} + + + + + + + +
+ External Links +
In development
+{/if} + + +{if $refid} + + + + + + + + + +
+ Externe Daten + +   +
ZabbixHostID = {$refid}, {$zbx_hostname} +
+{/if} diff --git a/tpl/import.tpl b/tpl/import.tpl new file mode 100644 index 0000000..14b2024 --- /dev/null +++ b/tpl/import.tpl @@ -0,0 +1,35 @@ + + + + + +
+ + Import + +   +
+ + + + + +
+ IP Reg import module +
+ + + + + + + +
+ Import pfsense NAT settings + +
+ + pfSense Konfigurationsdatei: + +
+
diff --git a/tpl/importpfsense.tpl b/tpl/importpfsense.tpl new file mode 100644 index 0000000..7c78bfe --- /dev/null +++ b/tpl/importpfsense.tpl @@ -0,0 +1,55 @@ + + + + + +
+ + Import + +   +
+ + + + + +
+ IP Reg import module +
+ + +

+ + + + + + + + + +
+ Configuration file + + {$xmlfile} of type {$xmlfiletype} ({$xmltmp}) +
+ Data + + + + + +{foreach item=nat from=$natlist} + + + + + + + +{/foreach} +
FromToDescription
{$nat.ext|long2ip}:{$nat.ext_port}{$nat.int|long2ip}:{$nat.int_port}{$nat.description}{$nat.dupe}
+ +
+