From 4302cbce58eedeff04a68de6e7e49007677dc473 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 18 Sep 2023 18:10:43 +0200 Subject: [PATCH 01/20] 11830 adding package preparation for rpm gotty --- extras/pandora_gotty/.gitattributes | 1 + extras/pandora_gotty/.gitignore | 1 + extras/pandora_gotty/Dockerfile | 8 ++++ extras/pandora_gotty/build.sh | 12 ++++++ extras/pandora_gotty/build_docker.sh | 2 + extras/pandora_gotty/pandora_gotty.spec | 41 +++++++++++++++++++ extras/pandora_gotty/src/.gitignore | 1 + extras/pandora_gotty/src/pandora_gotty | 3 ++ .../pandora_gotty/src/pandora_gotty_ssh.conf | 4 ++ .../src/pandora_gotty_telnet.conf | 4 ++ 10 files changed, 77 insertions(+) create mode 100644 extras/pandora_gotty/.gitattributes create mode 100644 extras/pandora_gotty/.gitignore create mode 100644 extras/pandora_gotty/Dockerfile create mode 100755 extras/pandora_gotty/build.sh create mode 100755 extras/pandora_gotty/build_docker.sh create mode 100644 extras/pandora_gotty/pandora_gotty.spec create mode 100644 extras/pandora_gotty/src/.gitignore create mode 100755 extras/pandora_gotty/src/pandora_gotty create mode 100644 extras/pandora_gotty/src/pandora_gotty_ssh.conf create mode 100644 extras/pandora_gotty/src/pandora_gotty_telnet.conf diff --git a/extras/pandora_gotty/.gitattributes b/extras/pandora_gotty/.gitattributes new file mode 100644 index 0000000000..ca0a55fe2e --- /dev/null +++ b/extras/pandora_gotty/.gitattributes @@ -0,0 +1 @@ +src/pandora_gotty filter=lfs diff=lfs merge=lfs -text diff --git a/extras/pandora_gotty/.gitignore b/extras/pandora_gotty/.gitignore new file mode 100644 index 0000000000..8d5bedc36a --- /dev/null +++ b/extras/pandora_gotty/.gitignore @@ -0,0 +1 @@ +*.rpm \ No newline at end of file diff --git a/extras/pandora_gotty/Dockerfile b/extras/pandora_gotty/Dockerfile new file mode 100644 index 0000000000..f708a6f4a7 --- /dev/null +++ b/extras/pandora_gotty/Dockerfile @@ -0,0 +1,8 @@ +FROM rockylinux:8 + +RUN dnf install -y rpm-build rpmdevtools +RUN rpmdev-setuptree +RUN mkdir /root/pandora_gotty +WORKDIR /root/pandora_gotty + +#CMD bash build.sh diff --git a/extras/pandora_gotty/build.sh b/extras/pandora_gotty/build.sh new file mode 100755 index 0000000000..e3be2587ca --- /dev/null +++ b/extras/pandora_gotty/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +VERSION=$(grep '%define version' pandora_gotty.spec | awk '{print $3}') +mkdir -p pandora_gotty-${VERSION} +cp src/* pandora_gotty-${VERSION}/ +tar -cvzf pandora_gotty-${VERSION}.tar.gz pandora_gotty-${VERSION}/* +mv pandora_gotty-${VERSION}.tar.gz ${HOME}/rpmbuild/SOURCES/ +rm -rf ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty* +rpmbuild -ba pandora_gotty.spec +rm -rf pandora_gotty-${VERSION} +mv ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty* . + diff --git a/extras/pandora_gotty/build_docker.sh b/extras/pandora_gotty/build_docker.sh new file mode 100755 index 0000000000..cc2c81caa3 --- /dev/null +++ b/extras/pandora_gotty/build_docker.sh @@ -0,0 +1,2 @@ +docker build -t pandora_gotty_builder . +docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder /root/pandora_gotty/build.sh \ No newline at end of file diff --git a/extras/pandora_gotty/pandora_gotty.spec b/extras/pandora_gotty/pandora_gotty.spec new file mode 100644 index 0000000000..5b0bde5d8e --- /dev/null +++ b/extras/pandora_gotty/pandora_gotty.spec @@ -0,0 +1,41 @@ +%define name pandora_gotty +%define version 1.0 +%define release 1%{?dist} +Summary: pandora_gptty for Pandora FMS +Name: %{name} +Version: %{version} +Release: %{release} +License: GPL +Vendor: PandoraFMS +Source0: %{name}-%{version}.tar.gz +URL: https://pandorafms.com +Group: System/Monitoring +Packager: PandoraFMS +BuildArch: x86_64 +Provides: %{name}-%{version} + +%description +pandora_gotty for Pandora FMS. + +%prep +%setup -q + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/%{_bindir} +mkdir -p %{buildroot}/etc/pandora_gotty/ +cp %{name} $RPM_BUILD_ROOT/%{_bindir} +cp pandora_gotty_ssh.conf %{buildroot}/etc/pandora_gotty/ +cp pandora_gotty_telnet.conf %{buildroot}/etc/pandora_gotty/ +%clean +rm -Rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%config(noreplace) /etc/pandora_gotty/pandora_gotty_ssh.conf +%config(noreplace) /etc/pandora_gotty/pandora_gotty_telnet.conf +%{_bindir}/%{name} + +%changelog +* Mon Sep 18 2023 PandoraFMS - 1.0-1 +- Initial RPM release diff --git a/extras/pandora_gotty/src/.gitignore b/extras/pandora_gotty/src/.gitignore new file mode 100644 index 0000000000..423058ca29 --- /dev/null +++ b/extras/pandora_gotty/src/.gitignore @@ -0,0 +1 @@ +*rpm \ No newline at end of file diff --git a/extras/pandora_gotty/src/pandora_gotty b/extras/pandora_gotty/src/pandora_gotty new file mode 100755 index 0000000000..dc71d46eaf --- /dev/null +++ b/extras/pandora_gotty/src/pandora_gotty @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3758eddb64db79c6ea1dac4cb200ee8ec86ef3f51723dad5be4365a1315b952b +size 13642854 diff --git a/extras/pandora_gotty/src/pandora_gotty_ssh.conf b/extras/pandora_gotty/src/pandora_gotty_ssh.conf new file mode 100644 index 0000000000..b00ca51e4b --- /dev/null +++ b/extras/pandora_gotty/src/pandora_gotty_ssh.conf @@ -0,0 +1,4 @@ +#to be fill +lkdslkds +sdjkfhasjdf +kdsjfslkjdhfa \ No newline at end of file diff --git a/extras/pandora_gotty/src/pandora_gotty_telnet.conf b/extras/pandora_gotty/src/pandora_gotty_telnet.conf new file mode 100644 index 0000000000..9aac8c73d0 --- /dev/null +++ b/extras/pandora_gotty/src/pandora_gotty_telnet.conf @@ -0,0 +1,4 @@ +#to be fill +dlksdlkfjs +sldjfslkjdf +kjdfhksjhdkjlfsh \ No newline at end of file From 7d09ed7503f9a10c33b09df1f0bd9d4c6dc7a8f4 Mon Sep 17 00:00:00 2001 From: rafael Date: Tue, 19 Sep 2023 10:44:41 +0200 Subject: [PATCH 02/20] 11830 changes on pandora_gotty packages --- .../{Dockerfile => Dockerfile-RPM} | 0 extras/pandora_gotty/build_all_docker.sh | 3 ++ extras/pandora_gotty/build_docker.sh | 2 -- .../pandora_gotty/{build.sh => build_rpm.sh} | 3 +- extras/pandora_gotty/pandora_gotty.spec | 6 ++-- extras/pandora_gotty/src/pandora_gotty.conf | 36 +++++++++++++++++++ .../pandora_gotty/src/pandora_gotty_ssh.conf | 4 --- .../src/pandora_gotty_telnet.conf | 4 --- 8 files changed, 43 insertions(+), 15 deletions(-) rename extras/pandora_gotty/{Dockerfile => Dockerfile-RPM} (100%) create mode 100755 extras/pandora_gotty/build_all_docker.sh delete mode 100755 extras/pandora_gotty/build_docker.sh rename extras/pandora_gotty/{build.sh => build_rpm.sh} (98%) create mode 100644 extras/pandora_gotty/src/pandora_gotty.conf delete mode 100644 extras/pandora_gotty/src/pandora_gotty_ssh.conf delete mode 100644 extras/pandora_gotty/src/pandora_gotty_telnet.conf diff --git a/extras/pandora_gotty/Dockerfile b/extras/pandora_gotty/Dockerfile-RPM similarity index 100% rename from extras/pandora_gotty/Dockerfile rename to extras/pandora_gotty/Dockerfile-RPM diff --git a/extras/pandora_gotty/build_all_docker.sh b/extras/pandora_gotty/build_all_docker.sh new file mode 100755 index 0000000000..e4da1a7558 --- /dev/null +++ b/extras/pandora_gotty/build_all_docker.sh @@ -0,0 +1,3 @@ +#Build RPM +docker build -t pandora_gotty_builder -f Dockerfile-RPM . +docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder /root/pandora_gotty/build_rpm.sh \ No newline at end of file diff --git a/extras/pandora_gotty/build_docker.sh b/extras/pandora_gotty/build_docker.sh deleted file mode 100755 index cc2c81caa3..0000000000 --- a/extras/pandora_gotty/build_docker.sh +++ /dev/null @@ -1,2 +0,0 @@ -docker build -t pandora_gotty_builder . -docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder /root/pandora_gotty/build.sh \ No newline at end of file diff --git a/extras/pandora_gotty/build.sh b/extras/pandora_gotty/build_rpm.sh similarity index 98% rename from extras/pandora_gotty/build.sh rename to extras/pandora_gotty/build_rpm.sh index e3be2587ca..f257f6ae57 100755 --- a/extras/pandora_gotty/build.sh +++ b/extras/pandora_gotty/build_rpm.sh @@ -1,5 +1,5 @@ #!/bin/bash - +#RPM VERSION=$(grep '%define version' pandora_gotty.spec | awk '{print $3}') mkdir -p pandora_gotty-${VERSION} cp src/* pandora_gotty-${VERSION}/ @@ -10,3 +10,4 @@ rpmbuild -ba pandora_gotty.spec rm -rf pandora_gotty-${VERSION} mv ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty* . +#DEB \ No newline at end of file diff --git a/extras/pandora_gotty/pandora_gotty.spec b/extras/pandora_gotty/pandora_gotty.spec index 5b0bde5d8e..005dfd945f 100644 --- a/extras/pandora_gotty/pandora_gotty.spec +++ b/extras/pandora_gotty/pandora_gotty.spec @@ -25,15 +25,13 @@ rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/%{_bindir} mkdir -p %{buildroot}/etc/pandora_gotty/ cp %{name} $RPM_BUILD_ROOT/%{_bindir} -cp pandora_gotty_ssh.conf %{buildroot}/etc/pandora_gotty/ -cp pandora_gotty_telnet.conf %{buildroot}/etc/pandora_gotty/ +cp pandora_gotty.conf %{buildroot}/etc/pandora_gotty/ %clean rm -Rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) -%config(noreplace) /etc/pandora_gotty/pandora_gotty_ssh.conf -%config(noreplace) /etc/pandora_gotty/pandora_gotty_telnet.conf +%config(noreplace) /etc/pandora_gotty/pandora_gotty.conf %{_bindir}/%{name} %changelog diff --git a/extras/pandora_gotty/src/pandora_gotty.conf b/extras/pandora_gotty/src/pandora_gotty.conf new file mode 100644 index 0000000000..01a037dd72 --- /dev/null +++ b/extras/pandora_gotty/src/pandora_gotty.conf @@ -0,0 +1,36 @@ +//Pandora Gotty + +// [bool] Permit clients to write to the TTY +permit_write = true + +// [bool] Enable basic authentication +enable_basic_auth = true + +// [string] Default username and password of basic authentication (user:pass) +// To enable basic authentication, set `true` to `enable_basic_auth` +credential = "pandora:Pandor4!" + +// [bool] Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB) +permit_arguments = true + +// [bool] Enable random URL generation +enable_random_url = true + +// [int] Default length of random strings appended to URL +// To enable random URL generation, set `true` to `enable_random_url` +random_url_length = 32 + +// [bool] Enable TLS/SSL +// enable_tls = false + +// [string] Default TLS certificate file path +// tls_crt_file = "~/.gotty.crt" + +// [string] Default TLS key file path +// tls_key_file = "~/.gotty.key" + +// [bool] Enable client certificate authentication +// enable_tls_client_auth = false + +// [string] Certificate file of CA for client certificates +// tls_ca_crt_file = "~/.gotty.ca.crt" \ No newline at end of file diff --git a/extras/pandora_gotty/src/pandora_gotty_ssh.conf b/extras/pandora_gotty/src/pandora_gotty_ssh.conf deleted file mode 100644 index b00ca51e4b..0000000000 --- a/extras/pandora_gotty/src/pandora_gotty_ssh.conf +++ /dev/null @@ -1,4 +0,0 @@ -#to be fill -lkdslkds -sdjkfhasjdf -kdsjfslkjdhfa \ No newline at end of file diff --git a/extras/pandora_gotty/src/pandora_gotty_telnet.conf b/extras/pandora_gotty/src/pandora_gotty_telnet.conf deleted file mode 100644 index 9aac8c73d0..0000000000 --- a/extras/pandora_gotty/src/pandora_gotty_telnet.conf +++ /dev/null @@ -1,4 +0,0 @@ -#to be fill -dlksdlkfjs -sldjfslkjdf -kjdfhksjhdkjlfsh \ No newline at end of file From 951cfa0863f5c10abec2282b36262c4c3669be28 Mon Sep 17 00:00:00 2001 From: rafael Date: Tue, 19 Sep 2023 11:56:15 +0200 Subject: [PATCH 03/20] 11830 finish builder for rpm and deb --- extras/pandora_gotty/.gitignore | 3 ++- extras/pandora_gotty/Dockerfile-deb | 6 ++++++ extras/pandora_gotty/README.md | 1 + extras/pandora_gotty/build_all_docker.sh | 12 ++++++++++-- extras/pandora_gotty/build_deb.sh | 15 +++++++++++++++ extras/pandora_gotty/build_rpm.sh | 3 +-- extras/pandora_gotty/deb/.gitignore | 3 +++ .../deb/pandora_gotty/DEBIAN/changelog | 5 +++++ .../deb/pandora_gotty/DEBIAN/control | 9 +++++++++ 9 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 extras/pandora_gotty/Dockerfile-deb create mode 100644 extras/pandora_gotty/README.md create mode 100755 extras/pandora_gotty/build_deb.sh create mode 100644 extras/pandora_gotty/deb/.gitignore create mode 100644 extras/pandora_gotty/deb/pandora_gotty/DEBIAN/changelog create mode 100644 extras/pandora_gotty/deb/pandora_gotty/DEBIAN/control diff --git a/extras/pandora_gotty/.gitignore b/extras/pandora_gotty/.gitignore index 8d5bedc36a..db388678f7 100644 --- a/extras/pandora_gotty/.gitignore +++ b/extras/pandora_gotty/.gitignore @@ -1 +1,2 @@ -*.rpm \ No newline at end of file +*.rpm +*.deb \ No newline at end of file diff --git a/extras/pandora_gotty/Dockerfile-deb b/extras/pandora_gotty/Dockerfile-deb new file mode 100644 index 0000000000..02a30a43d3 --- /dev/null +++ b/extras/pandora_gotty/Dockerfile-deb @@ -0,0 +1,6 @@ +FROM ubuntu:22.04 + +RUN apt-get update +RUN apt-get install -y dh-make debhelper build-essential +RUN mkdir /root/pandora_gotty +WORKDIR /root/pandora_gotty \ No newline at end of file diff --git a/extras/pandora_gotty/README.md b/extras/pandora_gotty/README.md new file mode 100644 index 0000000000..2e261c2e53 --- /dev/null +++ b/extras/pandora_gotty/README.md @@ -0,0 +1 @@ +To create the .deb and .rpm package need to hace docker installed on main system and execit `build_all_docker.sh` \ No newline at end of file diff --git a/extras/pandora_gotty/build_all_docker.sh b/extras/pandora_gotty/build_all_docker.sh index e4da1a7558..cb280999ba 100755 --- a/extras/pandora_gotty/build_all_docker.sh +++ b/extras/pandora_gotty/build_all_docker.sh @@ -1,3 +1,11 @@ #Build RPM -docker build -t pandora_gotty_builder -f Dockerfile-RPM . -docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder /root/pandora_gotty/build_rpm.sh \ No newline at end of file +docker build -t pandora_gotty_builder_rpm -f Dockerfile-RPM . || exit 1 +docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder_rpm /root/pandora_gotty/build_rpm.sh || exit 1 + +#Buikd DEB +docker build -t pandora_gotty_builder_deb -f Dockerfile-deb . || exit 1 +docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder_deb /root/pandora_gotty/build_deb.sh || exit 1 + +echo " - Done" +pwd +ls -l | grep -E "(\.deb|\.rpm)" \ No newline at end of file diff --git a/extras/pandora_gotty/build_deb.sh b/extras/pandora_gotty/build_deb.sh new file mode 100755 index 0000000000..483ab35076 --- /dev/null +++ b/extras/pandora_gotty/build_deb.sh @@ -0,0 +1,15 @@ +#!/bin/bash +#DEB +cd deb +VERSION=$(grep 'Version:' pandora_gotty/DEBIAN/control | awk '{print $2}') +mkdir -p pandora_gotty/usr/bin +mkdir -p pandora_gotty/etc/pandora_gotty +cp -a ../src/pandora_gotty pandora_gotty/usr/bin +cp -a ../src/pandora_gotty.conf pandora_gotty/etc/pandora_gotty +dpkg-deb --build pandora_gotty +mv pandora_gotty.deb ../ +rm -rf pandora_gotty/usr/ +rm -rf pandora_gotty/etc/ +cd .. +mv pandora_gotty.deb pandora_gotty_${VERSION}.deb +chmod 777 pandora_gotty_${VERSION}.deb diff --git a/extras/pandora_gotty/build_rpm.sh b/extras/pandora_gotty/build_rpm.sh index f257f6ae57..64a43fa099 100755 --- a/extras/pandora_gotty/build_rpm.sh +++ b/extras/pandora_gotty/build_rpm.sh @@ -9,5 +9,4 @@ rm -rf ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty* rpmbuild -ba pandora_gotty.spec rm -rf pandora_gotty-${VERSION} mv ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty* . - -#DEB \ No newline at end of file +chmod 777 *.rpm \ No newline at end of file diff --git a/extras/pandora_gotty/deb/.gitignore b/extras/pandora_gotty/deb/.gitignore new file mode 100644 index 0000000000..92a9f94179 --- /dev/null +++ b/extras/pandora_gotty/deb/.gitignore @@ -0,0 +1,3 @@ +*.deb +**/usr +**/etc diff --git a/extras/pandora_gotty/deb/pandora_gotty/DEBIAN/changelog b/extras/pandora_gotty/deb/pandora_gotty/DEBIAN/changelog new file mode 100644 index 0000000000..5d7e7f2ab6 --- /dev/null +++ b/extras/pandora_gotty/deb/pandora_gotty/DEBIAN/changelog @@ -0,0 +1,5 @@ +pandora_gotty (1.0-1) stable; urgency=low + + * Initial release. + + -- PandoraFMS Mon, 18 Sep 2023 00:00:00 +0000 \ No newline at end of file diff --git a/extras/pandora_gotty/deb/pandora_gotty/DEBIAN/control b/extras/pandora_gotty/deb/pandora_gotty/DEBIAN/control new file mode 100644 index 0000000000..f715ee1b49 --- /dev/null +++ b/extras/pandora_gotty/deb/pandora_gotty/DEBIAN/control @@ -0,0 +1,9 @@ +Source: pandora_gotty +Section: utils +Version: 1.0.0 +Priority: optional +Maintainer: PandoraFMS +Build-Depends: debhelper (>= 12) +Package: pandora-gotty +Architecture: amd64 +Description: pandora_gotty for Pandora FMS. From 19a9f82fe1b740bc9f4aeeae1ac67dcac32d4fac Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Mon, 25 Sep 2023 19:08:24 +0200 Subject: [PATCH 04/20] gotty changes --- pandora_console/extensions/quick_shell.php | 692 +++++++++++------- .../extras/delete_files/delete_files.txt | 3 +- pandora_console/godmode/menu.php | 2 +- pandora_console/godmode/setup/setup.php | 4 +- .../godmode/setup/setup_websocket_engine.php | 96 +-- pandora_console/pandora_websocket_engine | 175 ----- 6 files changed, 442 insertions(+), 530 deletions(-) delete mode 100755 pandora_console/pandora_websocket_engine diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php index 7e6db3271e..cd863f6b10 100644 --- a/pandora_console/extensions/quick_shell.php +++ b/pandora_console/extensions/quick_shell.php @@ -84,84 +84,38 @@ function quickShell() $method_port = get_parameter('port', null); // Retrieve main IP Address. - $address = agents_get_address($agent_id); + $agent_address = agents_get_address($agent_id); ui_require_css_file('wizard'); ui_require_css_file('discovery'); - // Settings. - // WebSocket host, where client should connect. - if (isset($config['ws_port']) === false) { - config_update_value('ws_port', 8080); + // Initialize Gotty Client. + if ($method === 'ssh') { + // SSH. + $args = '?arg='.$username.'@'.$agent_address; + //$args = '?arg='.$username.'@172.16.0.1'; + $args .= '&arg=-p%20'.$method_port; + } else if ($method == 'telnet') { + // Telnet. + $username = preg_replace('/[^a-zA-Z0-9\-\.]/', '', $username); + $args = '?arg=-l%20'.$username; + $args .= '&arg='.$agent_address; + $args .= '&arg='.$method_port.'&arg=-E'; } - if (empty($config['ws_proxy_url']) === true) { - $ws_url = 'http://'.$_SERVER['SERVER_ADDR'].':'.$config['ws_port']; - } else { - preg_match('/\/\/(.*)/', $config['ws_proxy_url'], $matches); - if (isset($_SERVER['HTTPS']) === true) { - $ws_url = 'https://'.$matches[1]; - } else { - $ws_url = 'http://'.$matches[1]; - } - } - - // Gotty settings. Internal communication (WS). - if (isset($config['gotty_host']) === false) { - config_update_value('gotty_host', '127.0.0.1'); - } - - if (isset($config['gotty_telnet_port']) === false) { - config_update_value('gotty_telnet_port', 8082); - } - - if (isset($config['gotty_ssh_port']) === false) { - config_update_value('gotty_ssh_port', 8081); - } - - // Context to allow self-signed certs. - $context = stream_context_create( - [ - 'http' => [ 'method' => 'GET'], - 'ssl' => [ - 'verify_peer' => false, - 'verify_peer_name' => false, - ], - ] - ); + $method_addr = ($method === 'ssh') ? $config['gotty_ssh_addr'] : $config['gotty_telnet_addr']; + $address = (empty($method_addr) === true) ? $_SERVER['SERVER_ADDR'] : $method_addr; + $use_ssl = ($method === 'ssh') ? $config['gotty_ssh_use_ssl'] : $config['gotty_telnet_use_ssl']; + $protocol = ((bool) $use_ssl === true) ? 'https://' : 'http://'; + $port = ($method === 'ssh') ? $config['gotty_ssh_port'] : $config['gotty_telnet_port']; + $connection_hash = ($method === 'ssh') ? $config['gotty_ssh_connection_hash'] : $config['gotty_telnet_connection_hash']; + $gotty_addr = $protocol.$address.':'.$port.'/'.$connection_hash.'/'.$args; // Username. Retrieve from form. if (empty($username) === true) { // No username provided, ask for it. $wiz = new Wizard(); - $test = curl($ws_url, []); - if ($test === false) { - ui_print_error_message(__('WebService engine has not been started, please check documentation.')); - $wiz->printForm( - [ - 'form' => [ - 'method' => 'POST', - 'action' => '#', - 'id' => 'retry_form', - ], - ] - ); - - html_print_action_buttons( - html_print_submit_button( - __('Retry'), - 'submit', - false, - [ - 'icon' => 'next', - 'form' => 'retry_form', - ], - true - ) - ); - return; - } $wiz->printForm( [ @@ -221,114 +175,25 @@ function quickShell() return; } - // Initialize Gotty Client. - $host = $config['gotty_host']; - if ($method == 'ssh') { - // SSH. - $port = $config['gotty_ssh_port']; - $command_arguments = "var args = '?arg=".$username.'@'.$address; - $command_arguments .= '&arg=-p '.$method_port."';"; - } else if ($method == 'telnet') { - // Telnet. - $port = $config['gotty_telnet_port']; - $username = preg_replace('/[^a-zA-Z0-9\-\.]/', '', $username); - $command_arguments = "var args = '?arg=-l ".$username; - $command_arguments .= '&arg='.$address; - $command_arguments .= '&arg='.$method_port."&arg=-E';"; - } else { - ui_print_error_message(__('Please use SSH or Telnet.')); - return; - } - - // If rediretion is enabled, we will try to connect using - // http:// or https:// endpoint. - $test = get_headers($ws_url, false, $context); - if ($test === false) { - if (empty($wiz) === true) { - $wiz = new Wizard(); - } - - ui_print_error_message(__('WebService engine has not been started, please check documentation.')); - echo $wiz->printGoBackButton('#'); - return; - } - - // Check credentials. - $auth_str = ''; - $gotty_url = $host.':'.$port; - if (empty($config['gotty_user']) === false - && empty($config['gotty_pass']) === false - ) { - $auth_str = io_safe_output($config['gotty_user']); - $auth_str .= ':'.io_output_password($config['gotty_pass']); - $gotty_url = $auth_str.'@'.$host.':'.$port; - } - - $r = file_get_contents('http://'.$gotty_url.'/js/hterm.js'); - if (empty($r) === true) { - if (empty($wiz) === true) { - $wiz = new Wizard(); - } - - ui_print_error_message(__('WebService engine is not working properly, please check documentation.')); - echo $wiz->printGoBackButton('#'); - return; - } - - // Override gotty client settings. - if (empty($auth_str) === true) { - $r .= "var gotty_auth_token = '';"; - } else { - $r .= "var gotty_auth_token = '"; - $r .= $auth_str."';"; - } - - // Set websocket target and method. - $gotty = file_get_contents('http://'.$gotty_url.'/js/gotty.js'); - $url = "var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws';"; - if (empty($config['ws_proxy_url']) === true) { - $new = "var url = (httpsEnabled ? 'wss://' : 'ws://')"; - $new .= " + window.location.host + ':"; - $new .= $config['ws_port'].'/'.$method."';"; - } else { - $new = "var url = '"; - $new .= $config['ws_proxy_url'].'/'.$method."';"; - } - - // Update firefox issue. - $original = ' this.iframe_.src = \'#\';'; - $trick = 'this.iframe_.src = \'javascript:\';'; - - $r = str_replace($original, $trick, $r); - - // Update url. - $gotty = str_replace($url, $new, $gotty); - - // Update websocket arguments. - $args = 'var args = window.location.search;'; - $new = $command_arguments; - - // Update arguments. - $gotty = str_replace($args, $new, $gotty); - ?> -
- - + +
+ 0) { - $msg = __('%d Updated', $changes); - if ($critical > 0) { - $msg = __( - '%d Updated, please restart WebSocket engine service', - $changes - ); - } - - ui_print_success_message($msg); - } - - // Form. Using old style. echo '
'; - echo ''.__('Quickshell').''; + echo ''.__('SSH connection parameters').''; - $t = new StdClass(); - $t->data = []; - $t->width = '100%'; - $t->class = 'filter-table-adv'; - $t->data = []; - $t->style = []; - $t->style[0] = 'width: 50%;'; + $test_start = ''; + $test_start .= ' '; - $t->data[0][] = html_print_label_input_block( - __('Gotty path'), + $ssh_table = new StdClass(); + $ssh_table->data = []; + $ssh_table->width = '100%'; + $ssh_table->class = 'filter-table-adv'; + $ssh_table->data = []; + $ssh_table->style = []; + $ssh_table->style[0] = 'width: 50%;'; + + $ssh_table->data[0][] = html_print_label_input_block( + __('Gotty address'), html_print_input_text( - 'gotty', - $config['gotty'], + 'gotty_ssh_addr', + $config['gotty_ssh_addr'], '', 30, 100, @@ -464,20 +381,8 @@ function quickShellSettings() ) ); - $t->data[0][] = html_print_label_input_block( - __('Gotty host'), - html_print_input_text( - 'gotty_host', - $config['gotty_host'], - '', - 30, - 100, - true - ) - ); - - $t->data[1][] = html_print_label_input_block( - __('Gotty ssh port'), + $ssh_table->data[0][] = html_print_label_input_block( + __('Gotty port'), html_print_input_text( 'gotty_ssh_port', $config['gotty_ssh_port'], @@ -488,8 +393,88 @@ function quickShellSettings() ) ); - $t->data[1][] = html_print_label_input_block( - __('Gotty telnet port'), + $ssh_table->data[1][] = html_print_label_input_block( + __('Gotty user'), + html_print_input_text( + 'gotty_ssh_user', + $config['gotty_ssh_user'], + '', + 30, + 100, + true + ) + ); + + $ssh_table->data[1][] = html_print_label_input_block( + __('Gotty password'), + html_print_input_password( + 'gotty_ssh_pass', + io_output_password($config['gotty_ssh_pass']), + '', + 30, + 100, + true + ) + ); + + $ssh_table->data[2][] = html_print_label_input_block( + __('Use SSL'), + html_print_checkbox_switch( + 'gotty_ssh_use_ssl', + 1, + $config['gotty_ssh_use_ssl'], + true, + $disable_agentaccess + ) + ); + + // Test. + $row = []; + $test_start = ''; + $test_start .= ' '; + + $ssh_table->data[2][] = html_print_button( + __('Test'), + 'test-gotty-ssh', + false, + 'handleTestSSH()', + [ + 'icon' => 'cog', + 'mode' => 'secondary', + 'style' => 'width: 115px;', + ], + true + ).$test_start; + + html_print_table($ssh_table); + + echo '
'; + + echo '
'; + echo ''.__('Telnet connection parameters').''; + + $telnet_table = new StdClass(); + $telnet_table->data = []; + $telnet_table->width = '100%'; + $telnet_table->class = 'filter-table-adv'; + $telnet_table->data = []; + $telnet_table->style = []; + $telnet_table->style[0] = 'width: 50%;'; + + $telnet_table->data[0][] = html_print_label_input_block( + __('Gotty address'), + html_print_input_text( + 'gotty_telnet_addr', + $config['gotty_telnet_addr'], + '', + 30, + 100, + true + ) + ); + + $telnet_table->data[0][] = html_print_label_input_block( + __('Gotty port'), html_print_input_text( 'gotty_telnet_port', $config['gotty_telnet_port'], @@ -500,18 +485,11 @@ function quickShellSettings() ) ); - $hidden = new stdClass(); - $hidden->data = []; - $hidden->width = '100%'; - $hidden->class = 'filter-table-adv'; - $hidden->data = []; - $hidden->style[0] = 'width: 50%;'; - - $hidden->data[0][] = html_print_label_input_block( + $telnet_table->data[1][] = html_print_label_input_block( __('Gotty user'), html_print_input_text( - 'gotty_user', - $config['gotty_user'], + 'gotty_telnet_user', + $config['gotty_telnet_user'], '', 30, 100, @@ -519,11 +497,11 @@ function quickShellSettings() ) ); - $hidden->data[0][] = html_print_label_input_block( + $telnet_table->data[1][] = html_print_label_input_block( __('Gotty password'), html_print_input_password( - 'gotty_pass', - io_output_password($config['gotty_pass']), + 'gotty_telnet_pass', + io_output_password($config['gotty_telnet_pass']), '', 30, 100, @@ -531,24 +509,71 @@ function quickShellSettings() ) ); - html_print_table($t); - - ui_print_toggle( - [ - 'content' => html_print_table($hidden, true), - 'name' => __('Advanced options'), - 'clean' => false, - 'main_class' => 'no-border-imp', - 'container_class' => 'no-border-imp', - ] + $telnet_table->data[2][] = html_print_label_input_block( + __('Use SSL'), + html_print_checkbox_switch( + 'gotty_telnet_use_ssl', + 1, + $config['gotty_telnet_use_ssl'], + true + ) ); - echo '
'; + // Test. + $row = []; + $test_start = ''; + $test_start .= ' '; + $telnet_table->data[2][] = html_print_button( + __('Test'), + 'test-gotty-telnet', + false, + 'handleTestTelnet()', + [ + 'icon' => 'cog', + 'mode' => 'secondary', + 'style' => 'width: 115px;', + ], + true + ).$test_start; + + html_print_table($telnet_table); + html_print_input_hidden('update_config', 1); + + echo ''; } -// This extension is usefull only if the agent has associated IP. +if (is_ajax() === true) { + $address = get_parameter('address'); + + if (isset($address) === true) { + $ch = curl_init($address); + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Maximum time for the entire request. + curl_setopt($ch, CURLOPT_TIMEOUT, 2); + + // Maximum time to establish a connection. + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); + + curl_exec($ch); + $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($response_code === 200 || $response_code === 401) { + $result = ['status' => 'success']; + } else { + $result = ['status' => 'error']; + } + + echo json_encode($result); + return; + } +} + +// This extension is useful only if the agent has associated IP. $agent_id = get_parameter('id_agente'); if (empty($agent_id) === false && get_parameter('sec2', '') == 'operation/agentes/ver_agente' @@ -573,4 +598,139 @@ if (empty($agent_id) === false } } +echo ''; + extensions_add_godmode_function('quickShellSettings'); diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 26eaa93392..d94207a4c9 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1707,4 +1707,5 @@ enterprise/godmode/wizards/Applications.class.php enterprise/godmode/wizards/Cloud.class.php enterprise/images/wizard/applications.png enterprise/images/wizard/cloud.png -enterprise/images/wizard/consoletasks.png \ No newline at end of file +enterprise/images/wizard/consoletasks.png +pandora_websocket_engine \ No newline at end of file diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 7cd504c8ac..da06372b8a 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -485,7 +485,7 @@ if ($access_console_node === true) { $sub2['godmode/setup/setup§ion=notifications']['text'] = __('Notifications'); $sub2['godmode/setup/setup§ion=notifications']['refr'] = 0; - $sub2['godmode/setup/setup§ion=websocket_engine']['text'] = __('Websocket Engine'); + $sub2['godmode/setup/setup§ion=websocket_engine']['text'] = __('QuickShell'); $sub2['godmode/setup/setup§ion=websocket_engine']['refr'] = 0; $sub2['godmode/setup/setup§ion=external_tools']['text'] = __('External Tools'); diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index 7e17f9fe4c..c1cf635d28 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -227,7 +227,7 @@ $buttons['websocket_engine'] = [ 'images/websocket_small.png', true, [ - 'title' => __('Websocket engine'), + 'title' => __('QuickShell'), 'class' => 'invert_filter', ] ).'', @@ -327,7 +327,7 @@ switch ($section) { case 'websocket_engine': $buttons['websocket_engine']['active'] = true; - $subpage = __('Pandora Websocket Engine'); + $subpage = __('QuickShell'); $help_header = 'quickshell_settings'; break; diff --git a/pandora_console/godmode/setup/setup_websocket_engine.php b/pandora_console/godmode/setup/setup_websocket_engine.php index 5ee134e558..bed6a01ee9 100644 --- a/pandora_console/godmode/setup/setup_websocket_engine.php +++ b/pandora_console/godmode/setup/setup_websocket_engine.php @@ -34,92 +34,20 @@ $url = ui_get_full_url( echo '
'; -echo '
'; -echo ''.__('WebSocket settings').''; - -$t = new StdClass(); -$t->data = []; -$t->width = '100%'; -$t->class = 'databox filter-table-adv'; -$t->data = []; - -$t->data[0][] = html_print_label_input_block( - __('Bind address'), - html_print_input_text( - 'ws_bind_address', - $config['ws_bind_address'], - '', - 30, - 100, - true - ) -); - -$t->data[0][] = html_print_label_input_block( - __('Bind port'), - html_print_input_text( - 'ws_port', - $config['ws_port'], - '', - 30, - 100, - true - ) -); - -$t->data[1][] = html_print_label_input_block( - __('WebSocket proxy url'), - html_print_input_text( - 'ws_proxy_url', - $config['ws_proxy_url'], - '', - 30, - 100, - true - ) -); - -html_print_input_hidden('update_config', 1); - -// Test. -$row = []; -$test_start = ''; -$test_start .= ' '; -$row['gotty_test'] = html_print_label_input_block( - __('Test connection'), - html_print_button( - __('Test'), - 'test-gotty', - false, - 'handleTest()', - [ - 'icon' => 'cog', - 'mode' => 'secondary mini', - 'style' => 'width: 115px;', - ], - true - ).$test_start, - ['div_class' => 'inline_flex row'] -); - -$t->data['gotty_test'] = $row; - -html_print_table($t); - -echo '
'; - if (function_exists('quickShellSettings') === true) { quickShellSettings(); } +$action_btns = html_print_submit_button( + __('Update'), + 'update_button', + false, + [ 'icon' => 'update' ], + true +); + html_print_action_buttons( - html_print_submit_button( - __('Update'), - 'update_button', - false, - [ 'icon' => 'update' ], - true - ) + $action_btns ); echo '
'; @@ -186,10 +114,8 @@ $handle_test_js = "var handleTest = function (event) { hideLoadingImage(); showMessage(); }; -} - - -$('#button-test-ehorus').click(handleTest);"; +}"; echo $handle_test_js; echo ''; + diff --git a/pandora_console/pandora_websocket_engine b/pandora_console/pandora_websocket_engine deleted file mode 100755 index 2d4536aae0..0000000000 --- a/pandora_console/pandora_websocket_engine +++ /dev/null @@ -1,175 +0,0 @@ -#!/bin/bash -# Copyright (c) 2005-2023 Pandora FMS -# -# /etc/init.d/websocket -# -# System startup script for Pandora FMS Console websocket engine -# -# Comments to support chkconfig on RedHat Linux -# chkconfig: 2345 90 10 -# description: Pandora FMS Console webscoket engine startup script -# -# Comments to support LSB init script conventions -### BEGIN INIT INFO -# Provides: websocket -# Required-Start: $syslog cron -# Should-Start: $network cron mysql -# Required-Stop: $syslog -# Should-Stop: $network -# Default-Start: 2 3 5 -# Default-Stop: 0 1 6 -# Short-Description: Pandora FMS Console websocket engine startup script -# Description: Pandora FMS Console websocket engine startup script -### END INIT INFO - -if [ -x /lib/lsb/init-functions ]; then -. /lib/lsb/init-functions -fi - -# If you want to run several pandora Console Websocket engines in this machine, just copy -# this script to another name, editing PANDORA_HOME to the new .conf - -export WS_ENGINE="/var/www/html/pandora_console/ws.php" -export PHP=/usr/bin/php -export WS_LOG="/var/log/pandora/web_socket.log" -export GOTTY="/tmp/" - -# Environment variables -if [[ -z ${PANDORA_RB_PRODUCT_NAME} ]]; then - PANDORA_RB_PRODUCT_NAME="Pandora FMS" -fi -if [[ -z ${PANDORA_RB_COPYRIGHT_NOTICE} ]]; then - PANDORA_RB_COPYRIGHT_NOTICE="Pandora FMS" -fi - -export PANDORA_RB_PRODUCT_NAME=$PANDORA_RB_PRODUCT_NAME -export PANDORA_RB_COPYRIGHT_NOTICE=$PANDORA_RB_COPYRIGHT_NOTICE - -# Uses a wait limit before sending a KILL signal, before trying to stop -# Pandora FMS Console Websocket engine nicely. Some big systems need some time before close -# all pending tasks / threads. - -export MAXWAIT=60 - -# Check for SUSE status scripts -if [ -f /etc/rc.status ] -then - . /etc/rc.status - rc_reset -else - # Define part of rc functions for non-suse systems - function rc_status () { - RETVAL=$? - case $1 in - -v) RETVAL=0;; - esac - } - function rc_exit () { exit $RETVAL; } - function rc_failed () { RETVAL=${1:-1}; } - RETVAL=0 -fi - -# This function replace pidof, not working in the same way in different linux distros - -function pidof_pandora () { - # This sets COLUMNS to XXX chars, because if command is run - # in a "strech" term, ps aux don't report more than COLUMNS - # characters and this will not work. - COLUMNS=300 - PANDORA_PID=`ps aux | grep "$PHP $WS_ENGINE" | grep -v grep | tail -1 | awk '{ print $2 }'` - echo $PANDORA_PID -} - -# Main script - -if [ ! -x $GOTTY ] -then - echo "Gotty not found in $GOTTY" - rc_failed 5 # program is not installed - rc_exit -fi - -if [ ! -f $PHP ] -then - echo "$PHP not found, please install version >= 7.0" - rc_failed 5 # program is not installed - rc_exit -fi - -case "$1" in - start) - PANDORA_PID=`pidof_pandora` - if [ ! -z "$PANDORA_PID" ] - then - echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is currently running on this machine with PID ($PANDORA_PID)." - rc_exit # running start on a service already running - fi - - export PERL_LWP_SSL_VERIFY_HOSTNAME=0 - $PHP $WS_ENGINE >> $WS_LOG 2>&1 & - sleep 1 - - PANDORA_PID=`pidof_pandora` - - if [ ! -z "$PANDORA_PID" ] - then - echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is now running with PID $PANDORA_PID" - rc_status -v - else - echo "Cannot start $PANDORA_RB_PRODUCT_NAME Console Websocket engine. Aborted." - echo "Check $PANDORA_RB_PRODUCT_NAME log files at $WS_LOG" - rc_failed 7 # program is not running - fi - ;; - - stop) - PANDORA_PID=`pidof_pandora` - if [ -z "$PANDORA_PID" ] - then - echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running, cannot stop it." - rc_exit # running stop on a service already stopped or not running - else - echo "Stopping $PANDORA_RB_PRODUCT_NAME Console Websocket engine" - kill $PANDORA_PID > /dev/null 2>&1 - COUNTER=0 - - while [ $COUNTER -lt $MAXWAIT ] - do - _PID=`pidof_pandora` - if [ "$_PID" != "$PANDORA_PID" ] - then - COUNTER=$MAXWAIT - fi - COUNTER=`expr $COUNTER + 1` - sleep 1 - done - - # Send a KILL -9 signal to process, if it's alive after 60secs, we need - # to be sure is really dead, and not pretending... - if [ "$_PID" = "$PANDORA_PID" ] - then - kill -9 $PANDORA_PID > /dev/null 2>&1 - fi - rc_status -v - fi - ;; - status) - PANDORA_PID=`pidof_pandora` - if [ -z "$PANDORA_PID" ] - then - echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running." - rc_failed 7 # program is not running - else - echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is running with PID $PANDORA_PID." - rc_status - fi - ;; - force-reload|restart) - $0 stop - $0 start - ;; - *) - echo "Usage: $0 { start | stop | restart | status }" - exit 1 -esac -rc_exit From 831ed2570de98793ca73291bfea6c26364a3e013 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Wed, 27 Sep 2023 11:35:57 +0200 Subject: [PATCH 05/20] implemented cron in open --- .../wizards/DiscoveryTaskList.class.php | 5 ++-- .../include/class/ConsoleSupervisor.php | 26 +++++++++++-------- pandora_console/include/functions_cron.php | 1 - 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 347458ff62..1230661550 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -160,10 +160,9 @@ class DiscoveryTaskList extends HTML return $this->enableTask(); } - if (enterprise_installed()) { - // This check only applies to enterprise users. - enterprise_hook('tasklist_checkrunning'); + enterprise_hook('tasklist_checkrunning'); + if (enterprise_installed()) { $ret = $this->showListConsoleTask(); } else { $ret = false; diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index a434a30e7f..26e3014edc 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -200,9 +200,7 @@ class ConsoleSupervisor * NOTIF.CRON.CONFIGURED */ - if (enterprise_installed()) { - $this->checkCronRunning(); - } + $this->checkCronRunning(); /* * Check if instance is registered. @@ -2651,14 +2649,20 @@ class ConsoleSupervisor if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { $message_conf_cron .= __('Discovery relies on an appropriate cron setup.'); $message_conf_cron .= '. '.__('Please, add the following line to your crontab file:'); - $message_conf_cron .= '
* * * * * <user> wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
-                $message_conf_cron .= str_replace(
-                    ENTERPRISE_DIR.'/meta/',
-                    '',
-                    ui_get_full_url(false)
-                );
-                $message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
-                $message_conf_cron .= '/cron/cron.php >> 
'; + if (enterprise_installed()) { + $message_conf_cron .= '
* * * * * <user> wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
+                    $message_conf_cron .= str_replace(
+                        ENTERPRISE_DIR.'/meta/',
+                        '',
+                        ui_get_full_url(false)
+                    );
+                    $message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
+                    $message_conf_cron .= '/cron/cron.php >> 
'; + } else { + $message_conf_cron .= '
* * * * * <user> wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
+                    $message_conf_cron .= ui_get_full_url(false).'cron.php >> 
'; + } + $message_conf_cron .= $config['homedir'].'/log/cron.log'; } diff --git a/pandora_console/include/functions_cron.php b/pandora_console/include/functions_cron.php index 2eafd8dccb..711ed7f6ba 100644 --- a/pandora_console/include/functions_cron.php +++ b/pandora_console/include/functions_cron.php @@ -463,7 +463,6 @@ function cron_list_table() ); $defined_tasks = db_get_all_rows_sql($sql); - if (!check_acl($config['id_user'], 0, 'PM')) { $read_tasks = []; foreach ($defined_tasks as $task) { From 57a02499829e5d253ad20acb4eee099c62a29526 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Wed, 27 Sep 2023 11:38:00 +0200 Subject: [PATCH 06/20] implmented cron in open --- .../include/class/DiscoveryConsoleTask.php | 331 ++++++++++ .../include/functions_cron_task.php | 623 ++++++++++++++++++ 2 files changed, 954 insertions(+) create mode 100644 pandora_console/include/class/DiscoveryConsoleTask.php create mode 100644 pandora_console/include/functions_cron_task.php diff --git a/pandora_console/include/class/DiscoveryConsoleTask.php b/pandora_console/include/class/DiscoveryConsoleTask.php new file mode 100644 index 0000000000..f9bd6ed877 --- /dev/null +++ b/pandora_console/include/class/DiscoveryConsoleTask.php @@ -0,0 +1,331 @@ + 0) { + $console_exists = db_get_row('tconsole', 'id_console', $config['id_console']); + if ($console_exists === false) { + db_process_sql_insert( + 'tconsole', + [ + 'id_console' => $config['id_console'], + 'description' => $config['console_description'], + 'version' => $pandora_version, + 'console_type' => ($config['reporting_console_node'] === true) ? 1 : 0, + 'timezone' => $config['timezone'], + 'public_url' => $config['public_url'], + ] + ); + } else { + db_process_sql_update( + 'tconsole', + [ + 'description' => $config['console_description'], + 'timezone' => $config['timezone'], + 'public_url' => $config['public_url'], + 'console_type' => (int) $config['reporting_console_node'], + 'version' => $pandora_version, + ], + [ + 'id_console' => $config['id_console'], + ] + ); + } + } + + // Maintenance task: schedule task 'cron_task_start_gotty' if not defined yet. + // Must do at every Cron execution. + $user_function_task_id = db_get_value_sql('SELECT id FROM `tuser_task_scheduled` WHERE `args` LIKE "%cron_task_start_gotty%"'); + + if ($user_function_task_id === false) { + $this->schedule( + 'cron_task_call_user_function', + [ + 0 => 'cron_task_start_gotty', + 'function_name' => 'cron_task_start_gotty', + 'internal' => 1, + ], + 'daily', + 0, + 0, + strtotime('tomorrow') + ); + } + + // Maintenance task: check whether start GoTTY SSH and Telnet processes are running and start otherwise. + // Must do at every Cron execution. + cron_task_start_gotty(false); + + // Do not output anything until is completed. There're session + // operations inside cron_task_run function. + ob_start(); + + if (cron_task_lock() === false) { + // Cannot continue. Locked. + echo ob_get_clean(); + exit; + } + + $time = get_system_time(); + $scheduled_tasks = db_get_all_rows_in_table('tuser_task_scheduled'); + if (!$scheduled_tasks) { + $scheduled_tasks = []; + } + + /* + Watch out! First_execution corresponds to next_execution the name + of the bbdd is maintained to ensure integrity. + */ + + foreach ($scheduled_tasks as $task) { + $params = unserialize($task['args']); + if ($this->shouldTaskRun($task) === false) { + continue; + } + + if ($task['scheduled'] == 'no') { + if (($params['first_execution']) < $time) { + echo date('Y/m/d H:i:s').' Execute once time cron task: '; + echo $task['id']; + echo "\n\n"; + cron_task_run($task['id']); + // The task was not scheduled and was executed once. + db_process_sql_delete( + 'tuser_task_scheduled', + ['id' => $task['id']] + ); + } + } else { + if (($params['first_execution']) < $time) { + echo date('Y/m/d H:i:s').' EXECUTED CRON TASK: '.$task['id']; + echo "\n"; + echo "\n"; + cron_task_run($task['id']); + } + } + } + + // Dump to output. + echo ob_get_clean(); + + // Release the lock. + cron_task_release_lock(); + + } + + + /** + * Schedules a discovery console task to be executed by cron. + * + * @param string $function_name Name of the function: + * cron_task_generate_report + * cron_task_generate_report_by_template + * cron_task_save_report_to_disk + * cron_task_do_backup + * cron_task_execute_custom_script + * cron_task_save_xml_report_to_disk + * cron_task_feedback_send_mail + * cron_task_generate_csv_log. + * @param array $arguments Task execution arguments (if needed). + * @param string $schedule Task schedule options: + * 'no', + * 'hourly', + * 'daily', + * 'weekly', + * 'monthly', + * 'yearly', + * 'custom'. + * @param integer $group_id Group id (0 => all). + * @param string|null $id_user User id, if null, current user. + * @param integer|null $time_start When to start, if null, now. + * + * @return boolean Sucessfully scheduled or not. + */ + public function schedule( + string $function_name, + array $arguments=[], + string $schedule='no', + int $group_id=0, + ?string $id_user=null, + ?int $time_start=null + ) { + global $config; + + if ($id_user === null) { + $id_user = $config['id_user']; + } + + $idUserTask = db_get_value( + 'id', + 'tuser_task', + 'function_name', + $function_name + ); + + if ($idUserTask === false) { + // Failed to identify function. + return false; + } + + if (in_array($schedule, self::SCHEDULES) === false) { + // Failed to schedule. Not a valid schedule option. + return false; + } + + if ($time_start === null) { + $time_start = strtotime('now'); + } + + // Params for send mail with cron. + $parameters = array_merge( + $arguments, + [ 'first_execution' => $time_start ] + ); + + // Values insert task cron. + $task = [ + 'id_usuario' => $id_user, + 'id_user_task' => $idUserTask, + 'args' => serialize($parameters), + 'scheduled' => $schedule, + 'id_grupo' => $group_id, + ]; + + $result = db_process_sql_insert( + 'tuser_task_scheduled', + $task + ); + + return ($result !== false); + } + + +} diff --git a/pandora_console/include/functions_cron_task.php b/pandora_console/include/functions_cron_task.php new file mode 100644 index 0000000000..69586a17b6 --- /dev/null +++ b/pandora_console/include/functions_cron_task.php @@ -0,0 +1,623 @@ + time()) + ) { + // Locked! + return false; + } + } + + // Try to get a lock from DB. + $dblock = db_get_lock($config['dbname'].'.'.$lockfile); + if ($dblock !== 1) { + // Locked! + return false; + } + + // Store PID in lock file. + $PID = getmypid(); + echo 'CRON running ['.$PID."]\n"; + file_put_contents($lock, $PID); + return true; +} + + +/** + * Check if CRON.task is available to start. + * + * @return boolean True, available. False not available. + */ +function cron_task_lock() +{ + return cron_lock('cron.lock'); +} + +/** + * Release CRON.task lock + * + * @return void + */ +function cron_task_release_lock() +{ + global $config; + + // Release DB lock. + $dblock = db_release_lock($config['dbname'].'.cron.lock'); + unlink($config['attachment_store'].'/cron.lock'); +} + +/** + * Calculates target schedule time + * + * @param string $scheduled_time Desired scheduled time. + * @param integer $custom_data Custom scheduled time. + * @param integer|null $timestamp Custom timestamp. + * + * @return integer amount of time. + */ +function cron_get_scheduled_time( + string $scheduled_time, + int $custom_data=0, + $timestamp=null +) { + if ($scheduled_time == 'no') { + return 0; + } + + if ($scheduled_time == 'hourly') { + return SECONDS_1HOUR; + } + + if ($scheduled_time == 'daily') { + return SECONDS_1DAY; + } + + if ($scheduled_time == 'weekly') { + return SECONDS_1WEEK; + } + + if ($scheduled_time == 'monthly') { + $month = (($timestamp === null) ? date('m') : date('m', $timestamp)); + $year = (($timestamp === null) ? date('Y') : date('Y', $timestamp)); + + $days_month = (cal_days_in_month( + CAL_GREGORIAN, + $month, + $year + ) * SECONDS_1DAY); + + return $days_month; + } + + if ($scheduled_time == 'yearly') { + return SECONDS_1YEAR; + } + + if ($scheduled_time == 'custom') { + return $custom_data; + } + + return 0; +} + +/** + * Run scheduled task. + * + * @param integer $id_user_task Task to be run. + * @param boolean $force_run Force run. + * + * @return void + */ +function cron_task_run( + int $id_user_task, + bool $force_run=false +) { + global $config; + + if (isset($config['id_console']) === true && $config['id_console'] > 0) { + $sql = sprintf( + 'SELECT * + FROM tuser_task_scheduled + WHERE id=%d AND id_console IN (0, %d)', + $id_user_task, + $config['id_console'] + ); + + $task_scheduled = db_get_row_sql($sql); + + if ($task_scheduled !== false) { + db_process_sql_update( + 'tconsole', + ['last_execution' => time()], + ['id_console' => $config['id_console']] + ); + } + } else { + $filter = [ + 'id' => $id_user_task, + 'id_console' => 0, + ]; + + $task_scheduled = db_get_row_filter('tuser_task_scheduled', $filter, false); + } + + $args = unserialize($task_scheduled['args']); + + if (enterprise_installed() === false + && isset($args['function_name']) === true + && $args['function_name'] !== 'cron_task_start_gotty' + ) { + // Only cron_task_start_gotty is allowed to run in non enterprise environments. + return; + } + + if (enterprise_installed() === true) { + $task = db_get_row('tuser_task', 'id', $task_scheduled['id_user_task']); + } else { + $task = [ + 'name' => 'Call PHP function', + 'function_name' => 'cron_task_call_user_function', + ]; + } + + // Register shutdown function in case of fatal error, like. + register_shutdown_function('cron_task_handle_error', $task_scheduled, $task, $force_run); + + if (is_metaconsole() && !defined('METACONSOLE')) { + define('METACONSOLE', 1); + } + + if (! function_exists($task['function_name'])) { + return; + } + + // If the task is disable, not run. + if ((bool) $task_scheduled['enabled'] === false) { + return; + } + + if (session_status() === PHP_SESSION_DISABLED) { + return; + } + + $old_user = ''; + if (isset($config['id_user']) === false) { + $config['id_user'] = $task_scheduled['id_usuario']; + } + + $old_user = $config['id_user']; + + $old_session_id = session_id(); + $new_session_id = 'cron-'.uniqid(); + + // Simulate user login. + session_id($new_session_id); + session_start(); + $_SESSION['id_usuario'] = $config['id_user']; + session_write_close(); + + set_time_limit(0); + + + if ($task['function_name'] == 'cron_task_generate_report_by_template' + || $task['function_name'] == 'cron_task_generate_report' + ) { + // If empty agent position, add it. + if (!isset($args[1])) { + array_splice($args, 1, 0, ''); + } + + $args[] = $task_scheduled['scheduled']; + } + + call_user_func_array( + $task['function_name'], + array_merge(array_values(($args ?? [])), [$id_user_task]) + ); + + if (session_status() === PHP_SESSION_ACTIVE) { + @session_destroy(); + } + + session_id($old_session_id); + session_start(); + + $config['id_user'] = $old_user; + $sql = ''; + $sql2 = ''; + + if (!$force_run) { + $period = cron_get_scheduled_time( + $task_scheduled['scheduled'], + $task_scheduled['custom_data'] + ); + $old_args = unserialize($task_scheduled['args']); + if ($period > 3600) { + $array_explode = explode( + ':', + date('H:i', $old_args['first_execution']) + ); + $hora_en_segundos = (($array_explode[0] * 3600 ) + ($array_explode[1] * 60)); + + $array_explode_period = explode( + ':', + date('H:i', ($old_args['first_execution'] + $period)) + ); + $hora_en_segundos2 = (($array_explode_period[0] * 3600 ) + ($array_explode_period[1] * 60)); + + if ($hora_en_segundos !== $hora_en_segundos2) { + $period = ($period + ($hora_en_segundos - $hora_en_segundos2)); + } + } + + try { + /* + Calculate the number of periods between last execution and + current time. + */ + + $num_of_periods = 0; + if ($period !== 0) { + $num_of_periods = ceil( + (time() - $old_args['first_execution']) / $period + ); + } + + if ($task_scheduled['scheduled'] == 'monthly') { + $updated_time = $old_args['first_execution']; + + // Update updated_time adding the period for each month individually since it is a variable value depending on the number of days a month has. + while ($num_of_periods > 0) { + // Get days of current month. + $monthly_period = cron_get_scheduled_time( + 'monthly', + $task_scheduled['custom_data'], + $updated_time + ); + $updated_time += $monthly_period; + $num_of_periods--; + } + + $old_args['first_execution'] = $updated_time; + } else if ($task_scheduled['scheduled'] == 'weekly') { + $weekly_schedule = json_decode(io_safe_output($old_args['weekly_schedule']), true); + if (empty($weekly_schedule) !== true) { + $datetime = new DateTime('tomorrow'); + $nameday = strtolower($datetime->format('l')); + $continue = true; + while ($continue === true) { + if (isset($weekly_schedule[$nameday]) === true) { + $weekly_date = $datetime->format('Y-m-d'); + $weekly_time = $weekly_schedule[$nameday][0]['start']; + $old_args['first_execution'] = strtotime($weekly_date.' '.$weekly_time); + + $continue = false; + } else { + $datetime->modify('+1 day'); + $nameday = strtolower($datetime->format('l')); + } + } + } + } else { + // Add it to next execution. + $old_args['first_execution'] += ($period * $num_of_periods); + } + } catch (Exception $e) { + // If some error (ex $period=0) next execution=current time+period. + $old_args['first_execution'] = (time() + $period); + } + + $new_args = serialize($old_args); + } + + if ($config['timesource'] == 'sql') { + $sql = sprintf( + 'UPDATE tuser_task_scheduled + SET last_run=UNIX_TIMESTAMP() + WHERE id=%d', + $id_user_task + ); + } else { + $sql = sprintf( + 'UPDATE tuser_task_scheduled + SET last_run= %d + WHERE id=%d', + time(), + $id_user_task + ); + } + + if (!$force_run) { + $sql2 = "UPDATE tuser_task_scheduled + SET args = '".$new_args."' + WHERE id=".$id_user_task; + } + + db_process_sql($sql); + db_process_sql($sql2); +} + + +/** + * Execuytes custom function defined in PHP. + * + * @param string $function_name Name to execute. + * + * @return void + */ +function cron_task_call_user_function(string $function_name) +{ + global $config; + include_once $config['homedir'].'/vendor/autoload.php'; + + call_user_func($function_name); +} + + +/** + * Check whether GoTTY SSH and Telnet processes are running and start otherwise. + * + * @param boolean $restart_mode Restart the processes if running. + * + * @return void + */ +function cron_task_start_gotty(bool $restart_mode=true) +{ + global $config; + + if (empty($config['gotty_ssh_addr']) === true + && empty($config['gotty_telnet_addr']) === true + ) { + return; + } + + include_once $config['homedir'].'/include/functions_config.php'; + + // Check prev SSH process running and kill it. + if (empty($config['restart_gotty_ssh_next_cron_port']) === false) { + config_update_value('restart_gotty_ssh_next_cron_port', ''); + + $prevProcessRunningSSH = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['restart_gotty_ssh_next_cron_port']."'"); + + if (!empty($prevProcessRunningSSH)) { + shell_exec("pkill -f 'pandora_gotty.*-p ".$config['restart_gotty_ssh_next_cron_port']."'"); + } + } + + // Check if prev Telnet process running and kill it. + if (empty($config['restart_gotty_telnet_next_cron_port']) === false) { + config_update_value('restart_gotty_telnet_next_cron_port', ''); + + $prevProcessRunningTelnet = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['restart_gotty_telnet_next_cron_port']."'"); + + if (!empty($prevProcessRunningTelnet)) { + shell_exec("pkill -f 'pandora_gotty.*-p ".$config['restart_gotty_telnet_next_cron_port']."'"); + } + } + + // Check if pandora_gotty is running on the configured port. + $processRunningSSH = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['gotty_ssh_port']."'"); + $processRunningTelnet = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['gotty_telnet_port']."'"); + + $start_ssh_proc = true; + $start_telnet_proc = true; + + if (empty($config['gotty_ssh_addr']) === true) { + $start_ssh_proc = false; + } + + if (empty($config['gotty_telnet_addr']) === true) { + $start_telnet_proc = false; + } + + if (!empty($processRunningSSH)) { + // Process is running. + if ($restart_mode === true || $start_ssh_proc === false) { + // Stop the process for restarting. + shell_exec("pkill -f 'pandora_gotty.*-p ".$config['gotty_ssh_port']."'"); + } else { + // Prevent starting if already running and must not be restarted. + $start_ssh_proc = false; + } + } + + if (!empty($processRunningTelnet)) { + // Process is running. + if ($restart_mode === true + || empty($config['restart_gotty_telnet_next_cron_port']) === false + || $start_telnet_proc === false + ) { + // Restart GoTTY if it is intended to be restarted specifically, port has changed, or address was changed to an empty value. + if (empty($config['restart_gotty_telnet_next_cron_port']) === false) { + $telnet_port_kill = $config['restart_gotty_telnet_next_cron_port']; + config_update_value('restart_gotty_telnet_next_cron_port', ''); + } else { + $telnet_port_kill = $config['gotty_telnet_port']; + } + + // Stop the process for restarting. + shell_exec("pkill -f 'pandora_gotty.*-p ".$telnet_port_kill."'"); + } else { + // Prevent starting if already running and must not be restarted. + $start_telnet_proc = false; + } + } + + if ($start_ssh_proc === false && $start_telnet_proc === false) { + // Nothing to do. + return; + } + + if ($start_ssh_proc === true) { + $logFilePathSSH = $config['homedir'].'/log/gotty_ssh_cron_tmp.log'; + shell_exec('touch '.$logFilePathSSH); + + // Start pandora_gotty and capture the output. + $command_ssh = '/usr/bin/nohup /usr/bin/pandora_gotty --config /etc/pandora_gotty/pandora_gotty.conf -p '.$config['gotty_ssh_port'].' ssh > '.$logFilePathSSH.' 2>&1 &'; + shell_exec($command_ssh); + } + + if ($start_telnet_proc === true) { + $logFilePathTelnet = $config['homedir'].'/log/gotty_telnet_cron_tmp.log'; + shell_exec('touch '.$logFilePathTelnet); + + // Start pandora_gotty and capture the output. + $command_telnet = '/usr/bin/nohup /usr/bin/pandora_gotty --config /etc/pandora_gotty/pandora_gotty.conf -p '.$config['gotty_telnet_port'].' telnet > '.$logFilePathTelnet.' 2>&1 &'; + shell_exec($command_telnet); + } + + $ssh_hash_read = false; + $telnet_hash_read = false; + + // Maximum wait time (seconds). + $maxWaitTime = 2; + + // Wait for content to appear in the log file. + $startTime = time(); + + // Workaround to wait until process inputs data in the log. + while (time() - $startTime < $maxWaitTime) { + if ($start_ssh_proc === true) { + // Read command output. + $log_content_ssh = file_get_contents($logFilePathSSH); + } + + if ($start_ssh_proc === true + && !empty($log_content_ssh) + && $ssh_hash_read === false + ) { + // Extract the URL from the output. + if (preg_match('/.*?HTTP server is listening at:\s+(\S+)/', $log_content_ssh, $matches)) { + $url = $matches[1]; + + // Extract the hash. + $parts = explode('/', $url); + $hash = array_slice($parts, -2, 1)[0]; + + config_update_value('gotty_ssh_connection_hash', $hash); + } + + unlink($logFilePathSSH); + + $ssh_hash_read = true; + } + + if ($start_telnet_proc === true) { + // Read command output. + $log_content_telnet = file_get_contents($logFilePathTelnet); + } + + if ($start_telnet_proc === true + && !empty($log_content_telnet) + && $telnet_hash_read === false + ) { + // Extract the URL from the output. + if (preg_match('/.*?HTTP server is listening at:\s+(\S+)/', $log_content_telnet, $matches)) { + $url = $matches[1]; + + // Extract the hash. + $parts = explode('/', $url); + $hash = array_slice($parts, -2, 1)[0]; + + config_update_value('gotty_telnet_connection_hash', $hash); + } + + unlink($logFilePathTelnet); + + $telnet_hash_read = true; + } + + if (($start_ssh_proc === false || $ssh_hash_read === true) + && ($start_telnet_proc === false || $telnet_hash_read === true) + ) { + break; + } + + // Sleep for a short interval before checking again. + usleep(100000); + } +} From f5be4cf17c4ad15fefb7039e5e9755acc6d4f8e5 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Wed, 27 Sep 2023 11:42:21 +0200 Subject: [PATCH 07/20] implemented cron in open --- pandora_console/cron.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 pandora_console/cron.php diff --git a/pandora_console/cron.php b/pandora_console/cron.php new file mode 100644 index 0000000000..80d9485cce --- /dev/null +++ b/pandora_console/cron.php @@ -0,0 +1,31 @@ + get_system_time()], + ['token' => 'cron_last_run'] +); + +$tasks = new DiscoveryConsoleTask(); + +$tasks->run(); + +if (is_reporting_console_node() === true) { + $supervisor = new ConsoleSupervisor(); + $supervisor->run(); +} \ No newline at end of file From 00c48c1c7d793edf20ba646b4a54b1300bc62738 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Wed, 27 Sep 2023 11:44:26 +0200 Subject: [PATCH 08/20] implemented cron in open --- pandora_console/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/cron.php b/pandora_console/cron.php index 80d9485cce..c6a3439403 100644 --- a/pandora_console/cron.php +++ b/pandora_console/cron.php @@ -8,7 +8,7 @@ require_once 'include/functions_db.php'; if (enterprise_installed() === true) { return; } -hd("ENTRA EN CRON OPEN", true); + // Load classes. require_once 'include/class/DiscoveryConsoleTask.php'; require_once 'include/class/ConsoleSupervisor.php'; From 3f2caf94044cc3b835a30f4c98041e40bdde8a0e Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Wed, 27 Sep 2023 18:28:12 +0200 Subject: [PATCH 09/20] some gotty changes --- pandora_console/cron.php | 8 +- pandora_console/godmode/menu.php | 4 +- pandora_console/godmode/setup/setup.php | 12 +- .../godmode/setup/setup_quickshell.php | 53 ++++++++ .../godmode/setup/setup_websocket_engine.php | 121 ------------------ .../include/class/ConsoleSupervisor.php | 4 +- .../include/class/DiscoveryConsoleTask.php | 9 +- pandora_console/include/functions_config.php | 14 -- .../include/functions_cron_task.php | 6 +- 9 files changed, 77 insertions(+), 154 deletions(-) create mode 100644 pandora_console/godmode/setup/setup_quickshell.php delete mode 100644 pandora_console/godmode/setup/setup_websocket_engine.php diff --git a/pandora_console/cron.php b/pandora_console/cron.php index c6a3439403..0811a9ef40 100644 --- a/pandora_console/cron.php +++ b/pandora_console/cron.php @@ -5,7 +5,9 @@ require_once 'include/auth/mysql.php'; require_once 'include/functions.php'; require_once 'include/functions_db.php'; -if (enterprise_installed() === true) { +global $config; + +if ((bool) $config['enterprise_installed'] === true) { return; } @@ -13,8 +15,6 @@ if (enterprise_installed() === true) { require_once 'include/class/DiscoveryConsoleTask.php'; require_once 'include/class/ConsoleSupervisor.php'; -global $config; - db_process_sql_update( 'tconfig', ['value' => get_system_time()], @@ -28,4 +28,4 @@ $tasks->run(); if (is_reporting_console_node() === true) { $supervisor = new ConsoleSupervisor(); $supervisor->run(); -} \ No newline at end of file +} diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index da06372b8a..b6f7b1a3b7 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -485,8 +485,8 @@ if ($access_console_node === true) { $sub2['godmode/setup/setup§ion=notifications']['text'] = __('Notifications'); $sub2['godmode/setup/setup§ion=notifications']['refr'] = 0; - $sub2['godmode/setup/setup§ion=websocket_engine']['text'] = __('QuickShell'); - $sub2['godmode/setup/setup§ion=websocket_engine']['refr'] = 0; + $sub2['godmode/setup/setup§ion=quickshell']['text'] = __('QuickShell'); + $sub2['godmode/setup/setup§ion=quickshell']['refr'] = 0; $sub2['godmode/setup/setup§ion=external_tools']['text'] = __('External Tools'); $sub2['godmode/setup/setup§ion=external_tools']['refr'] = 0; diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index c1cf635d28..18a9b1db78 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -221,9 +221,9 @@ $buttons['notifications'] = [ ).'', ]; -$buttons['websocket_engine'] = [ +$buttons['quickshell'] = [ 'active' => false, - 'text' => ''.html_print_image( + 'text' => ''.html_print_image( 'images/websocket_small.png', true, [ @@ -325,8 +325,8 @@ switch ($section) { $subpage = __('Notifications'); break; - case 'websocket_engine': - $buttons['websocket_engine']['active'] = true; + case 'quickshell': + $buttons['quickshell']['active'] = true; $subpage = __('QuickShell'); $help_header = 'quickshell_settings'; break; @@ -454,8 +454,8 @@ switch ($section) { include_once $config['homedir'].'/godmode/setup/setup_notifications.php'; break; - case 'websocket_engine': - include_once $config['homedir'].'/godmode/setup/setup_websocket_engine.php'; + case 'quickshell': + include_once $config['homedir'].'/godmode/setup/setup_quickshell.php'; break; case 'external_tools': diff --git a/pandora_console/godmode/setup/setup_quickshell.php b/pandora_console/godmode/setup/setup_quickshell.php new file mode 100644 index 0000000000..84b3fad1d0 --- /dev/null +++ b/pandora_console/godmode/setup/setup_quickshell.php @@ -0,0 +1,53 @@ +'; + +if (function_exists('quickShellSettings') === true) { + quickShellSettings(); +} + +$action_btns = html_print_submit_button( + __('Update'), + 'update_button', + false, + [ 'icon' => 'update' ], + true +); + +html_print_action_buttons( + $action_btns +); + +echo ''; diff --git a/pandora_console/godmode/setup/setup_websocket_engine.php b/pandora_console/godmode/setup/setup_websocket_engine.php deleted file mode 100644 index bed6a01ee9..0000000000 --- a/pandora_console/godmode/setup/setup_websocket_engine.php +++ /dev/null @@ -1,121 +0,0 @@ -'; - -if (function_exists('quickShellSettings') === true) { - quickShellSettings(); -} - -$action_btns = html_print_submit_button( - __('Update'), - 'update_button', - false, - [ 'icon' => 'update' ], - true -); - -html_print_action_buttons( - $action_btns -); - -echo ''; - -echo ''; - diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index 26e3014edc..b4320b1a4d 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -499,9 +499,7 @@ class ConsoleSupervisor * NOTIF.CRON.CONFIGURED */ - if (enterprise_installed()) { - $this->checkCronRunning(); - } + $this->checkCronRunning(); /* * Check if instance is registered. diff --git a/pandora_console/include/class/DiscoveryConsoleTask.php b/pandora_console/include/class/DiscoveryConsoleTask.php index f9bd6ed877..129bc93435 100644 --- a/pandora_console/include/class/DiscoveryConsoleTask.php +++ b/pandora_console/include/class/DiscoveryConsoleTask.php @@ -26,7 +26,7 @@ * ============================================================================ */ -if (enterprise_installed() === true) { +if ((bool) $config['enterprise_installed'] === true) { enterprise_include_once('/include/functions_cron.php'); } else { include_once $config['homedir'].'/include/functions_cron_task.php'; @@ -163,6 +163,13 @@ class DiscoveryConsoleTask // Maintenance task: schedule task 'cron_task_start_gotty' if not defined yet. // Must do at every Cron execution. + if ((bool) $config['enterprise_installed'] === false) { + $call_func_user_task_id = db_get_value_sql('SELECT id FROM `tuser_task` WHERE `function_name` = "cron_task_call_user_function"'); + if ($call_func_user_task_id === false) { + db_process_sql("INSERT INTO `tuser_task` (`function_name`, `parameters`, `name`) VALUES ('cron_task_call_user_function','a:1:{i:0;a:2:{s:11:\"description\";s:13:\"Function name\";s:4:\"type\";s:4:\"text\";}}','Call PHP function')"); + } + } + $user_function_task_id = db_get_value_sql('SELECT id FROM `tuser_task_scheduled` WHERE `args` LIKE "%cron_task_start_gotty%"'); if ($user_function_task_id === false) { diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 393c6a2610..3be80ad923 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -2030,20 +2030,6 @@ function config_update_config() } break; - case 'websocket_engine': - if (config_update_value('ws_bind_address', get_parameter('ws_bind_address'), true) === false) { - $error_update[] = __('WebSocket bind address'); - } - - if (config_update_value('ws_port', get_parameter('ws_port'), true) === false) { - $error_update[] = __('WebSocket port'); - } - - if (config_update_value('ws_proxy_url', get_parameter('ws_proxy_url'), true) === false) { - $error_update[] = __('WebSocket proxy url'); - } - break; - default: // Ignore. break; diff --git a/pandora_console/include/functions_cron_task.php b/pandora_console/include/functions_cron_task.php index 69586a17b6..0cc9cb08cd 100644 --- a/pandora_console/include/functions_cron_task.php +++ b/pandora_console/include/functions_cron_task.php @@ -227,7 +227,7 @@ function cron_task_run( $args = unserialize($task_scheduled['args']); - if (enterprise_installed() === false + if ((bool) $config['enterprise_installed'] === false && isset($args['function_name']) === true && $args['function_name'] !== 'cron_task_start_gotty' ) { @@ -235,7 +235,7 @@ function cron_task_run( return; } - if (enterprise_installed() === true) { + if ((bool) $config['enterprise_installed'] === true) { $task = db_get_row('tuser_task', 'id', $task_scheduled['id_user_task']); } else { $task = [ @@ -282,7 +282,6 @@ function cron_task_run( set_time_limit(0); - if ($task['function_name'] == 'cron_task_generate_report_by_template' || $task['function_name'] == 'cron_task_generate_report' ) { @@ -432,6 +431,7 @@ function cron_task_run( function cron_task_call_user_function(string $function_name) { global $config; + include_once $config['homedir'].'/vendor/autoload.php'; call_user_func($function_name); From 12fbd1e522eb3bff8594633c788a10ccf3fa65af Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Mon, 2 Oct 2023 13:57:11 +0200 Subject: [PATCH 10/20] some functional changes in gotty --- pandora_console/extensions/quick_shell.php | 187 +++++++++++++++--- .../include/class/DiscoveryConsoleTask.php | 47 +++-- .../include/functions_cron_task.php | 57 ++---- 3 files changed, 207 insertions(+), 84 deletions(-) diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php index cd863f6b10..d07342945a 100644 --- a/pandora_console/extensions/quick_shell.php +++ b/pandora_console/extensions/quick_shell.php @@ -31,6 +31,7 @@ global $config; require_once $config['homedir'].'/include/functions_agents.php'; require_once $config['homedir'].'/godmode/wizards/Wizard.main.php'; +require_once $config['homedir'].'/include/functions_cron_task.php'; /** @@ -78,9 +79,28 @@ function quickShell() return; } + $method = get_parameter('method', null); + + $setup_anchor = html_print_anchor( + [ + 'href' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=quickshell', + 'content' => __('GoTTY setup'), + ], + true + ); + + if ($method === 'ssh' && (bool) $config['gotty_ssh_enabled'] === false) { + ui_print_error_message(__('Please, enable SSH in %s', $setup_anchor)); + return; + } + + if ($method === 'telnet' && (bool) $config['gotty_telnet_enabled'] === false) { + ui_print_error_message(__('Please, enable Telnet in %s', $setup_anchor)); + return; + } + $agent_id = get_parameter('id_agente', 0); $username = get_parameter('username', null); - $method = get_parameter('method', null); $method_port = get_parameter('port', null); // Retrieve main IP Address. @@ -89,10 +109,10 @@ function quickShell() ui_require_css_file('wizard'); ui_require_css_file('discovery'); - // Initialize Gotty Client. + // Build URL args. if ($method === 'ssh') { // SSH. - $args = '?arg='.$username.'@'.$agent_address; + $args .= '?arg='.$username.'@'.$agent_address; //$args = '?arg='.$username.'@172.16.0.1'; $args .= '&arg=-p%20'.$method_port; } else if ($method == 'telnet') { @@ -103,20 +123,15 @@ function quickShell() $args .= '&arg='.$method_port.'&arg=-E'; } - $method_addr = ($method === 'ssh') ? $config['gotty_ssh_addr'] : $config['gotty_telnet_addr']; - $address = (empty($method_addr) === true) ? $_SERVER['SERVER_ADDR'] : $method_addr; - $use_ssl = ($method === 'ssh') ? $config['gotty_ssh_use_ssl'] : $config['gotty_telnet_use_ssl']; - $protocol = ((bool) $use_ssl === true) ? 'https://' : 'http://'; - $port = ($method === 'ssh') ? $config['gotty_ssh_port'] : $config['gotty_telnet_port']; - $connection_hash = ($method === 'ssh') ? $config['gotty_ssh_connection_hash'] : $config['gotty_telnet_connection_hash']; - $gotty_addr = $protocol.$address.':'.$port.'/'.$connection_hash.'/'.$args; + $connectionURL = buildConnectionURL($method); + //$basic_auth_hdr = $config['gotty_ssh_user'].':'.$config['gotty_ssh_pass'].'@'; + $gotty_addr = $connectionURL.$args; // Username. Retrieve from form. if (empty($username) === true) { // No username provided, ask for it. $wiz = new Wizard(); - $wiz->printForm( [ 'form' => [ @@ -192,13 +207,70 @@ function quickShell() } -
+
+ + + // Capture error sent from iframe. + window.addEventListener("message", function(event) { + var received_data = event.data; + + if (received_data.error_code) { + // Send error code to the server. + var new_url = window.location.href + "?error_code=" + received_data.error_code; + window.location.href = new_url; + } + }); + + var iframe = document.getElementById('gotty-iframe'); + console.log(iframe ); + + iframe.addEventListener("error", function (event) { + console.log("erorrrrrrr"); + // If an error occurs while loading the iframe content. + if (event.target.contentWindow) { + var status = event.target.contentWindow.document; + if (status && status.location) { + var status_code = status.location.href.match(/(\d{3})\.html/)[1]; + if (status_code >= "400" && status_code < "600") { + // Post the error data to the parent window. + window.parent.postMessage(status_code, window.location.origin); + } + } + } + }); + */ + ?> '; @@ -370,6 +471,16 @@ function quickShellSettings() $ssh_table->style[0] = 'width: 50%;'; $ssh_table->data[0][] = html_print_label_input_block( + __('Enable SSH GoTTY'), + html_print_checkbox_switch( + 'gotty_ssh_enabled', + 1, + $config['gotty_ssh_enabled'], + true + ) + ); + + $ssh_table->data[1][] = html_print_label_input_block( __('Gotty address'), html_print_input_text( 'gotty_ssh_addr', @@ -381,7 +492,7 @@ function quickShellSettings() ) ); - $ssh_table->data[0][] = html_print_label_input_block( + $ssh_table->data[1][] = html_print_label_input_block( __('Gotty port'), html_print_input_text( 'gotty_ssh_port', @@ -393,7 +504,7 @@ function quickShellSettings() ) ); - $ssh_table->data[1][] = html_print_label_input_block( + $ssh_table->data[2][] = html_print_label_input_block( __('Gotty user'), html_print_input_text( 'gotty_ssh_user', @@ -405,7 +516,7 @@ function quickShellSettings() ) ); - $ssh_table->data[1][] = html_print_label_input_block( + $ssh_table->data[2][] = html_print_label_input_block( __('Gotty password'), html_print_input_password( 'gotty_ssh_pass', @@ -417,7 +528,7 @@ function quickShellSettings() ) ); - $ssh_table->data[2][] = html_print_label_input_block( + $ssh_table->data[3][] = html_print_label_input_block( __('Use SSL'), html_print_checkbox_switch( 'gotty_ssh_use_ssl', @@ -433,7 +544,12 @@ function quickShellSettings() $test_start = ''; $test_start .= ' '; - $ssh_table->data[2][] = html_print_button( + /*$tip = ui_print_help_tip( + __('Save configuration before performing test to check if GoTTY process was started successfully'), + true + );*/ + + $ssh_table->data[3][] = html_print_button( __('Test'), 'test-gotty-ssh', false, @@ -462,6 +578,16 @@ function quickShellSettings() $telnet_table->style[0] = 'width: 50%;'; $telnet_table->data[0][] = html_print_label_input_block( + __('Enable Telnet GoTTY'), + html_print_checkbox_switch( + 'gotty_telnet_enabled', + 1, + $config['gotty_telnet_enabled'], + true + ) + ); + + $telnet_table->data[1][] = html_print_label_input_block( __('Gotty address'), html_print_input_text( 'gotty_telnet_addr', @@ -473,7 +599,7 @@ function quickShellSettings() ) ); - $telnet_table->data[0][] = html_print_label_input_block( + $telnet_table->data[1][] = html_print_label_input_block( __('Gotty port'), html_print_input_text( 'gotty_telnet_port', @@ -485,7 +611,7 @@ function quickShellSettings() ) ); - $telnet_table->data[1][] = html_print_label_input_block( + $telnet_table->data[2][] = html_print_label_input_block( __('Gotty user'), html_print_input_text( 'gotty_telnet_user', @@ -497,7 +623,7 @@ function quickShellSettings() ) ); - $telnet_table->data[1][] = html_print_label_input_block( + $telnet_table->data[2][] = html_print_label_input_block( __('Gotty password'), html_print_input_password( 'gotty_telnet_pass', @@ -509,7 +635,7 @@ function quickShellSettings() ) ); - $telnet_table->data[2][] = html_print_label_input_block( + $telnet_table->data[3][] = html_print_label_input_block( __('Use SSL'), html_print_checkbox_switch( 'gotty_telnet_use_ssl', @@ -524,7 +650,7 @@ function quickShellSettings() $test_start = ''; $test_start .= ' '; - $telnet_table->data[2][] = html_print_button( + $telnet_table->data[3][] = html_print_button( __('Test'), 'test-gotty-telnet', false, @@ -545,9 +671,10 @@ function quickShellSettings() if (is_ajax() === true) { - $address = get_parameter('address'); + $method = (string) get_parameter('method', ''); - if (isset($address) === true) { + if (empty($method) === false) { + $address = buildConnectionURL($method); $ch = curl_init($address); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -571,6 +698,9 @@ if (is_ajax() === true) { echo json_encode($result); return; } + + $result = ['status' => 'error']; + return; } // This extension is useful only if the agent has associated IP. @@ -599,13 +729,14 @@ if (empty($agent_id) === false } echo '*/ - ?> Date: Mon, 9 Oct 2023 18:56:02 +0200 Subject: [PATCH 17/20] some changes in gotty --- pandora_console/extensions/quick_shell.php | 380 ++++++++++--------- pandora_console/include/functions_config.php | 13 +- 2 files changed, 205 insertions(+), 188 deletions(-) diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php index b50a7ec828..2f45242942 100644 --- a/pandora_console/extensions/quick_shell.php +++ b/pandora_console/extensions/quick_shell.php @@ -79,8 +79,6 @@ function quickShell() return; } - $method = get_parameter('method', null); - $setup_anchor = html_print_anchor( [ 'href' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=quickshell', @@ -89,6 +87,15 @@ function quickShell() true ); + $fetch_result = get_parameter('fetch-result', null); + + if (isset($fetch_result) === true && $fetch_result === '0') { + ui_print_error_message(__('Connection error. Please check your settings at %s', $setup_anchor)); + return; + } + + $method = get_parameter('method', null); + if ((bool) $config['gotty_ssh_enabled'] === false && (bool) $config['gotty_telnet_enabled'] === false ) { @@ -118,6 +125,9 @@ function quickShell() $connectionURL = buildConnectionURL($method); $gotty_addr = $connectionURL.$args; + $connectionURLSSH = buildConnectionURL('ssh'); + $connectionURLTelnet = buildConnectionURL('telnet'); + // Username. Retrieve from form. if (empty($username) === true) { // No username provided, ask for it. @@ -160,6 +170,7 @@ function quickShell() 'label' => __('Username'), 'arguments' => [ 'type' => 'text', + 'id' => 'username', 'name' => 'username', 'required' => true, ], @@ -191,7 +202,7 @@ function quickShell() html_print_action_buttons( html_print_submit_button( __('Connect'), - 'submit', + 'submit-btn', false, [ 'icon' => 'cog', @@ -200,30 +211,57 @@ function quickShell() true ) ); + + echo ""; + return; } - // Check gotty connection before trying to load iframe. - $ch = curl_init($gotty_addr); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - // Maximum time for the entire request. - curl_setopt($ch, CURLOPT_TIMEOUT, 3); - // Maximum time to establish a connection. - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_MAXREDIRS, 10); - - $response = curl_exec($ch); - $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); - - curl_close($ch); - - if ($responseCode !== 200) { - ui_print_error_message(__('Connection error. Please check your settings at %s', $setup_anchor)); - exit; - } - ?>