diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control
index 67cd410a32..096aa04464 100644
--- a/pandora_agents/unix/DEBIAN/control
+++ b/pandora_agents/unix/DEBIAN/control
@@ -1,5 +1,5 @@
package: pandorafms-agent-unix
-Version: 7.0NG.738-190923
+Version: 7.0NG.738-190924
Architecture: all
Priority: optional
Section: admin
diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh
index 385336710c..8bd3a13ac4 100644
--- a/pandora_agents/unix/DEBIAN/make_deb_package.sh
+++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh
@@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-pandora_version="7.0NG.738-190923"
+pandora_version="7.0NG.738-190924"
echo "Test if you has the tools for to make the packages."
whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null
diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent
index eafeb00e78..8fff744779 100755
--- a/pandora_agents/unix/pandora_agent
+++ b/pandora_agents/unix/pandora_agent
@@ -42,7 +42,7 @@ my $Sem = undef;
my $ThreadSem = undef;
use constant AGENT_VERSION => '7.0NG.738';
-use constant AGENT_BUILD => '190923';
+use constant AGENT_BUILD => '190924';
# Agent log default file size maximum and instances
use constant DEFAULT_MAX_LOG_SIZE => 600000;
diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec
index f189eea490..7e2e74d76c 100644
--- a/pandora_agents/unix/pandora_agent.redhat.spec
+++ b/pandora_agents/unix/pandora_agent.redhat.spec
@@ -3,7 +3,7 @@
#
%define name pandorafms_agent_unix
%define version 7.0NG.738
-%define release 190923
+%define release 190924
Summary: Pandora FMS Linux agent, PERL version
Name: %{name}
diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec
index 561e65e18a..f85e093ffa 100644
--- a/pandora_agents/unix/pandora_agent.spec
+++ b/pandora_agents/unix/pandora_agent.spec
@@ -3,7 +3,7 @@
#
%define name pandorafms_agent_unix
%define version 7.0NG.738
-%define release 190923
+%define release 190924
Summary: Pandora FMS Linux agent, PERL version
Name: %{name}
diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer
index 1c0ee8ad1d..3966e0d83d 100755
--- a/pandora_agents/unix/pandora_agent_installer
+++ b/pandora_agents/unix/pandora_agent_installer
@@ -10,7 +10,7 @@
# **********************************************************************
PI_VERSION="7.0NG.738"
-PI_BUILD="190923"
+PI_BUILD="190924"
OS_NAME=`uname -s`
FORCE=0
diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi
index b8f1bcf5e7..faf6b9ab3f 100644
--- a/pandora_agents/win32/installer/pandora.mpi
+++ b/pandora_agents/win32/installer/pandora.mpi
@@ -186,7 +186,7 @@ UpgradeApplicationID
{}
Version
-{190923}
+{190924}
ViewReadme
{Yes}
diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc
index 9b445b24aa..1abef1dbf8 100644
--- a/pandora_agents/win32/pandora.cc
+++ b/pandora_agents/win32/pandora.cc
@@ -30,7 +30,7 @@ using namespace Pandora;
using namespace Pandora_Strutils;
#define PATH_SIZE _MAX_PATH+1
-#define PANDORA_VERSION ("7.0NG.738(Build 190923)")
+#define PANDORA_VERSION ("7.0NG.738(Build 190924)")
string pandora_path;
string pandora_dir;
diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc
index b185cf6fec..7c460efe3e 100644
--- a/pandora_agents/win32/versioninfo.rc
+++ b/pandora_agents/win32/versioninfo.rc
@@ -11,7 +11,7 @@ BEGIN
VALUE "LegalCopyright", "Artica ST"
VALUE "OriginalFilename", "PandoraAgent.exe"
VALUE "ProductName", "Pandora FMS Windows Agent"
- VALUE "ProductVersion", "(7.0NG.738(Build 190923))"
+ VALUE "ProductVersion", "(7.0NG.738(Build 190924))"
VALUE "FileVersion", "1.0.0.0"
END
END
diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control
index d883d99eac..287b9c842a 100644
--- a/pandora_console/DEBIAN/control
+++ b/pandora_console/DEBIAN/control
@@ -1,5 +1,5 @@
package: pandorafms-console
-Version: 7.0NG.738-190923
+Version: 7.0NG.738-190924
Architecture: all
Priority: optional
Section: admin
diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh
index 6ed2c0da18..bab5cdc815 100644
--- a/pandora_console/DEBIAN/make_deb_package.sh
+++ b/pandora_console/DEBIAN/make_deb_package.sh
@@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-pandora_version="7.0NG.738-190923"
+pandora_version="7.0NG.738-190924"
package_pear=0
package_pandora=1
diff --git a/pandora_console/godmode/groups/credential_store.php b/pandora_console/godmode/groups/credential_store.php
index 3273e1c038..46d1a929b7 100644
--- a/pandora_console/godmode/groups/credential_store.php
+++ b/pandora_console/godmode/groups/credential_store.php
@@ -29,599 +29,43 @@
// Begin.
global $config;
-// Check access.
-check_login();
+require_once $config['homedir'].'/include/class/CredentialStore.class.php';
-if (! check_acl($config['id_user'], 0, 'PM')) {
- db_pandora_audit(
- 'ACL Violation',
- 'Trying to access event viewer'
- );
+$ajaxPage = 'godmode/groups/credential_store';
+// Control call flow.
+try {
+ // User access and validation is being processed on class constructor.
+ $cs = new CredentialStore($ajaxPage);
+} catch (Exception $e) {
if (is_ajax()) {
- return ['error' => 'noaccess'];
+ echo json_encode(['error' => '[CredentialStore]'.$e->getMessage() ]);
+ exit;
+ } else {
+ echo '[CredentialStore]'.$e->getMessage();
}
- include 'general/noaccess.php';
+ // Stop this execution, but continue 'globally'.
return;
}
-// Required files.
-ui_require_css_file('credential_store');
-require_once $config['homedir'].'/include/functions_credential_store.php';
-require_once $config['homedir'].'/include/functions_io.php';
-
+// AJAX controller.
if (is_ajax()) {
- $draw = get_parameter('draw', 0);
- $filter = get_parameter('filter', []);
- $get_key = get_parameter('get_key', 0);
- $new_form = get_parameter('new_form', 0);
- $new_key = get_parameter('new_key', 0);
- $update_key = get_parameter('update_key', 0);
- $delete_key = get_parameter('delete_key', 0);
+ $method = get_parameter('method');
- if ($new_form) {
- echo print_inputs();
- exit;
- }
-
- if ($delete_key) {
- $identifier = get_parameter('identifier', null);
-
- if (empty($identifier)) {
- ajax_msg('error', __('identifier cannot be empty'));
- }
-
- if (db_process_sql_delete(
- 'tcredential_store',
- ['identifier' => $identifier]
- ) === false
- ) {
- ajax_msg('error', $config['dbconnection']->error, true);
+ if (method_exists($cs, $method) === true) {
+ if ($cs->ajaxMethod($method) === true) {
+ $cs->{$method}();
} else {
- ajax_msg('result', $identifier, true);
+ $cs->error('Unavailable method.');
}
+ } else {
+ $cs->error('Method not found. ['.$method.']');
}
- if ($update_key) {
- $data = get_parameter('values', null);
-
- if ($data === null || !is_array($data)) {
- echo json_encode(['error' => __('Invalid parameters, please retry')]);
- exit;
- }
-
- $values = [];
- foreach ($data as $key => $value) {
- if ($key == 'identifier') {
- $identifier = base64_decode($value);
- } else if ($key == 'product') {
- $product = base64_decode($value);
- } else {
- $values[$key] = base64_decode($value);
- }
- }
-
- if (empty($identifier)) {
- ajax_msg('error', __('identifier cannot be empty'));
- }
-
- if (empty($product)) {
- ajax_msg('error', __('product cannot be empty'));
- }
-
- if (db_process_sql_update(
- 'tcredential_store',
- $values,
- ['identifier' => $identifier]
- ) === false
- ) {
- ajax_msg('error', $config['dbconnection']->error);
- } else {
- ajax_msg('result', $identifier);
- }
-
- exit;
- }
-
- if ($new_key) {
- $data = get_parameter('values', null);
-
- if ($data === null || !is_array($data)) {
- echo json_encode(['error' => __('Invalid parameters, please retry')]);
- exit;
- }
-
- $values = [];
- foreach ($data as $key => $value) {
- $values[$key] = base64_decode($value);
- if ($key == 'identifier') {
- $values[$key] = preg_replace('/\s+/', '-', trim($values[$key]));
- }
- }
-
- $identifier = $values['identifier'];
-
- if (empty($identifier)) {
- ajax_msg('error', __('identifier cannot be empty'));
- }
-
- if (empty($values['product'])) {
- ajax_msg('error', __('product cannot be empty'));
- }
-
- if (db_process_sql_insert('tcredential_store', $values) === false) {
- ajax_msg('error', $config['dbconnection']->error);
- } else {
- ajax_msg('result', $identifier);
- }
-
- exit;
- }
-
- if ($get_key) {
- $identifier = get_parameter('identifier', null);
-
- $key = get_key($identifier);
- echo print_inputs($key);
-
- exit;
- }
-
- if ($draw) {
- // Datatables offset, limit and order.
- $start = get_parameter('start', 0);
- $length = get_parameter('length', $config['block_size']);
- $order = get_datatable_order(true);
- try {
- ob_start();
-
- $fields = [
- 'cs.*',
- 'tg.nombre as `group`',
- ];
-
- // Retrieve data.
- $data = credentials_get_all(
- // Fields.
- $fields,
- // Filter.
- $filter,
- // Offset.
- $start,
- // Limit.
- $length,
- // Order.
- $order['direction'],
- // Sort field.
- $order['field']
- );
-
- // Retrieve counter.
- $count = credentials_get_all(
- 'count',
- $filter
- );
-
- if ($data) {
- $data = array_reduce(
- $data,
- function ($carry, $item) {
- // Transforms array of arrays $data into an array
- // of objects, making a post-process of certain fields.
- $tmp = (object) $item;
- $tmp->username = io_safe_output($tmp->username);
-
- if (empty($tmp->group)) {
- $tmp->group = __('All');
- } else {
- $tmp->group = io_safe_output($tmp->group);
- }
-
- $carry[] = $tmp;
- return $carry;
- }
- );
- }
-
- // Datatables format: RecordsTotal && recordsfiltered.
- echo json_encode(
- [
- 'data' => $data,
- 'recordsTotal' => $count,
- 'recordsFiltered' => $count,
- ]
- );
- // Capture output.
- $response = ob_get_clean();
- } catch (Exception $e) {
- return json_encode(['error' => $e->getMessage()]);
- }
-
- // If not valid, show error with issue.
- json_decode($response);
- if (json_last_error() == JSON_ERROR_NONE) {
- // If valid dump.
- echo $response;
- } else {
- echo json_encode(
- ['error' => $response]
- );
- }
-
-
- exit;
- }
-
+ // Stop any execution.
exit;
+} else {
+ // Run.
+ $cs->run();
}
-
-// Datatables list.
-try {
- $columns = [
- 'group',
- 'identifier',
- 'product',
- 'username',
- 'options',
- ];
-
- $column_names = [
- __('Group'),
- __('Identifier'),
- __('Product'),
- __('User'),
- [
- 'text' => __('Options'),
- 'class' => 'action_buttons',
- ],
- ];
-
- $table_id = 'keystore';
- // Load datatables user interface.
- ui_print_datatable(
- [
- 'id' => $table_id,
- 'class' => 'info_table',
- 'style' => 'width: 100%',
- 'columns' => $columns,
- 'column_names' => $column_names,
- 'ajax_url' => 'godmode/groups/credential_store',
- 'ajax_postprocess' => 'process_datatables_item(item)',
- 'no_sortable_columns' => [-1],
- 'order' => [
- 'field' => 'identifier',
- 'direction' => 'asc',
- ],
- 'search_button_class' => 'sub filter float-right',
- 'form' => [
- 'inputs' => [
- [
- 'label' => __('Group'),
- 'type' => 'select',
- 'id' => 'filter_id_group',
- 'name' => 'filter_id_group',
- 'options' => users_get_groups_for_select(
- $config['id_user'],
- 'AR',
- true,
- true,
- false
- ),
- ],
- [
- 'label' => __('Free search'),
- 'type' => 'text',
- 'class' => 'mw250px',
- 'id' => 'free_search',
- 'name' => 'free_search',
- ],
- ],
- ],
- ]
- );
-} catch (Exception $e) {
- echo $e->getMessage();
-}
-
-// Auxiliar div.
-$new = '
';
-$details = '';
-$aux = '';
-
-
-echo $new.$details.$aux;
-
-// Create button.
-echo '';
-html_print_submit_button(
- __('Add key'),
- 'create',
- false,
- 'class="sub next"'
-);
-echo '
';
-
-?>
-
-
diff --git a/pandora_console/include/class/CredentialStore.class.php b/pandora_console/include/class/CredentialStore.class.php
new file mode 100644
index 0000000000..188950d92a
--- /dev/null
+++ b/pandora_console/include/class/CredentialStore.class.php
@@ -0,0 +1,1203 @@
+AJAXMethods);
+ }
+
+
+ /**
+ * Generates a JSON error.
+ *
+ * @param string $msg Error message.
+ *
+ * @return void
+ */
+ public function error($msg)
+ {
+ echo json_encode(
+ ['error' => $msg]
+ );
+ }
+
+
+ /**
+ * Minor function to dump json message as ajax response.
+ *
+ * @param string $type Type: result || error.
+ * @param string $msg Message.
+ * @param boolean $delete Deletion messages.
+ *
+ * @return void
+ */
+ private function ajaxMsg($type, $msg, $delete=false)
+ {
+ $msg_err = 'Failed while saving: %s';
+ $msg_ok = 'Successfully saved into keystore ';
+
+ if ($delete) {
+ $msg_err = 'Failed while removing: %s';
+ $msg_ok = 'Successfully deleted ';
+ }
+
+ if ($type == 'error') {
+ echo json_encode(
+ [
+ $type => ui_print_error_message(
+ __(
+ $msg_err,
+ $msg
+ ),
+ '',
+ true
+ ),
+ ]
+ );
+ } else {
+ echo json_encode(
+ [
+ $type => ui_print_success_message(
+ __(
+ $msg_ok,
+ $msg
+ ),
+ '',
+ true
+ ),
+ ]
+ );
+ }
+
+ exit;
+ }
+
+
+ /**
+ * Initializes object and validates user access.
+ *
+ * @param string $ajax_controller Path of ajaxController, is the 'page'
+ * variable sent in ajax calls.
+ *
+ * @return Object
+ */
+ public function __construct($ajax_controller)
+ {
+ global $config;
+
+ // Check access.
+ check_login();
+
+ if (! check_acl($config['id_user'], 0, 'AR')) {
+ db_pandora_audit(
+ 'ACL Violation',
+ 'Trying to access event viewer'
+ );
+
+ if (is_ajax()) {
+ echo json_encode(['error' => 'noaccess']);
+ }
+
+ include 'general/noaccess.php';
+ exit;
+ }
+
+ $this->ajaxController = $ajax_controller;
+
+ return $this;
+ }
+
+
+ /**
+ * Returns an array with all the credentials matching filter and ACL.
+ *
+ * @param array $fields Fields array or 'count' keyword to retrieve count.
+ * @param array $filter Filters to be applied.
+ * @param integer $offset Offset (pagination).
+ * @param integer $limit Limit (pagination).
+ * @param string $order Sort order.
+ * @param string $sort_field Sort field.
+ *
+ * @return array With all results or false if error.
+ * @throws Exception On error.
+ */
+ public static function getAll(
+ $fields,
+ $filter,
+ $offset=null,
+ $limit=null,
+ $order=null,
+ $sort_field=null
+ ) {
+ $sql_filters = [];
+ $order_by = '';
+ $pagination = '';
+
+ global $config;
+
+ if (!is_array($filter)) {
+ error_log('[credential_get_all] Filter must be an array.');
+ throw new Exception('[credential_get_all] Filter must be an array.');
+ }
+
+ $count = false;
+ if (!is_array($fields) && $fields == 'count') {
+ $fields = ['cs.*'];
+ $count = true;
+ } else if (!is_array($fields)) {
+ error_log('[credential_get_all] Fields must be an array or "count".');
+ throw new Exception('[credential_get_all] Fields must be an array or "count".');
+ }
+
+ if (isset($filter['product']) && !empty($filter['product'])) {
+ $sql_filters[] = sprintf(' AND cs.product = "%s"', $filter['product']);
+ }
+
+ if (isset($filter['free_search']) && !empty($filter['free_search'])) {
+ $sql_filters[] = vsprintf(
+ ' AND (lower(cs.username) like lower("%%%s%%")
+ OR cs.identifier like "%%%s%%"
+ OR lower(cs.product) like lower("%%%s%%"))',
+ array_fill(0, 3, $filter['free_search'])
+ );
+ }
+
+ if (isset($filter['filter_id_group']) && $filter['filter_id_group'] > 0) {
+ $propagate = db_get_value(
+ 'propagate',
+ 'tgrupo',
+ 'id_grupo',
+ $filter['filter_id_group']
+ );
+
+ if (!$propagate) {
+ $sql_filters[] = sprintf(
+ ' AND cs.id_group = %d ',
+ $filter['filter_id_group']
+ );
+ } else {
+ $groups = [ $filter['filter_id_group'] ];
+ $childrens = groups_get_childrens($id_group, null, true);
+ if (!empty($childrens)) {
+ foreach ($childrens as $child) {
+ $groups[] = (int) $child['id_grupo'];
+ }
+ }
+
+ $filter['filter_id_group'] = $groups;
+ $sql_filters[] = sprintf(
+ ' AND cs.id_group IN (%s) ',
+ join(',', $filter['filter_id_group'])
+ );
+ }
+ }
+
+ if (isset($filter['group_list']) && is_array($filter['group_list'])) {
+ $sql_filters[] = sprintf(
+ ' AND cs.id_group IN (%s) ',
+ join(',', $filter['group_list'])
+ );
+ } else if (users_is_admin() !== true) {
+ $user_groups = users_get_groups(
+ $config['id_user'],
+ 'AR'
+ );
+
+ // Always add group 'ALL' because 'ALL' group credentials
+ // must be available for all users.
+ if (is_array($user_groups) === true) {
+ $user_groups = ([0] + array_keys($user_groups));
+ } else {
+ $user_groups = [0];
+ }
+
+ $sql_filters[] = sprintf(
+ ' AND cs.id_group IN (%s) ',
+ join(',', $user_groups)
+ );
+ }
+
+ if (isset($filter['identifier'])) {
+ $sql_filters[] = sprintf(
+ ' AND cs.identifier = "%s" ',
+ $filter['identifier']
+ );
+ }
+
+ if (isset($order)) {
+ $dir = 'asc';
+ if ($order == 'desc') {
+ $dir = 'desc';
+ };
+
+ if (in_array(
+ $sort_field,
+ [
+ 'group',
+ 'identifier',
+ 'product',
+ 'username',
+ 'options',
+ ]
+ )
+ ) {
+ $order_by = sprintf(
+ 'ORDER BY `%s` %s',
+ $sort_field,
+ $dir
+ );
+ }
+ }
+
+ if (isset($limit) && $limit > 0
+ && isset($offset) && $offset >= 0
+ ) {
+ $pagination = sprintf(
+ ' LIMIT %d OFFSET %d ',
+ $limit,
+ $offset
+ );
+ }
+
+ $sql = sprintf(
+ 'SELECT %s
+ FROM tcredential_store cs
+ LEFT JOIN tgrupo tg
+ ON tg.id_grupo = cs.id_group
+ WHERE 1=1
+ %s
+ %s
+ %s',
+ join(',', $fields),
+ join(' ', $sql_filters),
+ $order_by,
+ $pagination
+ );
+
+ if ($count) {
+ $sql = sprintf('SELECT count(*) as n FROM ( %s ) tt', $sql);
+
+ return db_get_value_sql($sql);
+ }
+
+ return db_get_all_rows_sql($sql);
+ }
+
+
+ /**
+ * Retrieves target key from keystore or false in case of error.
+ *
+ * @param string $identifier Key identifier.
+ *
+ * @return array Key or false if error.
+ */
+ public static function getKey($identifier)
+ {
+ global $config;
+
+ if (empty($identifier)) {
+ return false;
+ }
+
+ $keys = self::getAll(
+ [
+ 'cs.*',
+ 'tg.nombre as `group`',
+ ],
+ ['identifier' => $identifier]
+ );
+
+ if (is_array($keys) === true) {
+ // Only 1 must exist.
+ $key = $keys[0];
+
+ // Decrypt content.
+ $key['username'] = io_output_password($key['username']);
+ $key['password'] = io_output_password($key['password']);
+
+ return $key;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Return all keys avaliable for current user.
+ *
+ * @param string $product Filter by product.
+ *
+ * @return array Keys or false if error.
+ */
+ public static function getKeys($product=false)
+ {
+ global $config;
+
+ if ($product !== false) {
+ $filter['product'] = $product;
+ }
+
+ $keys = self::getAll(
+ [
+ 'cs.*',
+ 'tg.nombre as `group`',
+ ],
+ $filter
+ );
+
+ if (is_array($keys) === true) {
+ // Improve usage and decode output.
+ $return = array_reduce(
+ $keys,
+ function ($carry, $item) {
+ $item['username'] = io_output_password($item['username']);
+ $item['password'] = io_output_password($item['password']);
+ $carry[$item['identifier']] = $item['identifier'];
+ return $carry;
+ }
+ );
+
+ return $return;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Ajax method invoked by datatables to draw content.
+ *
+ * @return void
+ */
+ public function draw()
+ {
+ // Datatables offset, limit and order.
+ $filter = get_parameter('filter', []);
+ $start = get_parameter('start', 0);
+ $length = get_parameter('length', $config['block_size']);
+ $order = get_datatable_order(true);
+ try {
+ ob_start();
+
+ $fields = [
+ 'cs.*',
+ 'tg.nombre as `group`',
+ ];
+
+ // Retrieve data.
+ $data = $this->getAll(
+ // Fields.
+ $fields,
+ // Filter.
+ $filter,
+ // Offset.
+ $start,
+ // Limit.
+ $length,
+ // Order.
+ $order['direction'],
+ // Sort field.
+ $order['field']
+ );
+
+ // Retrieve counter.
+ $count = $this->getAll(
+ 'count',
+ $filter
+ );
+
+ if ($data) {
+ $data = array_reduce(
+ $data,
+ function ($carry, $item) {
+ // Transforms array of arrays $data into an array
+ // of objects, making a post-process of certain fields.
+ $tmp = (object) $item;
+ $tmp->username = io_output_password($tmp->username);
+
+ if (empty($tmp->group)) {
+ $tmp->group = __('All');
+ } else {
+ $tmp->group = io_safe_output($tmp->group);
+ }
+
+ $carry[] = $tmp;
+ return $carry;
+ }
+ );
+ }
+
+ // Datatables format: RecordsTotal && recordsfiltered.
+ echo json_encode(
+ [
+ 'data' => $data,
+ 'recordsTotal' => $count,
+ 'recordsFiltered' => $count,
+ ]
+ );
+ // Capture output.
+ $response = ob_get_clean();
+ } catch (Exception $e) {
+ echo json_encode(['error' => $e->getMessage()]);
+ exit;
+ }
+
+ // If not valid, show error with issue.
+ json_decode($response);
+ if (json_last_error() == JSON_ERROR_NONE) {
+ // If valid dump.
+ echo $response;
+ } else {
+ echo json_encode(
+ ['error' => $response]
+ );
+ }
+
+ exit;
+ }
+
+
+ /**
+ * Prints inputs for modal "Add key".
+ *
+ * @return void
+ */
+ public function loadModal()
+ {
+ $identifier = get_parameter('identifier', null);
+ $key = self::getKey($identifier);
+
+ echo $this->printInputs($key);
+ }
+
+
+ /**
+ * Prepare variables received using form. AJAX environment only.
+ *
+ * @return array of values processed or false in case of error.
+ */
+ private function prepareKeyValues()
+ {
+ $identifier = get_parameter('identifier', null);
+ $id_group = get_parameter('id_group', null);
+ $product = get_parameter('product', null);
+ $username = get_parameter('username', null);
+ $password = get_parameter('password', null);
+ $extra_1 = get_parameter('extra_1', null);
+ $extra_2 = get_parameter('extra_2', null);
+
+ if (empty($identifier)) {
+ $error = __('Key identifier is required');
+ } else if ($id_group === null) {
+ $error = __('You must select a group where store this key!');
+ } else if (empty($product)) {
+ $error = __('You must specify a product type');
+ } else if (empty($username) && (empty($password))) {
+ $error = __('You must specify a username and/or password');
+ }
+
+ // Encrypt content (if needed).
+ $values = [
+ 'identifier' => $identifier,
+ 'id_group' => $id_group,
+ 'product' => $product,
+ 'username' => io_input_password($username),
+ 'password' => io_input_password($password),
+ 'extra_1' => $extra_1,
+ 'extra_2' => $extra_2,
+ ];
+
+ // Spaces are not allowed.
+ $values['identifier'] = preg_replace('/\s+/', '-', trim($identifier));
+
+ return $values;
+ }
+
+
+ /**
+ * Stores a key into credential store.
+ *
+ * @param array $values Key definition.
+ * @param string $identifier Update or create.
+ *
+ * @return boolean True if ok, false if not ok.
+ */
+ private function storeKey($values, $identifier=false)
+ {
+ if ($identifier === false) {
+ // New.
+ return db_process_sql_insert('tcredential_store', $values);
+ } else {
+ // Update.
+ return db_process_sql_update(
+ 'tcredential_store',
+ $values,
+ ['identifier' => $identifier]
+ );
+ }
+
+ }
+
+
+ /**
+ * Add a new key into Credential Store
+ *
+ * @return void
+ */
+ public function addKey()
+ {
+ global $config;
+
+ $values = $this->prepareKeyValues();
+
+ if ($this->storeKey($values) === false) {
+ $this->ajaxMsg('error', $config['dbconnection']->error);
+ } else {
+ $this->ajaxMsg('result', $values['identifier']);
+ }
+
+ exit;
+ }
+
+
+ /**
+ * Add a new key into Credential Store
+ *
+ * @return void
+ */
+ public function updateKey()
+ {
+ global $config;
+
+ $values = $this->prepareKeyValues();
+ $identifier = $values['identifier'];
+
+ if ($this->storeKey($values, $identifier) === false) {
+ $this->ajaxMsg('error', $config['dbconnection']->error);
+ } else {
+ $this->ajaxMsg('result', $identifier);
+ }
+
+ exit;
+ }
+
+
+ /**
+ * AJAX method. Delete key from keystore.
+ *
+ * @return void
+ */
+ public function deleteKey()
+ {
+ global $config;
+
+ $identifier = get_parameter('identifier', null);
+
+ if (empty($identifier)) {
+ $this->ajaxMsg('error', __('identifier cannot be empty'), true);
+ }
+
+ if (self::getKey($identifier) === false) {
+ // User has no grants to delete target key.
+ $this->ajaxMsg('error', __('Not allowed'), true);
+ }
+
+ if (db_process_sql_delete(
+ 'tcredential_store',
+ ['identifier' => $identifier]
+ ) === false
+ ) {
+ $this->ajaxMsg('error', $config['dbconnection']->error, true);
+ } else {
+ $this->ajaxMsg('result', $identifier, true);
+ }
+
+ }
+
+
+ /**
+ * Run CredentialStore (main page).
+ *
+ * @return void
+ */
+ public function run()
+ {
+ global $config;
+
+ // Require specific CSS and JS.
+ ui_require_css_file('wizard');
+ ui_require_css_file('discovery');
+ ui_require_css_file('credential_store');
+
+ if (!isset($config['encryption_passphrase'])) {
+ $url = 'https://pandorafms.com/docs/index.php?title=Pandora:Documentation_en:Password_Encryption';
+ if ($config['language'] == 'es') {
+ $url = 'https://pandorafms.com/docs/index.php?title=Pandora:Documentation_es:Cifrado_Contrase%C3%B1as';
+ }
+
+ ui_print_warning_message(
+ __(
+ 'Database encryption is not enabled. Credentials will be stored in plaintext. %s',
+ ''.__('How to configure encryption.').''
+ )
+ );
+ }
+
+ // Datatables list.
+ try {
+ $columns = [
+ 'group',
+ 'identifier',
+ 'product',
+ 'username',
+ 'options',
+ ];
+
+ $column_names = [
+ __('Group'),
+ __('Identifier'),
+ __('Product'),
+ __('User'),
+ [
+ 'text' => __('Options'),
+ 'class' => 'action_buttons',
+ ],
+ ];
+
+ $this->tableId = 'keystore';
+ // Load datatables user interface.
+ ui_print_datatable(
+ [
+ 'id' => $this->tableId,
+ 'class' => 'info_table',
+ 'style' => 'width: 100%',
+ 'columns' => $columns,
+ 'column_names' => $column_names,
+ 'ajax_url' => $this->ajaxController,
+ 'ajax_data' => ['method' => 'draw'],
+ 'ajax_postprocess' => 'process_datatables_item(item)',
+ 'no_sortable_columns' => [-1],
+ 'order' => [
+ 'field' => 'identifier',
+ 'direction' => 'asc',
+ ],
+ 'search_button_class' => 'sub filter float-right',
+ 'form' => [
+ 'inputs' => [
+ [
+ 'label' => __('Group'),
+ 'type' => 'select',
+ 'id' => 'filter_id_group',
+ 'name' => 'filter_id_group',
+ 'options' => users_get_groups_for_select(
+ $config['id_user'],
+ 'AR',
+ true,
+ true,
+ false
+ ),
+ ],
+ [
+ 'label' => __('Free search'),
+ 'type' => 'text',
+ 'class' => 'mw250px',
+ 'id' => 'free_search',
+ 'name' => 'free_search',
+ ],
+ ],
+ ],
+ ]
+ );
+ } catch (Exception $e) {
+ echo $e->getMessage();
+ }
+
+ // Auxiliar div.
+ $modal = '';
+ $msg = '';
+ $aux = '';
+
+ echo $modal.$msg.$aux;
+
+ // Create button.
+ echo '';
+ html_print_submit_button(
+ __('Add key'),
+ 'create',
+ false,
+ 'class="sub next"'
+ );
+ echo '
';
+
+ echo $this->loadJS();
+
+ }
+
+
+ /**
+ * Generates inputs for new/update forms.
+ *
+ * @param array $values Values or null.
+ *
+ * @return string Inputs.
+ */
+ public function printInputs($values=null)
+ {
+ if (!is_array($values)) {
+ $values = [];
+ }
+
+ $form = [
+ 'action' => '#',
+ 'id' => 'modal_form',
+ 'onsubmit' => 'return false;',
+ 'class' => 'modal',
+ 'extra' => 'autocomplete="new-password"',
+ ];
+
+ $inputs = [];
+
+ $inputs[] = [
+ 'label' => __('Identifier'),
+ 'id' => 'div-identifier',
+ 'arguments' => [
+ 'name' => 'identifier',
+ 'type' => 'text',
+ 'value' => $values['identifier'],
+ 'disabled' => (bool) $values['identifier'],
+ 'return' => true,
+ ],
+ ];
+
+ $inputs[] = [
+ 'label' => __('Group'),
+ 'arguments' => [
+ 'name' => 'id_group',
+ 'id' => 'id_group',
+ 'input_class' => 'flex-row',
+ 'type' => 'select_groups',
+ 'selected' => $values['id_group'],
+ 'return' => true,
+ 'class' => 'w50p',
+ ],
+ ];
+
+ $inputs[] = [
+ 'label' => __('Product'),
+ 'id' => 'div-product',
+ 'arguments' => [
+ 'name' => 'product',
+ 'input_class' => 'flex-row',
+ 'type' => 'select',
+ 'script' => 'calculate_inputs()',
+ 'fields' => [
+ 'CUSTOM' => __('Custom'),
+ 'AWS' => __('Aws'),
+ 'AZURE' => __('Azure'),
+ // 'GOOGLE' => __('Google'),
+ ],
+ 'selected' => (isset($values['product']) ? $values['product'] : 'CUSTOM'),
+ 'disabled' => (bool) $values['product'],
+ 'return' => true,
+ ],
+ ];
+
+ $user_label = __('Username');
+ $pass_label = __('Password');
+ $extra_1_label = __('Extra');
+ $extra_2_label = __('Extra (2)');
+ $extra1 = true;
+ $extra2 = true;
+
+ // Remember to update credential_store.php also.
+ switch ($values['product']) {
+ case 'AWS':
+ $user_label = __('Access key ID');
+ $pass_label = __('Secret access key');
+ $extra1 = false;
+ $extra2 = false;
+ break;
+
+ case 'AZURE':
+ $user_label = __('Account ID');
+ $pass_label = __('Application secret');
+ $extra_1_label = __('Tenant or domain name');
+ $extra_2_label = __('Subscription id');
+ break;
+
+ case 'GOOGLE':
+ // Need further investigation.
+ case 'CUSTOM':
+ $user_label = __('Account ID');
+ $pass_label = __('Password');
+ $extra1 = false;
+ $extra2 = false;
+ default:
+ // Use defaults.
+ break;
+ }
+
+ $inputs[] = [
+ 'label' => $user_label,
+ 'id' => 'div-username',
+ 'arguments' => [
+ 'name' => 'username',
+ 'input_class' => 'flex-row',
+ 'type' => 'text',
+ 'value' => $values['username'],
+ 'return' => true,
+ ],
+ ];
+
+ $inputs[] = [
+ 'label' => $pass_label,
+ 'id' => 'div-password',
+ 'arguments' => [
+ 'name' => 'password',
+ 'input_class' => 'flex-row',
+ 'type' => 'password',
+ 'value' => $values['password'],
+ 'return' => true,
+ ],
+ ];
+
+ if ($extra1) {
+ $inputs[] = [
+ 'label' => $extra_1_label,
+ 'id' => 'div-extra_1',
+ 'arguments' => [
+ 'name' => 'extra_1',
+ 'input_class' => 'flex-row',
+ 'type' => 'text',
+ 'value' => $values['extra_1'],
+ 'return' => true,
+ ],
+ ];
+ }
+
+ if ($extra2) {
+ $inputs[] = [
+ 'label' => $extra_2_label,
+ 'id' => 'div-extra_2',
+ 'arguments' => [
+ 'name' => 'extra_2',
+ 'input_class' => 'flex-row',
+ 'type' => 'text',
+ 'value' => $values['extra_2'],
+ 'return' => true,
+ 'display' => $extra2,
+ ],
+
+ ];
+ }
+
+ return $this->printForm(
+ [
+ 'form' => $form,
+ 'inputs' => $inputs,
+ ],
+ true
+ );
+ }
+
+
+ /**
+ * Loads JS content.
+ *
+ * @return string JS content.
+ */
+ public function loadJS()
+ {
+ ob_start();
+
+ // Javascript content.
+ ?>
+
+ 0) {
- $propagate = db_get_value(
- 'propagate',
- 'tgrupo',
- 'id_grupo',
- $filter['filter_id_group']
- );
-
- if (!$propagate) {
- $sql_filters[] = sprintf(
- ' AND cs.id_group = %d ',
- $filter['filter_id_group']
- );
- } else {
- $groups = [ $filter['filter_id_group'] ];
- $childrens = groups_get_childrens($id_group, null, true);
- if (!empty($childrens)) {
- foreach ($childrens as $child) {
- $groups[] = (int) $child['id_grupo'];
- }
- }
-
- $filter['filter_id_group'] = $groups;
- $sql_filters[] = sprintf(
- ' AND cs.id_group IN (%s) ',
- join(',', $filter['filter_id_group'])
- );
- }
- }
-
- if (isset($filter['group_list']) && is_array($filter['group_list'])) {
- $sql_filters[] = sprintf(
- ' AND cs.id_group IN (%s) ',
- join(',', $filter['group_list'])
- );
- }
-
- if (isset($order)) {
- $dir = 'asc';
- if ($order == 'desc') {
- $dir = 'desc';
- };
-
- if (in_array(
- $sort_field,
- [
- 'group',
- 'identifier',
- 'product',
- 'username',
- 'options',
- ]
- )
- ) {
- $order_by = sprintf(
- 'ORDER BY `%s` %s',
- $sort_field,
- $dir
- );
- }
- }
-
- if (isset($limit) && $limit > 0
- && isset($offset) && $offset >= 0
- ) {
- $pagination = sprintf(
- ' LIMIT %d OFFSET %d ',
- $limit,
- $offset
- );
- }
-
- $sql = sprintf(
- 'SELECT %s
- FROM tcredential_store cs
- LEFT JOIN tgrupo tg
- ON tg.id_grupo = cs.id_group
- WHERE 1=1
- %s
- %s
- %s',
- join(',', $fields),
- join(' ', $sql_filters),
- $order_by,
- $pagination
- );
-
- if ($count) {
- $sql = sprintf('SELECT count(*) as n FROM ( %s ) tt', $sql);
-
- return db_get_value_sql($sql);
- }
-
- return db_get_all_rows_sql($sql);
-}
-
-
-/**
- * Retrieves target key from keystore or false in case of error.
- *
- * @param string $identifier Key identifier.
- *
- * @return array Key or false if error.
- */
-function get_key($identifier)
-{
- return db_get_row_filter(
- 'tcredential_store',
- [ 'identifier' => $identifier ]
- );
-}
-
-
-/**
- * Minor function to dump json message as ajax response.
- *
- * @param string $type Type: result || error.
- * @param string $msg Message.
- * @param boolean $delete Deletion messages.
- *
- * @return void
- */
-function ajax_msg($type, $msg, $delete=false)
-{
- $msg_err = 'Failed while saving: %s';
- $msg_ok = 'Successfully saved into keystore ';
-
- if ($delete) {
- $msg_err = 'Failed while removing: %s';
- $msg_ok = 'Successfully deleted ';
- }
-
- if ($type == 'error') {
- echo json_encode(
- [
- $type => ui_print_error_message(
- __(
- $msg_err,
- $msg
- ),
- '',
- true
- ),
- ]
- );
- } else {
- echo json_encode(
- [
- $type => ui_print_success_message(
- __(
- $msg_ok,
- $msg
- ),
- '',
- true
- ),
- ]
- );
- }
-
- exit;
-}
-
-
-/**
- * Generates inputs for new/update forms.
- *
- * @param array $values Values or null.
- *
- * @return string Inputs.
- */
-function print_inputs($values=null)
-{
- if (!is_array($values)) {
- $values = [];
- }
-
- $return = '';
- $return .= html_print_input(
- [
- 'label' => __('Identifier'),
- 'name' => 'identifier',
- 'input_class' => 'flex-row',
- 'type' => 'text',
- 'value' => $values['identifier'],
- 'disabled' => (bool) $values['identifier'],
- 'return' => true,
- 'script' => 'alert(\'puta\')',
- ]
- );
- $return .= html_print_input(
- [
- 'label' => __('Group'),
- 'name' => 'id_group',
- 'id' => 'id_group',
- 'input_class' => 'flex-row',
- 'type' => 'select_groups',
- 'selected' => $values['id_group'],
- 'return' => true,
- 'class' => 'w50p',
- ]
- );
- $return .= html_print_input(
- [
- 'label' => __('Product'),
- 'name' => 'product',
- 'input_class' => 'flex-row',
- 'type' => 'select',
- 'script' => 'calculate_inputs()',
- 'fields' => [
- 'CUSTOM' => __('Custom'),
- 'AWS' => __('Aws'),
- 'AZURE' => __('Azure'),
- // 'GOOGLE' => __('Google'),
- ],
- 'selected' => $values['product'],
- 'disabled' => (bool) $values['product'],
- 'return' => true,
- ]
- );
- $user_label = __('Username');
- $pass_label = __('Password');
- $extra_1_label = __('Extra');
- $extra_2_label = __('Extra (2)');
- $extra1 = true;
- $extra2 = true;
-
- // Remember to update credential_store.php also.
- switch ($values['product']) {
- case 'AWS':
- $user_label = __('Access key ID');
- $pass_label = __('Secret access key');
- $extra1 = false;
- $extra2 = false;
- break;
-
- case 'AZURE':
- $user_label = __('Account ID');
- $pass_label = __('Application secret');
- $extra_1_label = __('Tenant or domain name');
- $extra_2_label = __('Subscription id');
- break;
-
- case 'GOOGLE':
- // Need further investigation.
- case 'CUSTOM':
- $user_label = __('Account ID');
- $pass_label = __('Password');
- $extra1 = false;
- $extra2 = false;
- default:
- // Use defaults.
- break;
- }
-
- $return .= html_print_input(
- [
- 'label' => $user_label,
- 'name' => 'username',
- 'input_class' => 'flex-row',
- 'type' => 'text',
- 'value' => $values['username'],
- 'return' => true,
- ]
- );
- $return .= html_print_input(
- [
- 'label' => $pass_label,
- 'name' => 'password',
- 'input_class' => 'flex-row',
- 'type' => 'password',
- 'value' => $values['password'],
- 'return' => true,
- ]
- );
- if ($extra1) {
- $return .= html_print_input(
- [
- 'label' => $extra_1_label,
- 'name' => 'extra_1',
- 'input_class' => 'flex-row',
- 'type' => 'text',
- 'value' => $values['extra_1'],
- 'return' => true,
- ]
- );
- }
-
- if ($extra2) {
- $return .= html_print_input(
- [
- 'label' => $extra_2_label,
- 'name' => 'extra_2',
- 'input_class' => 'flex-row',
- 'type' => 'text',
- 'value' => $values['extra_2'],
- 'return' => true,
- 'display' => $extra2,
- ]
- );
- }
-
- return $return;
-}
-
-
-/**
- * Retrieve all identifiers available for current user.
- *
- * @param string $product Target product.
- *
- * @return array Of account identifiers.
- */
-function credentials_list_accounts($product)
-{
- global $config;
-
- check_login();
-
- include_once $config['homedir'].'/include/functions_users.php';
-
- static $user_groups;
-
- if (!isset($user_groups)) {
- $user_groups = users_get_groups(
- $config['id_user'],
- 'AR'
- );
-
- // Always add group 'ALL' because 'ALL' group credentials
- // must be available for all users.
- if (is_array($user_groups)) {
- $user_groups = ([0] + array_keys($user_groups));
- } else {
- $user_groups = [0];
- }
- }
-
- $creds = credentials_get_all(
- ['identifier'],
- [
- 'product' => $product,
- 'group_list' => $user_groups,
- ]
- );
-
- if ($creds === false) {
- return [];
- }
-
- $ret = array_reduce(
- $creds,
- function ($carry, $item) {
- $carry[$item['identifier']] = $item['identifier'];
- return $carry;
- }
- );
-
- return $ret;
-}
+// Deprecated.
diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php
index ffb36aa3ae..75533f7f56 100644
--- a/pandora_console/include/functions_events.php
+++ b/pandora_console/include/functions_events.php
@@ -2739,6 +2739,10 @@ function events_get_agent(
$date = time_w_fixed_tz($date);
}
+ if (is_metaconsole() && $events_group === false) {
+ $id_server = true;
+ }
+
if (empty($date)) {
$date = get_system_time();
}
diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php
index 5fa4824a1e..12d4aecc01 100644
--- a/pandora_console/include/functions_html.php
+++ b/pandora_console/include/functions_html.php
@@ -1475,6 +1475,14 @@ function html_print_input_password(
$attr['class'] = $class;
}
+ if ($disabled === false) {
+ // Trick to avoid password completion on most browsers.
+ if ($autocomplete !== 'on') {
+ $disabled = true;
+ $attr['onfocus'] = "this.removeAttribute('readonly');";
+ }
+ }
+
return html_print_input_text_extended($name, $value, 'password-'.$name, $alt, $size, $maxlength, $disabled, '', $attr, $return, true, '', $autocomplete);
}
diff --git a/pandora_console/include/functions_io.php b/pandora_console/include/functions_io.php
index 32c66ca1e3..baddb18531 100755
--- a/pandora_console/include/functions_io.php
+++ b/pandora_console/include/functions_io.php
@@ -507,7 +507,7 @@ function ___($string /*, variable arguments */)
}
-/*
+/**
* json_encode for multibyte characters.
*
* @param string Text string to be encoded.
@@ -528,7 +528,7 @@ function io_json_mb_encode($string, $encode_options=0)
}
-/*
+/**
* Prepare the given password to be stored in the Pandora FMS Database,
* encrypting it if necessary.
*
@@ -541,16 +541,22 @@ function io_input_password($password)
global $config;
enterprise_include_once('include/functions_crypto.php');
- $ciphertext = enterprise_hook('openssl_encrypt_decrypt', ['encrypt', io_safe_output($password)]);
+ $ciphertext = enterprise_hook(
+ 'openssl_encrypt_decrypt',
+ [
+ 'encrypt',
+ io_safe_input($password),
+ ]
+ );
if ($ciphertext === ENTERPRISE_NOT_HOOK) {
- return $password;
+ return io_safe_input($password);
}
return $ciphertext;
}
-/*
+/**
* Process the given password read from the Pandora FMS Database,
* decrypting it if necessary.
*
@@ -563,10 +569,17 @@ function io_output_password($password)
global $config;
enterprise_include_once('include/functions_crypto.php');
- $plaintext = enterprise_hook('openssl_encrypt_decrypt', ['decrypt', io_safe_output($password)]);
+ $plaintext = enterprise_hook(
+ 'openssl_encrypt_decrypt',
+ [
+ 'decrypt',
+ $password,
+ ]
+ );
+
if ($plaintext === ENTERPRISE_NOT_HOOK) {
- return $password;
+ return io_safe_output($password);
}
- return $plaintext;
+ return io_safe_output($plaintext);
}
diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js
index 1fc5912fb9..33ab956a1f 100644
--- a/pandora_console/include/javascript/pandora.js
+++ b/pandora_console/include/javascript/pandora.js
@@ -1890,6 +1890,16 @@ function load_modal(settings) {
width = settings.onshow.width;
}
+ settings.target.html("Loading modal...");
+ settings.target
+ .dialog({
+ title: "Loading",
+ close: false,
+ width: 200,
+ buttons: []
+ })
+ .show();
+
$.ajax({
method: "post",
url: settings.url,
@@ -1898,6 +1908,9 @@ function load_modal(settings) {
data: data,
success: function(data) {
settings.target.html(data);
+ if (settings.onload != undefined) {
+ settings.onload(data);
+ }
settings.target.dialog({
resizable: true,
draggable: true,
@@ -1927,6 +1940,9 @@ function load_modal(settings) {
click: function() {
if (AJAX_RUNNING) return;
AJAX_RUNNING = 1;
+ if (settings.onsubmit.preaction != undefined) {
+ settings.onsubmit.preaction();
+ }
var formdata = new FormData();
if (settings.extradata) {
settings.extradata.forEach(function(item) {
@@ -1954,7 +1970,9 @@ function load_modal(settings) {
contentType: false,
data: formdata,
success: function(data) {
- settings.ajax_callback(data);
+ if (settings.ajax_callback != undefined) {
+ settings.ajax_callback(data);
+ }
AJAX_RUNNING = 0;
}
});
diff --git a/pandora_console/include/styles/credential_store.css b/pandora_console/include/styles/credential_store.css
index aa77985188..5707d90780 100644
--- a/pandora_console/include/styles/credential_store.css
+++ b/pandora_console/include/styles/credential_store.css
@@ -10,3 +10,33 @@
#new_key select {
width: 60%;
}
+
+ul.wizard li > label:not(.p-switch) {
+ width: auto;
+}
+
+form.top-action-buttons ul.wizard {
+ display: flex;
+ flex-direction: row;
+}
+
+ul.wizard li {
+ margin-right: 1em;
+}
+
+form.modal ul.wizard li {
+ display: flex;
+ flex-direction: row;
+ width: 90%;
+ margin: 0 auto;
+ justify-items: center;
+}
+
+form.modal ul.wizard li * {
+ flex: 1;
+}
+
+ul.wizard li.flex-indep {
+ flex: 1;
+ margin: 0;
+}
diff --git a/pandora_console/install.php b/pandora_console/install.php
index a06e476f1e..610185a0bf 100644
--- a/pandora_console/install.php
+++ b/pandora_console/install.php
@@ -129,7 +129,7 @@
'index.php?sec=reporting&sec2=godmode/reporting/reporting_builder', 'text' => __('Reporting')]);
diff --git a/pandora_console/pandora_console.redhat.spec b/pandora_console/pandora_console.redhat.spec
index 573a742276..e25c49aa2f 100644
--- a/pandora_console/pandora_console.redhat.spec
+++ b/pandora_console/pandora_console.redhat.spec
@@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.738
-%define release 190923
+%define release 190924
# User and Group under which Apache is running
%define httpd_name httpd
diff --git a/pandora_console/pandora_console.rhel7.spec b/pandora_console/pandora_console.rhel7.spec
index 7e44602da4..13fc340121 100644
--- a/pandora_console/pandora_console.rhel7.spec
+++ b/pandora_console/pandora_console.rhel7.spec
@@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.738
-%define release 190923
+%define release 190924
# User and Group under which Apache is running
%define httpd_name httpd
diff --git a/pandora_console/pandora_console.spec b/pandora_console/pandora_console.spec
index 659938b9aa..c56f8c41c9 100644
--- a/pandora_console/pandora_console.spec
+++ b/pandora_console/pandora_console.spec
@@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.738
-%define release 190923
+%define release 190924
%define httpd_name httpd
# User and Group under which Apache is running
%define httpd_name apache2
diff --git a/pandora_server/DEBIAN/control b/pandora_server/DEBIAN/control
index cdf6610772..7cd9b0c5cd 100644
--- a/pandora_server/DEBIAN/control
+++ b/pandora_server/DEBIAN/control
@@ -1,5 +1,5 @@
package: pandorafms-server
-Version: 7.0NG.738-190923
+Version: 7.0NG.738-190924
Architecture: all
Priority: optional
Section: admin
diff --git a/pandora_server/DEBIAN/make_deb_package.sh b/pandora_server/DEBIAN/make_deb_package.sh
index 7bb767b956..79c391dbb1 100644
--- a/pandora_server/DEBIAN/make_deb_package.sh
+++ b/pandora_server/DEBIAN/make_deb_package.sh
@@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-pandora_version="7.0NG.738-190923"
+pandora_version="7.0NG.738-190924"
package_cpan=0
package_pandora=1
diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm
index 3b77520174..20934859c7 100644
--- a/pandora_server/lib/PandoraFMS/Config.pm
+++ b/pandora_server/lib/PandoraFMS/Config.pm
@@ -45,7 +45,7 @@ our @EXPORT = qw(
# version: Defines actual version of Pandora Server for this module only
my $pandora_version = "7.0NG.738";
-my $pandora_build = "190923";
+my $pandora_build = "190924";
our $VERSION = $pandora_version." ".$pandora_build;
# Setup hash
@@ -1037,7 +1037,7 @@ sub pandora_load_config {
$pa_config->{'console_pass'}= safe_input(clean_blank($1));
}
elsif ($parametro =~ m/^encryption_passphrase\s(.*)/i) { # 6.0
- $pa_config->{'encryption_passphrase'}= safe_input(clean_blank($1));
+ $pa_config->{'encryption_passphrase'} = clean_blank($1);
}
elsif ($parametro =~ m/^unknown_interval\s+([0-9]*)/i) { # > 5.1SP2
$pa_config->{'unknown_interval'}= clean_blank($1);
diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm
index e1556d74b6..667cd7c909 100644
--- a/pandora_server/lib/PandoraFMS/Core.pm
+++ b/pandora_server/lib/PandoraFMS/Core.pm
@@ -3155,11 +3155,20 @@ sub pandora_get_config_value ($$) {
##########################################################################
## Get credential from credential store
##########################################################################
-sub pandora_get_credential ($$) {
- my ($dbh, $identifier) = @_;
+sub pandora_get_credential ($$$) {
+ my ($pa_config, $dbh, $identifier) = @_;
my $key = get_db_single_row($dbh, 'SELECT * FROM tcredential_store WHERE identifier = ?', $identifier);
+ $key->{'username'} = pandora_output_password(
+ $pa_config,
+ safe_output($key->{'username'})
+ );
+ $key->{'password'} = pandora_output_password(
+ $pa_config,
+ safe_output($key->{'password'})
+ );
+
return $key;
}
diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm
index a45d1108f2..d96e359a76 100644
--- a/pandora_server/lib/PandoraFMS/PluginTools.pm
+++ b/pandora_server/lib/PandoraFMS/PluginTools.pm
@@ -32,7 +32,7 @@ our @ISA = qw(Exporter);
# version: Defines actual version of Pandora Server for this module only
my $pandora_version = "7.0NG.738";
-my $pandora_build = "190923";
+my $pandora_build = "190924";
our $VERSION = $pandora_version." ".$pandora_build;
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm
index 9710913efe..715703b5b6 100755
--- a/pandora_server/lib/PandoraFMS/Tools.pm
+++ b/pandora_server/lib/PandoraFMS/Tools.pm
@@ -624,7 +624,7 @@ sub logger ($$;$) {
$message = safe_output ($message);
$level = 1 unless defined ($level);
- return if ($level > $pa_config->{'verbosity'});
+ return if (!defined ($pa_config->{'verbosity'}) || $level > $pa_config->{'verbosity'});
if (!defined($pa_config->{'log_file'})) {
print strftime ("%Y-%m-%d %H:%M:%S", localtime()) . " [V". $level ."] " . $message . "\n";
diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec
index f2819ac79b..08a4ee2de5 100644
--- a/pandora_server/pandora_server.redhat.spec
+++ b/pandora_server/pandora_server.redhat.spec
@@ -3,7 +3,7 @@
#
%define name pandorafms_server
%define version 7.0NG.738
-%define release 190923
+%define release 190924
Summary: Pandora FMS Server
Name: %{name}
diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec
index 56cbacb03d..089fece9fc 100644
--- a/pandora_server/pandora_server.spec
+++ b/pandora_server/pandora_server.spec
@@ -3,7 +3,7 @@
#
%define name pandorafms_server
%define version 7.0NG.738
-%define release 190923
+%define release 190924
Summary: Pandora FMS Server
Name: %{name}
diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer
index 158d1e9deb..6afd51d072 100755
--- a/pandora_server/pandora_server_installer
+++ b/pandora_server/pandora_server_installer
@@ -9,7 +9,7 @@
# **********************************************************************
PI_VERSION="7.0NG.738"
-PI_BUILD="190923"
+PI_BUILD="190924"
MODE=$1
if [ $# -gt 1 ]; then
diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl
index 427e6817a2..0ac8ad2b9e 100644
--- a/pandora_server/util/pandora_db.pl
+++ b/pandora_server/util/pandora_db.pl
@@ -34,7 +34,7 @@ use PandoraFMS::Config;
use PandoraFMS::DB;
# version: define current version
-my $version = "7.0NG.738 PS190923";
+my $version = "7.0NG.738 PS190924";
# Pandora server configuration
my %conf;
diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl
index 974f7d06c9..d82f947ef6 100755
--- a/pandora_server/util/pandora_manage.pl
+++ b/pandora_server/util/pandora_manage.pl
@@ -36,7 +36,7 @@ use Encode::Locale;
Encode::Locale::decode_argv;
# version: define current version
-my $version = "7.0NG.738 PS190923";
+my $version = "7.0NG.738 PS190924";
# save program name for logging
my $progname = basename($0);