1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22/**
23 * Class containing methods for operations with autoregistration.
24 */
25class CAutoregistration extends CApiService {
26
27	public const ACCESS_RULES = [
28		'get' => ['min_user_type' => USER_TYPE_SUPER_ADMIN],
29		'update' => ['min_user_type' => USER_TYPE_SUPER_ADMIN]
30	];
31
32	protected $tableName = 'config';
33	protected $tableAlias = 'c';
34
35	/**
36	 * @param array $options
37	 *
38	 * @throws APIException if the input is invalid.
39	 *
40	 * @return array
41	 */
42	public function get(array $options) {
43		$api_input_rules = ['type' => API_OBJECT, 'fields' => [
44			'output' =>	['type' => API_OUTPUT, 'in' => 'tls_accept', 'default' => API_OUTPUT_EXTEND]
45		]];
46		if (!CApiInputValidator::validate($api_input_rules, $options, '/', $error)) {
47			self::exception(ZBX_API_ERROR_PARAMETERS, $error);
48		}
49
50		if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN) {
51			return [];
52		}
53
54		if ($options['output'] === API_OUTPUT_EXTEND) {
55			$options['output'] = ['tls_accept'];
56		}
57
58		$options['output'] = preg_replace("/^(tls_accept)$/", "autoreg_$1", $options['output']);
59
60		$db_autoreg = [];
61
62		$result = DBselect($this->createSelectQuery($this->tableName(), $options));
63		while ($row = DBfetch($result)) {
64			$db_autoreg[] = $row;
65		}
66		if ($this->outputIsRequested('autoreg_tls_accept', $options['output'])) {
67			$db_autoreg = CArrayHelper::renameObjectsKeys($db_autoreg, ['autoreg_tls_accept' => 'tls_accept']);
68		}
69		$db_autoreg = $this->unsetExtraFields($db_autoreg, ['configid'], []);
70
71		return $db_autoreg[0];
72	}
73
74	/**
75	 * @param array  $autoreg
76	 *
77	 * @return bool
78	 */
79	public function update(array $autoreg) {
80		$this->validateUpdate($autoreg, $db_autoreg);
81
82		$upd_config = [];
83		$upd_config_autoreg_tls = [];
84
85		if (array_key_exists('tls_accept', $autoreg) && $autoreg['tls_accept'] != $db_autoreg['tls_accept']) {
86			$upd_config['autoreg_tls_accept'] = $autoreg['tls_accept'];
87		}
88
89		// strings
90		foreach (['tls_psk_identity', 'tls_psk'] as $field_name) {
91			if (array_key_exists($field_name, $autoreg) && $autoreg[$field_name] !== $db_autoreg[$field_name]) {
92				$upd_config_autoreg_tls[$field_name] = $autoreg[$field_name];
93			}
94		}
95
96		if ($upd_config) {
97			DB::update('config', [
98				'values' => $upd_config,
99				'where' => ['configid' => $db_autoreg['configid']]
100			]);
101		}
102
103		if ($upd_config_autoreg_tls) {
104			DB::update('config_autoreg_tls', [
105				'values' => $upd_config_autoreg_tls,
106				'where' => ['autoreg_tlsid' => $db_autoreg['autoreg_tlsid']]
107			]);
108		}
109
110		$this->addAuditBulk(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_AUTOREGISTRATION,
111			[['configid' => $db_autoreg['configid']] + $autoreg], [$db_autoreg['configid'] => $db_autoreg]
112		);
113
114		return true;
115	}
116
117	/**
118	 * @param array  $autoreg
119	 * @param array  $db_autoreg
120	 *
121	 * @throws APIException if the input is invalid.
122	 */
123	protected function validateUpdate(array &$autoreg, array &$db_autoreg = null) {
124		$api_input_rules = ['type' => API_OBJECT, 'flags' => API_NOT_EMPTY, 'fields' => [
125			'tls_accept' =>			['type' => API_INT32, 'in' => HOST_ENCRYPTION_NONE.':'.(HOST_ENCRYPTION_NONE | HOST_ENCRYPTION_PSK)],
126			'tls_psk_identity' =>	['type' => API_STRING_UTF8, 'length' => DB::getFieldLength('config_autoreg_tls', 'tls_psk_identity')],
127			'tls_psk' =>			['type' => API_PSK, 'length' => DB::getFieldLength('config_autoreg_tls', 'tls_psk')]
128		]];
129		if (!CApiInputValidator::validate($api_input_rules, $autoreg, '/', $error)) {
130			self::exception(ZBX_API_ERROR_PARAMETERS, $error);
131		}
132
133		// Check permissions.
134		if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN) {
135			self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
136		}
137
138		$db_autoreg = DBfetch(DBselect(
139			"SELECT c.configid,c.autoreg_tls_accept AS tls_accept,ca.autoreg_tlsid,ca.tls_psk_identity,ca.tls_psk".
140			" FROM config c,config_autoreg_tls ca"
141		));
142
143		$tls_accept = array_key_exists('tls_accept', $autoreg) ? $autoreg['tls_accept'] : $db_autoreg['tls_accept'];
144
145		// PSK validation.
146		foreach (['tls_psk_identity', 'tls_psk'] as $field_name) {
147			if ($tls_accept & HOST_ENCRYPTION_PSK) {
148				if (!array_key_exists($field_name, $autoreg) && $db_autoreg[$field_name] === '') {
149					self::exception(ZBX_API_ERROR_PARAMETERS,
150						_s('Invalid parameter "%1$s": %2$s.', '/', _s('the parameter "%1$s" is missing', $field_name))
151					);
152				}
153
154				if (array_key_exists($field_name, $autoreg) && $autoreg[$field_name] === '') {
155					self::exception(ZBX_API_ERROR_PARAMETERS,
156						_s('Invalid parameter "%1$s": %2$s.', '/'.$field_name, _('cannot be empty'))
157					);
158				}
159			}
160			else {
161				if (array_key_exists($field_name, $autoreg) && $autoreg[$field_name] !== '') {
162					self::exception(ZBX_API_ERROR_PARAMETERS,
163						_s('Invalid parameter "%1$s": %2$s.', '/'.$field_name, _('should be empty'))
164					);
165				}
166
167				if (!array_key_exists($field_name, $autoreg) && $db_autoreg[$field_name] !== '') {
168					$autoreg[$field_name] = '';
169				}
170			}
171		}
172	}
173}
174