From bab98eca444c757644c081bff2f35c789c0f0b8b Mon Sep 17 00:00:00 2001 From: Frank Bergkemper Date: Fri, 31 Oct 2014 14:52:17 +0000 Subject: [PATCH] Native director connectivity Replaced the old director communication with the new native connectivity. --- Makefile.am | 2 - Makefile.in | 2 - config/autoload/local.php.dist | 38 +- debian/control | 1 - doc/install/INSTALL.md | 33 +- install/sudoers.d/bareos-webui-bconsole | 4 - .../Client/Controller/ClientController.php | 28 +- .../Client/view/client/client/details.phtml | 31 +- .../Controller/DirectorController.php | 46 +- .../src/Director/Model/DirectorTable.php | 25 +- .../view/director/director/index.phtml | 22 +- .../view/director/director/messages.phtml | 24 +- .../view/director/director/schedule.phtml | 24 +- .../director/director/schedulerstatus.phtml | 24 +- .../view/director/director/version.phtml | 24 +- .../Fileset/Controller/FilesetController.php | 22 +- .../view/fileset/fileset/details.phtml | 22 +- .../Install/Controller/InstallController.php | 91 +-- .../Install/view/install/install/test.phtml | 33 +- .../Job/src/Job/Controller/JobController.php | 14 +- module/Job/view/job/job/cancel.phtml | 8 +- module/Job/view/job/job/rerun.phtml | 8 +- .../Storage/Controller/StorageController.php | 24 +- .../view/storage/storage/autochanger.phtml | 24 +- .../view/storage/storage/details.phtml | 24 +- packaging/obs/bareos-webui.spec | 13 +- .../Bareos/BConsole/BConsoleConnector.php | 76 -- .../library/Bareos/BSock/BareosBSock.php | 728 ++++++++++++++++++ .../library/Bareos/BSock/BareosBase64.php | 108 +++ .../Bareos/Db/Sql/BareosSqlCompatHelper.php | 22 + 30 files changed, 1050 insertions(+), 495 deletions(-) delete mode 100644 install/sudoers.d/bareos-webui-bconsole delete mode 100644 vendor/Bareos/library/Bareos/BConsole/BConsoleConnector.php create mode 100644 vendor/Bareos/library/Bareos/BSock/BareosBSock.php create mode 100644 vendor/Bareos/library/Bareos/BSock/BareosBase64.php diff --git a/Makefile.am b/Makefile.am index f7100fc9..132c285f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,10 @@ install: install-am mkdir -p $(DESTDIR)$(pkgdatadir) mkdir -p $(DESTDIR)/@HTTPD_CONF@ - mkdir -p $(DESTDIR)@sysconfdir@/sudoers.d/ cp -pr init_autoloader.php config/ data/ module/ public/ vendor/ $(DESTDIR)$(pkgdatadir) cp -p config/autoload/local.php.dist $(DESTDIR)/etc/bareos-webui.conf.php ln -s /etc/bareos-webui.conf.php $(DESTDIR)/$(pkgdatadir)/config/autoload/local.php $(INSTALL) -m 0640 install/apache/bareos-webui.conf $(DESTDIR)@HTTPD_CONF@/ - $(INSTALL) -m 0440 install/sudoers.d/bareos-webui-bconsole $(DESTDIR)@sysconfdir@/sudoers.d/ # #$(INSTALL_SCRIPT) install/bareos-webui-config $(DESTDIR)@sbindir@ diff --git a/Makefile.in b/Makefile.in index 1b1c7925..bf82c095 100644 --- a/Makefile.in +++ b/Makefile.in @@ -522,13 +522,11 @@ uninstall-am: install: install-am mkdir -p $(DESTDIR)$(pkgdatadir) mkdir -p $(DESTDIR)/@HTTPD_CONF@ - mkdir -p $(DESTDIR)@sysconfdir@/sudoers.d/ cp -pr init_autoloader.php config/ data/ module/ public/ vendor/ $(DESTDIR)$(pkgdatadir) cp -p config/autoload/local.php.dist $(DESTDIR)/etc/bareos-webui.conf.php ln -s /etc/bareos-webui.conf.php $(DESTDIR)/$(pkgdatadir)/config/autoload/local.php $(INSTALL) -m 0640 install/apache/bareos-webui.conf $(DESTDIR)@HTTPD_CONF@/ - $(INSTALL) -m 0440 install/sudoers.d/bareos-webui-bconsole $(DESTDIR)@sysconfdir@/sudoers.d/ # #$(INSTALL_SCRIPT) install/bareos-webui-config $(DESTDIR)@sbindir@ diff --git a/config/autoload/local.php.dist b/config/autoload/local.php.dist index 691f87a2..eea78547 100644 --- a/config/autoload/local.php.dist +++ b/config/autoload/local.php.dist @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -32,16 +32,14 @@ * .dist extension at the end and populate values as needed. * * @NOTE: This file is ignored from Git by default with the .gitignore included. - * This is a good practice, as it prevents sensitive credentials from accidentally + * This is a good practice, as it prevents sensitive credentials from accidentally * being committed into version control. */ return array( - 'db' => array( - // Set your database driver here: Pdo_Mysql, Pdo_Pgsql, Mysqli or Pgsql - 'driver' => 'Pdo_Pgsql', + 'driver' => 'Pdo_Pgsql', // Set your database here 'dbname' => 'bareos', // Set your hostname here @@ -50,15 +48,25 @@ return array( 'username' => 'bareos_webui', // Set your password here 'password' => '', - ), - 'bconsole' => array( - // Set full path to bconsole command - 'exec_path' => '/usr/sbin/bconsole', - // Use sudo to execute bconsole command: true or false - 'sudo' => 'true', - // Set full path to bconsole configuration file - 'config_path' => '/etc/bareos/bconsole.conf', - ), - + 'director' => array( + // Director hostname or ip address + 'host' => '127.0.0.1', + // Director port + 'port' => '9101', + // Director password + 'password' => '', + // Director named console + 'console_name' => null, + // TLS parameter + 'tls_verify_peer' => false, + 'server_can_do_tls' => false, + 'server_requires_tls' => false, + 'client_can_do_tls' => true, + 'client_requires_tls' => false, + 'ca_file' => null, + 'cert_file' => null, + 'cert_file_passphrase' => null, + 'allowed_cns' => null, + ), ); diff --git a/debian/control b/debian/control index c306fa8e..7d80af6f 100644 --- a/debian/control +++ b/debian/control @@ -14,6 +14,5 @@ Vcs-Browser: https://github.com/bareos/bareos-webui.git Package: bareos-webui Architecture: all Depends: apache2 | httpd, libapache2-mod-php5 | php5 | php5-cgi, php5-cli, php5-gd, php5-json, php5-mysql, php5-pgsql, php5-sqlite | php5-sqlite3, zendframework (>= 2.2.0) | zend-framework (>= 2.2.0) | php5-zendframework2 (>= 2.2.0), ${misc:Depends} -Recommends: sudo Description: Bareos Web User Interface. Webinterface for the Bareos backup system. diff --git a/doc/install/INSTALL.md b/doc/install/INSTALL.md index f1ec1755..68ce27fa 100644 --- a/doc/install/INSTALL.md +++ b/doc/install/INSTALL.md @@ -5,7 +5,6 @@ Remember: this project is still in alpha state. ### SYSTEM REQUIREMENTS * A working Bareos environment, Bareos 12.4 or later, including a Bareos catalog database (currently only PostgreSQL is tested) -* A working Bareos Console (bconsole) on this system * An Apache 2.x Webserver with mod-rewrite, mod-php5 and mod-setenvif enabled * PHP 5.3.3 or later * PHP PDO Extension @@ -20,7 +19,7 @@ Remember: this project is still in alpha state. ### How bareos-webui accesses Bareos Bareos-webui connects to Bareos by - * bconsole + * native connection to the director * database connection (read-only) to the Bareos catalog ## Installation @@ -50,7 +49,6 @@ However, not all distributions offer these packages. * add the [Bareos contrib](http://download.bareos.org/bareos/contrib/) repository that is matching your Linux distribution * install the package bareos-webui - * verify, that your local bconsole can connect to your Bareos environment, e.g. run ```bconsole``` * configure your database connection to your Bareos catalog in ```/etc/bareos-webui.conf.php``` (this is the link target of ```/usr/share/bareos-webui/config/autoload/local.php```). See [configure database connection](#configure-the-database-connection) * reload your Apache webserver * test bareos-webui using the url: [http://localhost/bareos-webui](http://localhost/bareos-webui) @@ -67,7 +65,7 @@ git clone https://github.com/bareos/bareos-webui.git cd bareos-webui ``` -* Download composer.phar +* Download composer.phar ``` wget https://getcomposer.org/composer.phar @@ -99,30 +97,6 @@ This will change and no longer be necessary in future, but it is the way to go f SetEnv "ZF2_PATH" "/usr/share/php5" ``` -### Configuration to be able to run bconsole commands within the web-frontend - -In order to be able to execute bconsole commands within the web-frontend, it is necessary there is a sudo rule for the user under -which your webserver is running. So, run visudo and add the following lines, e.g: - -``` -# bareos web-frontend entry -wwwrun ALL=NOPASSWD: /usr/sbin/bconsole -``` - -or something like ... - -``` -# bareos web-frontend entry -apache ALL=NOPASSWD: /usr/sbin/bconsole -``` - -You can use the default sudo configuration from bareos-webui, that should work on most Linux distributions: -``` -cd /etc/sudoers.d/ -wget https://raw.github.com/bareos/bareos-webui/master/install/sudoers.d/bareos-webui-bconsole -chmod u=r,g=r,o= bareos-webui-bconsole -``` - ### Configure the database connection Bareos-webui needs only a read-only connection to the Bareos catalog database, so there are multiple possibilities to configure bareos-webui: @@ -159,8 +133,7 @@ Reload the PostgreSQL configuration: pg_ctl reload ``` - -##### +##### Adapt the bareos-webui configuration file to match your database settings. diff --git a/install/sudoers.d/bareos-webui-bconsole b/install/sudoers.d/bareos-webui-bconsole deleted file mode 100644 index 78283102..00000000 --- a/install/sudoers.d/bareos-webui-bconsole +++ /dev/null @@ -1,4 +0,0 @@ -# allow apache to run bconsole. required for bareos-webui -Cmnd_Alias BCON = /usr/sbin/bconsole -n -c /etc/bareos/bconsole.conf, /usr/sbin/bconsole -n -c /etc/bareos/webui/bconsole.conf, /usr/sbin/bconsole -Defaults!BCON !requiretty -wwwrun,www-data,apache ALL=(root) NOPASSWD: BCON diff --git a/module/Client/src/Client/Controller/ClientController.php b/module/Client/src/Client/Controller/ClientController.php index 2141f560..731734da 100644 --- a/module/Client/src/Client/Controller/ClientController.php +++ b/module/Client/src/Client/Controller/ClientController.php @@ -4,7 +4,7 @@ use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; -use Bareos\BConsole\BConsoleConnector; +use Bareos\BSock\BareosBSock; class ClientController extends AbstractActionController { @@ -15,8 +15,8 @@ class ClientController extends AbstractActionController public function indexAction() { $order_by = $this->params()->fromRoute('order_by') ? $this->params()->fromRoute('order_by') : 'ClientId'; - $order = $this->params()->fromRoute('order') ? $this->params()->fromRoute('order') : 'DESC'; - $limit = $this->params()->fromRoute('limit') ? $this->params()->fromRoute('limit') : '25'; + $order = $this->params()->fromRoute('order') ? $this->params()->fromRoute('order') : 'DESC'; + $limit = $this->params()->fromRoute('limit') ? $this->params()->fromRoute('limit') : '25'; $paginator = $this->getClientTable()->fetchAll(true, $order_by, $order); $paginator->setCurrentPageNumber( (int) $this->params()->fromQuery('page', 1) ); $paginator->setItemCountPerPage($limit); @@ -31,30 +31,32 @@ public function indexAction() ); } - public function detailsAction() + public function detailsAction() { - + $id = (int) $this->params()->fromRoute('id', 0); if(!$id) { return $this->redirect()->toRoute('client'); } - + $result = $this->getClientTable()->getClient($id); $cmd = 'status client="' . $result->name . '"'; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel( array( 'client' => $this->getClientTable()->getClient($id), 'job' => $this->getJobTable()->getLastSuccessfulClientJob($id), - 'bconsoleOutput' => $bcon->getBConsoleOutput($cmd), + 'bconsoleOutput' => $bsock->send_command($cmd), ) ); - + } - public function getClientTable() + public function getClientTable() { if(!$this->clientTable) { $sm = $this->getServiceLocator(); @@ -62,8 +64,8 @@ public function getClientTable() } return $this->clientTable; } - - public function getJobTable() + + public function getJobTable() { if(!$this->jobTable) { $sm = $this->getServiceLocator(); @@ -71,6 +73,6 @@ public function getJobTable() } return $this->jobTable; } - + } diff --git a/module/Client/view/client/client/details.phtml b/module/Client/view/client/client/details.phtml index 40a489b8..bfe4e587 100644 --- a/module/Client/view/client/client/details.phtml +++ b/module/Client/view/client/client/details.phtml @@ -12,11 +12,11 @@ $this->headTitle($title);
- +

General Information

- +
@@ -53,11 +53,11 @@ $this->headTitle($title);
- +

todo placeholder (client stats)

- +
@@ -65,21 +65,12 @@ $this->headTitle($title);
- -
- -
-    
-    bconsoleOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+bconsoleOutput; ?>
+
+
+
- diff --git a/module/Director/src/Director/Controller/DirectorController.php b/module/Director/src/Director/Controller/DirectorController.php index f993f189..0dafea71 100644 --- a/module/Director/src/Director/Controller/DirectorController.php +++ b/module/Director/src/Director/Controller/DirectorController.php @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -28,20 +28,22 @@ use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; -use Bareos\BConsole\BConsoleConnector; +use Bareos\BSock\BareosBSock; -class DirectorController extends AbstractActionController +class DirectorController extends AbstractActionController { protected $directorOutput = array(); - + public function indexAction() { $cmd = "status director"; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel(array( - 'directorOutput' => $bcon->getBConsoleOutput($cmd), + 'directorOutput' => $bsock->send_command($cmd), )); } @@ -49,41 +51,49 @@ public function messagesAction() { $cmd = "messages"; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel(array( - 'directorOutput' => $bcon->getBConsoleOutput($cmd), + 'directorOutput' => $bsock->send_command($cmd), )); } - + public function scheduleAction() { $cmd = "show schedule"; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel(array( - 'directorOutput' => $bcon->getBConsoleOutput($cmd), + 'directorOutput' => $bsock->send_command($cmd), )); } - + public function schedulerstatusAction() { $cmd = "status scheduler"; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel(array( - 'directorOutput' => $bcon->getBConsoleOutput($cmd), + 'directorOutput' => $bsock->send_command($cmd), )); } - + public function versionAction() { $cmd = "version"; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel(array( - 'directorOutput' => $bcon->getBConsoleOutput($cmd), + 'directorOutput' => $bsock->send_command($cmd), )); } - + } diff --git a/module/Director/src/Director/Model/DirectorTable.php b/module/Director/src/Director/Model/DirectorTable.php index 4683669c..f49e68c7 100644 --- a/module/Director/src/Director/Model/DirectorTable.php +++ b/module/Director/src/Director/Model/DirectorTable.php @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -27,31 +27,12 @@ //use Zend\Db\TableGateway\TableGateway; -class DirectorTable +class DirectorTable { -// protected $tableGateway; -/* - public function __construct(TableGateway $tableGateway) - { - $this->tableGateway = $tableGateway; - } - public function fetchAll() - { - $resultSet = $this->tableGateway->select(); - return $resultSet; - } -*/ - - public function __construct() + public function __construct() { } - public function getStatus() - { - $status = exec('ls -al'); - return $status; - } - } diff --git a/module/Director/view/director/director/index.phtml b/module/Director/view/director/director/index.phtml index ec259070..e9154669 100644 --- a/module/Director/view/director/director/index.phtml +++ b/module/Director/view/director/director/index.phtml @@ -43,19 +43,11 @@ $this->headTitle($title);
- -
- -
-    
-    directorOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+directorOutput; ?>
+
+
+
diff --git a/module/Director/view/director/director/messages.phtml b/module/Director/view/director/director/messages.phtml index dfba84e1..2e2a1148 100644 --- a/module/Director/view/director/director/messages.phtml +++ b/module/Director/view/director/director/messages.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -42,19 +42,11 @@ $this->headTitle($title);
- -
- -
-    
-    directorOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+directorOutput; ?>
+
+
+
diff --git a/module/Director/view/director/director/schedule.phtml b/module/Director/view/director/director/schedule.phtml index e2e2c5cf..66b7300e 100644 --- a/module/Director/view/director/director/schedule.phtml +++ b/module/Director/view/director/director/schedule.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -42,19 +42,11 @@ $this->headTitle($title);
- -
- -
-    
-    directorOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+directorOutput; ?>
+
+
+
diff --git a/module/Director/view/director/director/schedulerstatus.phtml b/module/Director/view/director/director/schedulerstatus.phtml index 01aef91a..27e1800c 100644 --- a/module/Director/view/director/director/schedulerstatus.phtml +++ b/module/Director/view/director/director/schedulerstatus.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -42,19 +42,11 @@ $this->headTitle($title);
- -
- -
-    
-    directorOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+directorOutput; ?>
+
+
+
diff --git a/module/Director/view/director/director/version.phtml b/module/Director/view/director/director/version.phtml index 9c7ae6cc..761f4acf 100644 --- a/module/Director/view/director/director/version.phtml +++ b/module/Director/view/director/director/version.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -42,19 +42,11 @@ $this->headTitle($title);
- -
- -
-    
-    directorOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+directorOutput; ?>
+
+
+
diff --git a/module/Fileset/src/Fileset/Controller/FilesetController.php b/module/Fileset/src/Fileset/Controller/FilesetController.php index 070df670..6e85ce6f 100644 --- a/module/Fileset/src/Fileset/Controller/FilesetController.php +++ b/module/Fileset/src/Fileset/Controller/FilesetController.php @@ -27,7 +27,7 @@ use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; -use Bareos\BConsole\BConsoleConnector; +use Bareos\BSock\BareosBSock; class FilesetController extends AbstractActionController { @@ -37,8 +37,8 @@ class FilesetController extends AbstractActionController public function indexAction() { $order_by = $this->params()->fromRoute('order_by') ? $this->params()->fromRoute('order_by') : 'FileSetId'; - $order = $this->params()->fromRoute('order') ? $this->params()->fromRoute('order') : 'DESC'; - $limit = $this->params()->fromRoute('limit') ? $this->params()->fromRoute('limit') : '25'; + $order = $this->params()->fromRoute('order') ? $this->params()->fromRoute('order') : 'DESC'; + $limit = $this->params()->fromRoute('limit') ? $this->params()->fromRoute('limit') : '25'; $paginator = $this->getFilesetTable()->fetchAll(true, $order_by, $order); $paginator->setCurrentPageNumber( (int) $this->params()->fromQuery('page', 1) ); $paginator->setItemCountPerPage($limit); @@ -53,28 +53,30 @@ public function indexAction() ); } - public function detailsAction() + public function detailsAction() { $id = (int) $this->params()->fromRoute('id', 0); $fset = $this->getFilesetTable()->getFileSet($id); - $cmd = 'show fileset="' . $fset->fileset . '"'; + $cmd = 'show fileset="' . $fset->fileset . '"'; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); - + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); + if (!$id) { return $this->redirect()->toRoute('fileset'); } - + return new ViewModel( array( 'fileset' => $this->getFilesetTable()->getFileset($id), 'history' => $this->getFilesetTable()->getFilesetHistory($id), - 'configuration' => $bcon->getBConsoleOutput($cmd), + 'configuration' => $bsock->send_command($cmd), ) ); } - public function getFilesetTable() + public function getFilesetTable() { if(!$this->filesetTable) { $sm = $this->getServiceLocator(); diff --git a/module/Fileset/view/fileset/fileset/details.phtml b/module/Fileset/view/fileset/fileset/details.phtml index d32a8dc9..3260e639 100644 --- a/module/Fileset/view/fileset/fileset/details.phtml +++ b/module/Fileset/view/fileset/fileset/details.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -35,11 +35,11 @@ $this->headTitle($title);
- +

General Information

- +
@@ -67,17 +67,11 @@ $this->headTitle($title);
- -
-    
-    configuration as $row) {
-	echo $row ."
"; - } - ?> -
-
- +
+
+configuration; ?>
+
+
diff --git a/module/Install/src/Install/Controller/InstallController.php b/module/Install/src/Install/Controller/InstallController.php index 9225002f..e4f943c5 100644 --- a/module/Install/src/Install/Controller/InstallController.php +++ b/module/Install/src/Install/Controller/InstallController.php @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -34,7 +34,7 @@ class InstallController extends AbstractActionController { - + const REQUIRED_PHP_VERSION = "5.3"; const REQUIRED_ZF_VERSION = "2.2"; const REQUIRED_EXT_PDO = "YES"; @@ -84,18 +84,9 @@ public function testAction() 'DB_PASSWORD_CHECK' => $this->getDbPasswordStatus(), 'DB_CONNECTION_CHECK' => $this->getDbConnectionStatus(), 'DB_READACCESS_CHECK' => $this->getDbReadAccessStatus(), - 'REQUIRED_BCONSOLE_EXEC' => self::REQUIRED_BCONSOLE_EXEC, - 'CONFIGURED_BCONSOLE_EXEC' => $this->getConfiguredBConsoleExecPath(), - 'BCONSOLE_EXEC_CHECK' => $this->getBConsoleExecPathStatus(), - 'REQUIRED_BCONSOLE_CONF' => self::REQUIRED_BCONSOLE_CONF, - 'CONFIGURED_BCONSOLE_CONF' => $this->getConfiguredBConsoleConfPath(), - 'BCONSOLE_CONF_CHECK' => $this->getBConsoleConfPathStatus(), - 'REQUIRED_BCONSOLE_SUDO' => self::REQUIRED_BCONSOLE_SUDO, - 'CONFIGURED_BCONSOLE_SUDO' => $this->getConfiguredBConsoleSudo(), - 'BCONSOLE_SUDO_CHECK' => $this->getBConsoleSudoStatus(), )); return $viewModel; - } + } private function getInstalledPHPVersion() { @@ -106,8 +97,8 @@ private function getInstalledPHPVersion() private function getInstalledZFVersion() { return Version::VERSION; - } - + } + private function compareVersions($installed, $required) { if(version_compare($installed, $required, '<')) { @@ -282,77 +273,5 @@ private function getDbReadAccessStatus() } } - private function getConfiguredBConsoleExecPath() - { - $config = $this->getServiceLocator()->get('Config'); - $exec_path = $config['bconsole']['exec_path']; - if($exec_path != "") { - return $exec_path; - } - else { - $err = "NOT SET"; - return $err; - } - } - - private function getBConsoleExecPathStatus() - { - if(self::getConfiguredBConsoleExecPath() == "NOT SET") { - return -1; - } - else { - return 0; - } - } - - private function getConfiguredBConsoleConfPath() - { - $config = $this->getServiceLocator()->get('Config'); - $config_path = $config['bconsole']['config_path']; - if($config_path != "") { - return $config_path; - } - else { - $err = "NOT SET"; - return $err; - } - } - - private function getBConsoleConfPathStatus() - { - if(self::getConfiguredBConsoleConfPath() == "NOT SET") { - return -1; - } - else { - return 0; - } - } - - private function getConfiguredBConsoleSudo() - { - $config = $this->getServiceLocator()->get('Config'); - $sudo = $config['bconsole']['sudo']; - if($sudo == true) { - $msg = "TRUE"; - } - elseif($sudo == false) { - $msg = "FALSE"; - } - else { - $msg = "NOT SET"; - } - return $msg; - } - - private function getBConsoleSudoStatus() - { - if(self::getConfiguredBConsoleSudo() == "TRUE" || self::getConfiguredBConsoleSudo() == "FALSE") { - return 0; - } - else { - return -1; - } - } - } diff --git a/module/Install/view/install/install/test.phtml b/module/Install/view/install/install/test.phtml index b13fc312..f19fad1b 100644 --- a/module/Install/view/install/install/test.phtml +++ b/module/Install/view/install/install/test.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -128,37 +128,6 @@ $this->headTitle($title);
-

bconsole

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RequiredConfiguredStatus
Path to executableREQUIRED_BCONSOLE_EXEC; ?>CONFIGURED_BCONSOLE_EXEC; ?>printStatusGlyphicons($this->BCONSOLE_EXEC_CHECK); ?>
Path to configurationREQUIRED_BCONSOLE_CONF; ?>CONFIGURED_BCONSOLE_CONF; ?>printStatusGlyphicons($this->BCONSOLE_CONF_CHECK); ?>
Use sudoREQUIRED_BCONSOLE_SUDO; ?>CONFIGURED_BCONSOLE_SUDO; ?>printStatusGlyphicons($this->BCONSOLE_SUDO_CHECK); ?>
- diff --git a/module/Job/src/Job/Controller/JobController.php b/module/Job/src/Job/Controller/JobController.php index cbce46e2..2bf952dc 100644 --- a/module/Job/src/Job/Controller/JobController.php +++ b/module/Job/src/Job/Controller/JobController.php @@ -28,7 +28,7 @@ use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; -use Bareos\BConsole\BConsoleConnector; +use Bareos\BSock\BareosBSock; class JobController extends AbstractActionController { @@ -161,10 +161,12 @@ public function rerunAction() $jobid = (int) $this->params()->fromRoute('id', 0); $cmd = "rerun jobid=" . $jobid . " yes"; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel( array( - 'bconsoleOutput' => $bcon->getBConsoleOutput($cmd), + 'bconsoleOutput' => $bsock->send_command($cmd), 'jobid' => $jobid, ) ); @@ -175,10 +177,12 @@ public function cancelAction() $jobid = (int) $this->params()->fromRoute('id', 0); $cmd = "cancel jobid=" . $jobid . " yes"; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel( array( - 'bconsoleOutput' => $bcon->getBConsoleOutput($cmd) + 'bconsoleOutput' => $bsock->send_command($cmd) ) ); } diff --git a/module/Job/view/job/job/cancel.phtml b/module/Job/view/job/job/cancel.phtml index ccefa1ee..d0c0b68a 100644 --- a/module/Job/view/job/job/cancel.phtml +++ b/module/Job/view/job/job/cancel.phtml @@ -35,11 +35,7 @@ $this->headTitle($title);

Cancel job jobid; ?>

-    
-    bconsoleOutput as $row) {
-	echo $row ."
"; - } - ?> + +bconsoleOutput; ?>
diff --git a/module/Job/view/job/job/rerun.phtml b/module/Job/view/job/job/rerun.phtml index 602593e6..a6ee604d 100644 --- a/module/Job/view/job/job/rerun.phtml +++ b/module/Job/view/job/job/rerun.phtml @@ -35,11 +35,7 @@ $this->headTitle($title);

Re-running job jobid; ?>

-    
-    bconsoleOutput as $row) {
-	echo $row ."
"; - } - ?> + +bconsoleOutput; ?>
diff --git a/module/Storage/src/Storage/Controller/StorageController.php b/module/Storage/src/Storage/Controller/StorageController.php index 7b690751..dea13854 100644 --- a/module/Storage/src/Storage/Controller/StorageController.php +++ b/module/Storage/src/Storage/Controller/StorageController.php @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -27,7 +27,7 @@ use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; -use Bareos\BConsole\BConsoleConnector; +use Bareos\BSock\BareosBSock; class StorageController extends AbstractActionController { @@ -55,7 +55,7 @@ public function indexAction() ); } - public function detailsAction() + public function detailsAction() { $id = (int) $this->params()->fromRoute('id', 0); if(!$id) { @@ -64,14 +64,16 @@ public function detailsAction() $result = $this->getStorageTable()->getStorage($id); $cmd = "status storage=" . $result->name; $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel(array( - 'bconsoleOutput' => $bcon->getBConsoleOutput($cmd), + 'bconsoleOutput' => $bsock->send_command($cmd), ) ); } - public function autochangerAction() + public function autochangerAction() { $id = (int) $this->params()->fromRoute('id', 0); if(!$id) { @@ -79,15 +81,17 @@ public function autochangerAction() } $result = $this->getStorageTable()->getStorage($id); $cmd = "status storage=" . $result->name . " slots"; - $config = $this->getServiceLocator()->get('Config'); - $bcon = new BConsoleConnector($config['bconsole']); + $config = $this->getServiceLocator()->get('Config'); + $bsock = new BareosBSock(); + $bsock->set_config($config['director']); + $bsock->init(); return new ViewModel(array( - 'bconsoleOutput' => $bcon->getBConsoleOutput($cmd), + 'bconsoleOutput' => $bsock->send_command($cmd), ) ); } - public function getStorageTable() + public function getStorageTable() { if(!$this->storageTable) { $sm = $this->getServiceLocator(); diff --git a/module/Storage/view/storage/storage/autochanger.phtml b/module/Storage/view/storage/storage/autochanger.phtml index 077afcad..dc964334 100644 --- a/module/Storage/view/storage/storage/autochanger.phtml +++ b/module/Storage/view/storage/storage/autochanger.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -33,19 +33,11 @@ $this->headTitle($title);
- -
- -
-    
-    bconsoleOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+bconsoleOutput; ?>
+
+
+
diff --git a/module/Storage/view/storage/storage/details.phtml b/module/Storage/view/storage/storage/details.phtml index 7479c801..0605bdda 100644 --- a/module/Storage/view/storage/storage/details.phtml +++ b/module/Storage/view/storage/storage/details.phtml @@ -3,7 +3,7 @@ /** * * bareos-webui - Bareos Web-Frontend - * + * * @link https://github.com/bareos/bareos-webui for the canonical source repository * @copyright Copyright (c) 2013-2014 dass-IT GmbH (http://www.dass-it.de/) * @license GNU Affero General Public License (http://www.gnu.org/licenses/) @@ -33,19 +33,11 @@ $this->headTitle($title);
- -
- -
-    
-    bconsoleOutput as $row) {
-	echo $row ."
"; - } - ?> -
-
- -
- +
+
+
+bconsoleOutput; ?>
+
+
+
diff --git a/packaging/obs/bareos-webui.spec b/packaging/obs/bareos-webui.spec index c43ed1a3..6144943e 100644 --- a/packaging/obs/bareos-webui.spec +++ b/packaging/obs/bareos-webui.spec @@ -13,9 +13,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch BuildRequires: autoconf automake -BuildRequires: sudo -Requires: bareos-bconsole bareos-common Requires: php >= 5.3.3 Requires: php-ZendFramework2 >= 2.2.0 Requires: php-pdo @@ -28,7 +26,6 @@ Requires: php-pdo # * PHP PHAR Extension # * PHP DATE Extension # * PHP OpenSSL Extension -Requires: sudo %if 0%{?suse_version} BuildRequires: apache2 @@ -79,16 +76,10 @@ make # makeinstall macro does not work on RedHat #makeinstall make DESTDIR=%{buildroot} install -# /etc/sudoers.d/ should not belong to this package, -# but is does currently not exist on most distributions touch filelist -if ! [ -x /etc/sudoers.d/ ]; then - echo "%dir %attr(750,root,root) /etc/sudoers.d/" > filelist -fi - %post -# if command a2enmod exists, +# if command a2enmod exists, # use it to enable Apache rewrite module LOG=/var/log/bareos-webui-install.log echo "`date`: BEGIN bareos-webui init" >> $LOG @@ -113,5 +104,3 @@ rm -rf $RPM_BUILD_ROOT %config(noreplace) %{_apache_conf_dir}/bareos-webui.conf #/usr/sbin/bareos-webui-config -# sudo requires permissions 440 and config files without any "." -%attr(440,root,root) %config(noreplace) /etc/sudoers.d/bareos-webui-bconsole diff --git a/vendor/Bareos/library/Bareos/BConsole/BConsoleConnector.php b/vendor/Bareos/library/Bareos/BConsole/BConsoleConnector.php deleted file mode 100644 index 9c7dce60..00000000 --- a/vendor/Bareos/library/Bareos/BConsole/BConsoleConnector.php +++ /dev/null @@ -1,76 +0,0 @@ -bconsole_exec_path = $config['exec_path']; - } - else { - throw new \Exception("Sorry, bconsole settings in /config/autoload/local.php not setup correctly. Missing parameter bconsole exec_path."); - } - - if(!empty($config['config_path'])) { - $this->bconsole_config_path = $config['config_path']; - } - else { - throw new \Exception("Sorry, bconsole settings in /config/autoload/local.php not setup correctly. Missing parameter bconsole config_path."); - } - - if(!empty($config['sudo'])) { - $this->bconsole_sudo = $config['sudo']; - } - else { - throw new \Exception("Sorry, bconsole settings in /config/autoload/local.php not setup correctly. Missing parameter bconsole sudo."); - } - } - - public function getBConsoleOutput($cmd) - { - - $descriptorspec = array( - 0 => array("pipe", "r"), - 1 => array("pipe", "w"), - 2 => array("pipe", "r") - ); - - $cwd = '/usr/sbin'; - $env = array('/usr/sbin'); - - if($this->bconsole_sudo == "true") { - $process = proc_open('sudo ' . $this->bconsole_exec_path . ' -c ' . $this->bconsole_config_path, $descriptorspec, $pipes, $cwd, $env); - } - else { - $process = proc_open($this->bconsole_exec_path, $descriptorspec, $pipes, $cwd, $env); - } - - if(!is_resource($process)) - throw new \Exception("proc_open error"); - - if(is_resource($process)) - { - fwrite($pipes[0], $cmd); - fclose($pipes[0]); - while(!feof($pipes[1])) { - array_push($this->bconsole_output, fread($pipes[1],8192)); - } - fclose($pipes[1]); - } - - $return_value = proc_close($process); - - return $this->bconsole_output; - - } - -} - diff --git a/vendor/Bareos/library/Bareos/BSock/BareosBSock.php b/vendor/Bareos/library/Bareos/BSock/BareosBSock.php new file mode 100644 index 00000000..6a081a11 --- /dev/null +++ b/vendor/Bareos/library/Bareos/BSock/BareosBSock.php @@ -0,0 +1,728 @@ +. + * + */ +namespace Bareos\BSock; + +class BareosBSock +{ + const BNET_TLS_NONE = 0; /* cannot do TLS */ + const BNET_TLS_OK = 1; /* can do, but not required on my end */ + const BNET_TLS_REQUIRED = 2; /* TLS is required */ + + const BNET_EOD = -1; /* End of data stream, new data may follow */ + const BNET_EOD_POLL = -2; /* End of data and poll all in one */ + const BNET_STATUS = -3; /* Send full status */ + const BNET_TERMINATE = -4; /* Conversation terminated, doing close() */ + const BNET_POLL = -5; /* Poll request, I'm hanging on a read */ + const BNET_HEARTBEAT = -6; /* Heartbeat Response requested */ + const BNET_HB_RESPONSE = -7; /* Only response permited to HB */ + const BNET_xxxxxxPROMPT = -8; /* No longer used -- Prompt for subcommand */ + const BNET_BTIME = -9; /* Send UTC btime */ + const BNET_BREAK = -10; /* Stop current command -- ctl-c */ + const BNET_START_SELECT = -11; /* Start of a selection list */ + const BNET_END_SELECT = -12; /* End of a select list */ + const BNET_INVALID_CMD = -13; /* Invalid command sent */ + const BNET_CMD_FAILED = -14; /* Command failed */ + const BNET_CMD_OK = -15; /* Command succeeded */ + const BNET_CMD_BEGIN = -16; /* Start command execution */ + const BNET_MSGS_PENDING = -17; /* Messages pending */ + const BNET_MAIN_PROMPT = -18; /* Server ready and waiting */ + const BNET_SELECT_INPUT = -19; /* Return selection input */ + const BNET_WARNING_MSG = -20; /* Warning message */ + const BNET_ERROR_MSG = -21; /* Error message -- command failed */ + const BNET_INFO_MSG = -22; /* Info message -- status line */ + const BNET_RUN_CMD = -23; /* Run command follows */ + const BNET_YESNO = -24; /* Request yes no response */ + const BNET_START_RTREE = -25; /* Start restore tree mode */ + const BNET_END_RTREE = -26; /* End restore tree mode */ + const BNET_SUB_PROMPT = -27; /* Indicate we are at a subprompt */ + const BNET_TEXT_INPUT = -28; /* Get text input from user */ + + const DIR_OK_AUTH = "1000 OK auth\n"; + const DIR_AUTH_FAILED = "1999 Authorization failed.\n"; + + protected $config = array( + 'debug' => false, + 'host' => null, + 'port' => null, + 'password' => null, + 'console_name' => null, + 'tls_verify_peer' => null, + 'server_can_do_tls' => null, + 'server_requires_tls' => null, + 'client_can_do_tls' => null, + 'client_requires_tls' => null, + 'ca_file' => null, + 'cert_file' => null, + 'cert_file_passphrase' => null, + 'allowed_cns' => null, + ); + + private $socket = null; + + /** + * Initialize the connection + */ + public function init() + { + if(self::connect()) { + return true; + } else { + return false; + } + } + + private function set_config_keyword($setting, $key) + { + if (array_key_exists($key, $this->config)) { + $this->config[$key] = $setting; + } else { + throw new \Exception("Illegal parameter $key in /config/autoload/local.php"); + } + } + + /** + * Set the connection configuration + * + * @param $config + */ + public function set_config($config) + { + array_walk($config, array('self', 'set_config_keyword')); + + if(empty($config['host'])) { + throw new \Exception("Missing parameter 'host' in /config/autoload/local.php"); + } + + if(empty($config['port'])) { + throw new \Exception("Missing parameter 'port' in /config/autoload/local.php"); + } + + if(empty($config['password'])) { + throw new \Exception("Missing parameter 'password' in /config/autoload/local.php"); + } + + if($this->config['debug']) { + var_dump($this->config); + } + } + + /** + * Network to host length + * + * @param $buffer + * @return int + */ + private function ntohl($buffer) + { + $len = array(); + + $len = unpack('N', $buffer); + $actual_length = (float) $len[1]; + + if($actual_length > (float)2147483647) { + $actual_length -= (float)"4294967296"; + } + + return (int) $actual_length; + } + + /** + * Replace spaces in a string with the special escape character ^A which is used + * to send strings with spaces to specific director commands. + * + * @param $str + * @return string + */ + private function bash_spaces($str) + { + $length = strlen($str); + $bashed_str = ""; + + for($i = 0; $i < $length; $i++) { + if($str[$i] == ' ') { + $bashed_str .= '^A'; + } else { + $bashed_str .= $str[$i]; + } + } + + return $bashed_str; + } + + /** + * Send a string over the console socket. + * Encode the length as the first 4 bytes of the message and append the string. + * + * @param $msg + * @return boolean + */ + private function send($msg) + { + $str_length = 0; + $str_length = strlen($msg); + $msg = pack('N', $str_length) . $msg; + $str_length += 4; + + while($str_length > 0) { + $send = fwrite($this->socket, $msg, $str_length); + if($send === false) { + return false; + } elseif($send < $str_length) { + $msg = substr($msg, $send); + $str_length -= $send; + } else { + return true; + } + } + } + + /** + * Receive a string over the console socket. + * First read first 4 bytes which encoded the length of the string and + * the read the actual string. + * + * @return string + */ + private function receive($len=0) + { + $buffer = ""; + $msg_len = array(); + + if ($len == 0) { + $buffer = fread($this->socket, 4); + if($buffer === false){ + return false; + } + $msg_len = unpack('N', $buffer); + } else { + $msg_len[1] = $len; + } + + if ($msg_len[1] > 0) { + $buffer = fread($this->socket, $msg_len[1]); + } + + return $buffer; + } + + /** + * Special receive function that also knows the different so called BNET signals the + * Bareos director can send as part of the data stream. + * + * @return string + */ + private function receive_message() + { + $msg = ""; + $buffer = ""; + + while (true) { + $buffer = fread($this->socket, 4); + + if ($buffer === false) { + throw new \Exception("Error reading socket. " . socket_strerror(socket_last_error()) . "\n"); + } + + $len = self::ntohl($buffer); + + if ($len == 0) { + break; + } + + if ($len > 0 && $len < 1000000) { + $buffer = fread($this->socket, $len); + $msg .= $buffer; + } elseif ($len < 0) { + // signal received + switch ($len) { + case self::BNET_EOD: + if($this->config['debug']) { + echo "Got BNET_EOD\n"; + } + return $msg; + case self::BNET_EOD_POLL: + break; + case self::BNET_STATUS: + break; + case self::BNET_TERMINATE: + break; + case self::BNET_POLL: + break; + case self::BNET_HEARTBEAT: + break; + case self::BNET_HB_RESPONSE: + break; + case self::BNET_xxxxxxPROMPT: + break; + case self::BNET_BTIME: + break; + case self::BNET_BREAK: + break; + case self::BNET_START_SELECT: + break; + case self::BNET_END_SELECT: + break; + case self::BNET_INVALID_CMD: + break; + case self::BNET_CMD_FAILED: + break; + case self::BNET_CMD_OK: + break; + case self::BNET_CMD_BEGIN: + break; + case self::BNET_MSGS_PENDING: + break; + case self::BNET_MAIN_PROMPT: + if($this->config['debug']) { + echo "Got BNET_MAIN_PROMPT\n"; + } + return $msg; + case self::BNET_SELECT_INPUT: + break; + case self::BNET_WARNING_MSG: + break; + case self::BNET_ERROR_MSG: + break; + case self::BNET_INFO_MSG: + break; + case self::BNET_RUN_CMD: + break; + case self::BNET_YESNO: + break; + case self::BNET_START_RTREE: + break; + case self::BNET_END_RTREE: + break; + case self::BNET_SUB_PROMPT: + if($this->config['debug']) { + echo "Got BNET_SUB_PROMPT\n"; + } + return $msg; + case self::BNET_TEXT_INPUT: + break; + default: + throw new \Exception("Received unknown signal " . $len . "\n"); + break; + } + } else { + throw new \Exception("Received illegal packet of size " . $len . "\n"); + } + } + + return $msg; + } + + + /** + * Connect to a Bareos Director, authenticate the session and establish TLS if needed. + * + * @return boolean + */ + private function connect() + { + if (!isset($this->config['host']) or !isset($this->config['port'])) { + return false; + } + + $port = $this->config['port']; + $remote = "tcp://" . $this->config['host'] . ":" . $port; + + $context = stream_context_create(); + + /* + * It only makes sense to setup the whole TLS context when we as client support or + * demand a TLS connection. + */ + if ($this->config['client_can_do_tls'] || $this->config['client_requires_tls']) { + /* + * We verify the peer ourself so the normal stream layer doesn't need to. + * But that does mean we need to capture the certficate. + */ + $result = stream_context_set_option($context, 'ssl', 'verify_peer', false); + $result = stream_context_set_option($context, 'ssl', 'capture_peer_cert', true); + + /* + * Setup a CA file + */ + if (!empty($this->config['ca_file'])) { + $result = stream_context_set_option($context, 'ssl', 'cafile', $this->config['ca_file']); + if ($this->config['tls_verify_peer']) { + $result = stream_context_set_option($context, 'ssl', 'verify_peer', true); + } + } else { + $result = stream_context_set_option($context, 'ssl', 'allow_self_signed', true); + } + + /* + * Cert file which needs to contain the client certificate and the key in PEM encoding. + */ + if (!empty($this->config['cert_file'])) { + $result = stream_context_set_option($context, 'ssl', 'local_cert', $this->config['cert_file']); + + /* + * Passphrase needed to unlock the above cert file. + */ + if (!empty($this->config['cert_file_passphrase'])) { + $result = stream_context_set_option($context, 'ssl', 'passphrase', $this->config['cert_file_passphrase']); + } + } + } + + $this->socket = stream_socket_client($remote, $error, $errstr, 60, + STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $context); + if (!$this->socket) { + throw new \Exception("Error Connecting Socket: " . $errstr . "\n"); + } + + if($this->config['debug']) { + echo "Connected to " . $this->config['host'] . " on port " . $this->config['port'] . "\n"; + } + + if (!self::login()) { + return false; + } + + if (($this->config['server_can_do_tls'] || $this->config['server_requires_tls']) && + ($this->config['client_can_do_tls'] || $this->config['client_requires_tls'])) { + $result = stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + if (!$result) { + throw new \Exception("Error in TLS handshake\n"); + } + } + + if ($this->config['tls_verify_peer']) { + if (!empty($this->config['allowed_cns'])) { + if (!self::tls_postconnect_verify_cn()) { + throw new \Exception("Error in TLS postconnect verify CN\n"); + } + } else { + if (!self::tls_postconnect_verify_host()) { + throw new \Exception("Error in TLS postconnect verify host\n"); + } + } + } + + /* + * Get the 1000 OK: xx-dir Version: ... + */ + $recv = self::receive(); + + if($this->config['debug']) { + echo($recv); + } + + return true; + } + + /** + * Disconnect a connected console session + * + * @return boolean + */ + private function disconnect() + { + fclose($this->socket); + if($this->config['debug']) { + echo "Connection to " . $this->config['host'] . " on port " . $this->config['port'] . " closed\n"; + } + return true; + } + + /** + * Login into a Bareos Director e.g. authenticate the console session + * + * @return boolean + */ + private function login() + { + if(isset($this->config['console_name'])) { + $bashed_console_name = self::bash_spaces($this->config['console_name']); + $DIR_HELLO = "Hello " . $bashed_console_name . " calling\n"; + } else { + $DIR_HELLO = "Hello *UserAgent* calling\n"; + } + + self::send($DIR_HELLO); + $recv = self::receive(); + + self::cram_md5_response($recv, $this->config['password']); + $recv = self::receive(); + + if(strncasecmp($recv, self::DIR_AUTH_FAILED, strlen(self::DIR_AUTH_FAILED)) == 0) { + throw new \Exception("Failed to authenticate with Director\n"); + } elseif(strncasecmp($recv, self::DIR_OK_AUTH, strlen(self::DIR_OK_AUTH)) == 0) { + return self::cram_md5_challenge($this->config['password']); + } else { + throw new \Exception("Unknown response to authentication by Director $recv\n"); + } + + } + + /** + * Verify the CN of the certificate against a list of allowed CN names. + * + * @return boolean + */ + private function tls_postconnect_verify_cn() + { + $options = stream_context_get_options($this->socket); + + if (isset($options['ssl']) && isset($options['ssl']['peer_certificate'])) { + $cert_data = openssl_x509_parse($options["ssl"]["peer_certificate"]); + + if ($this->config['debug']) { + print_r($cert_data); + } + + if (isset($cert_data['subject']['CN'])) { + $common_names = $cert_data['subject']['CN']; + if ($this->config['debug']) { + echo("CommonNames: " . $common_names . "\n"); + } + } + + if (isset($common_names)) { + $checks = explode(',', $common_names); + + foreach($checks as $check) { + $allowed_cns = explode(',', $this->config['allowed_cns']); + foreach($allowed_cns as $allowed_cn) { + if (strcasecmp($check, $allowed_cn) == 0) { + return true; + } + } + } + } + } + + return false; + } + + /** + * Verify TLS names + * + * @param $names + * @return boolean + */ + private function verify_tls_name($names) + { + $hostname = $this->config['host']; + $checks = explode(',', $names); + + $tmp = explode('.', $hostname); + $rev_hostname = array_reverse($tmp); + $ok = false; + + foreach($checks as $check) { + $tmp = explode(':', $check); + + /* + * Candidates must start with DNS: + */ + if ($tmp[0] != 'DNS') { + continue; + } + + /* + * and have something afterwards + */ + if (!isset($tmp[1])) { + continue; + } + + $tmp = explode('.', $tmp[1]); + + /* + * "*.com" is not a valid match + */ + if (count($tmp) < 3) { + continue; + } + + $cand = array_reverse($tmp); + $ok = true; + + foreach($cand as $i => $item) { + if (!isset($rev_hostname[$i])) { + $ok = false; + break; + } + + if ($rev_hostname[$i] == $item) { + continue; + } + + if ($item == '*') { + break; + } + } + + if ($ok) { + break; + } + } + + return $ok; + } + + /** + * Verify the subjectAltName or CN of the certificate against the hostname we are connecting to. + * + * @return boolean + */ + private function tls_postconnect_verify_host() + { + $options = stream_context_get_options($this->socket); + + if (isset($options['ssl']) && isset($options['ssl']['peer_certificate'])) { + $cert_data = openssl_x509_parse($options["ssl"]["peer_certificate"]); + + if ($this->config['debug']) { + print_r($cert_data); + } + + /* + * Check subjectAltName extensions first. + */ + if (isset($cert_data['extensions'])) { + if (isset($cert_data['extensions']['subjectAltName'])) { + $alt_names = $cert_data['extensions']['subjectAltName']; + if ($this->config['debug']) { + echo("AltNames: " . $alt_names . "\n"); + } + + if (self::verify_tls_name($alt_names)) { + return true; + } + } + } + + /* + * Try verifying against the subject name. + */ + if (isset($cert_data['subject']['CN'])) { + $common_names = "DNS:" . $cert_data['subject']['CN']; + if ($this->config['debug']) { + echo("CommonNames: " . $common_names . "\n"); + } + + if (self::verify_tls_name($common_names)) { + return true; + } + } + } + + return false; + } + + /** + * Perform a CRAM MD5 response + * + * @param $recv + * @param $password + * @return boolean + */ + private function cram_md5_response($recv, $password) + { + list($chal, $ssl) = sscanf($recv, "auth cram-md5 %s ssl=%d"); + + switch($ssl) { + case self::BNET_TLS_OK: + $this->config['server_can_do_tls'] = true; + break; + case self::BNET_TLS_REQUIRED: + $this->config['server_requires_tls'] = true; + break; + default: + $this->config['server_can_do_tls'] = false; + $this->config['server_requires_tls'] = false; + break; + } + + $m = hash_hmac('md5', $chal, md5($password), true); + $msg = rtrim(base64_encode($m), "="); + + self::send($msg); + + return true; + } + + /** + * Perform a CRAM MD5 challenge + * + * @param $password + * @return boolean + */ + private function cram_md5_challenge($password) + { + $rand = rand(1000000000, 9999999999); + $time = time(); + $clientname = "php-bsock"; + $client = "<" . $rand . "." . $time . "@" . $clientname . ">"; + + if($this->config['client_requires_tls']) { + $DIR_AUTH = sprintf("auth cram-md5 %s ssl=%d\n", $client, self::BNET_TLS_REQUIRED); + } elseif($this->config['client_can_do_tls']) { + $DIR_AUTH = sprintf("auth cram-md5 %s ssl=%d\n", $client, self::BNET_TLS_OK); + } else { + $DIR_AUTH = sprintf("auth cram-md5 %s ssl=%d\n", $client, self::BNET_TLS_NONE); + } + + if(self::send($DIR_AUTH) == true) { + $recv = self::receive(); + $m = hash_hmac('md5', $client, md5($password), true); + + $b64 = new BareosBase64(); + $msg = rtrim( $b64->encode($m, false), "=" ); + + if (self::send(self::DIR_OK_AUTH) == true && strcmp(trim($recv), trim($msg)) == 0) { + return true; + } else { + return false; + } + } else { + return false; + } + + } + + /** + * Send a single command + * + * @param $cmd + * @return string + */ + public function send_command($cmd) + { + $result = ""; + if(self::send($cmd)) { + $result = self::receive_message(); + self::disconnect(); + } + return $result; + } + +} +?> diff --git a/vendor/Bareos/library/Bareos/BSock/BareosBase64.php b/vendor/Bareos/library/Bareos/BSock/BareosBase64.php new file mode 100644 index 00000000..a117982a --- /dev/null +++ b/vendor/Bareos/library/Bareos/BSock/BareosBase64.php @@ -0,0 +1,108 @@ +. + * + */ +namespace Bareos\BSock; + +class BareosBase64 +{ + + private $base64_digits = array( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'); + + private $encoded = ""; + + /** + * base64 encoding + * @param $arg + * @param $compatible (true=standard / false=non-standard) + * @return string + */ + public function encode($arg, $compatible=false) + { + if (strlen($arg) <= 0) { + return false; + } else { + if ($compatible) { + $this->encoded = base64_encode($arg); + } else { + $this->encoded = self::to_bareos_base64($arg); + } + } + return $this->encoded; + } + + /** + * Computes the 2's complement + */ + private function twos_comp($val, $bits) + { + if ( ($val & (1 << ($bits - 1) )) != 0 ) + $val = $val - (1 << $bits); + return $val; + } + + /** + * Bareos base64 encoding + * @param $arg + */ + private function to_bareos_base64($arg) + { + $reg = 0; + $rem = 0; + $save = 0; + $mask = 0; + $len = strlen($arg); + $buffer = ""; + + for ( $i = 0; $i < $len; ) { + if ($rem < 6) { + $reg <<= 8; + $t = ord( $arg[$i++] ); + if ($t > 127) { + $t = $this->twos_comp($t, 8); + } + $reg |= $t; + $rem += 8; + } + $save = $reg; + $reg >>= ($rem - 6); + $tmp = $reg & 0x3F; + $buffer .= $this->base64_digits[$tmp]; + $reg = $save; + $rem -= 6; + } + + $mask = (1 << $rem) - 1; + $buffer .= $this->base64_digits[$reg & $mask]; + + return $buffer; + } + +} + +?> diff --git a/vendor/Bareos/library/Bareos/Db/Sql/BareosSqlCompatHelper.php b/vendor/Bareos/library/Bareos/Db/Sql/BareosSqlCompatHelper.php index b9970231..2d9080ba 100644 --- a/vendor/Bareos/library/Bareos/Db/Sql/BareosSqlCompatHelper.php +++ b/vendor/Bareos/library/Bareos/Db/Sql/BareosSqlCompatHelper.php @@ -1,5 +1,27 @@ . + * + */ namespace Bareos\Db\Sql; class BareosSqlCompatHelper