-
-
Notifications
You must be signed in to change notification settings - Fork 150
/
Config.php
267 lines (233 loc) · 9.05 KB
/
Config.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
<?php
namespace RouterOS;
use RouterOS\Exceptions\ConfigException;
use RouterOS\Helpers\ArrayHelper;
use RouterOS\Helpers\TypeHelper;
use RouterOS\Interfaces\ConfigInterface;
use function gettype;
/**
* Class Config with array of parameters
*
* @package RouterOS
* @since 0.1
*/
class Config implements ConfigInterface
{
/**
* By default legacy login on RouterOS pre-6.43 is not supported
*/
public const LEGACY = false;
/**
* Default port number
*/
public const PORT = 8728;
/**
* Default ssl port number
*/
public const PORT_SSL = 8729;
/**
* If true then use API in SSL mode
*
* @see https://wiki.mikrotik.com/wiki/Manual:API-SSL
*/
public const SSL = false;
/**
* List of additional options for work with SSL context
*
* @see https://www.php.net/manual/en/context.ssl.php
*/
public const SSL_OPTIONS = [
/*
* Sets the list of available ciphers. By default, RouterOS available via 'ADH:ALL'.
*
* @example 'ADH:ALL' // Alias to ADH:ALL@SECLEVEL=1
* 'ADH:ALL@SECLEVEL=0' // Everything is permitted. This retains compatibility with previous versions of OpenSSL.
* 'ADH:ALL@SECLEVEL=1' // The security level corresponds to a minimum of 80 bits of security.
* 'ADH:ALL@SECLEVEL=2' // Security level set to 112 bits of security.
* 'ADH:ALL@SECLEVEL=3' // Security level set to 128 bits of security.
* 'ADH:ALL@SECLEVEL=4' // Security level set to 192 bits of security.
* 'ADH:ALL@SECLEVEL=5' // Security level set to 256 bits of security.
*
* @link https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html
*/
'ciphers' => 'ADH:ALL', // ADH:ALL, ADH:ALL@SECLEVEL=0, ADH:ALL@SECLEVEL=1 ... ADH:ALL@SECLEVEL=5
// Require verification of SSL certificate used.
'verify_peer' => false,
// Require verification of peer name.
'verify_peer_name' => false,
// Allow self-signed certificates. Requires verify_peer=true.
'allow_self_signed' => false,
];
/**
* Max timeout for connecting to router (in seconds)
*/
public const TIMEOUT = 10;
/**
* Max read timeout from router (in seconds)
*/
public const SOCKET_TIMEOUT = 30;
/**
* List of options for socket context
*
* @see https://www.php.net/manual/en/context.socket.php
*/
public const SOCKET_OPTIONS = [
// Examples:
// 'bindto' => '192.168.0.100:0', // connect to the internet using the '192.168.0.100' IP
// 'bindto' => '192.168.0.100:7000', // connect to the internet using the '192.168.0.100' IP and port '7000'
// 'bindto' => '[2001:db8::1]:7000', // connect to the internet using the '2001:db8::1' IPv6 address and port '7000'
// 'bindto' => '0:7000', // connect to the internet using port '7000'
// 'bindto' => '0:0', // Forcing IPv4
// 'bindto' => '[::]:0', // Forcing IPv6
// 'tcp_nodelay' => true, // Setting this option to true will set SOL_TCP,NO_DELAY=1 appropriately, thus disabling the TCP Nagle algorithm.
];
/**
* Count of reconnect attempts
*/
public const ATTEMPTS = 10;
/**
* Delay between attempts in seconds
*/
public const ATTEMPTS_DELAY = 1;
/**
* Number of SSH port for exporting configuration
*/
public const SSH_PORT = 22;
/**
* By default stream on blocking mode
*/
public const SOCKET_BLOCKING = true;
/**
* Max read timeout from router via SSH (in seconds)
*/
public const SSH_TIMEOUT = 30;
public const SSH_PRIVATE_KEY = '~/.ssh/id_rsa';
/**
* List of allowed parameters of config
*/
public const ALLOWED = [
'host' => 'string', // Address of Mikrotik RouterOS
'user' => 'string', // Username
'pass' => 'string', // Password
'port' => 'integer', // RouterOS API port number for access (if not set use default or default with SSL if SSL enabled)
'ssl' => 'boolean', // Enable ssl support (if port is not set this parameter must change default port to ssl port)
'ssl_options' => 'array', // List of SSL options, eg.
'legacy' => 'boolean', // Support of legacy login scheme (true - pre 6.43, false - post 6.43)
'timeout' => 'integer', // Max timeout for instantiating connection with RouterOS
'socket_timeout' => 'integer', // Max timeout for read from RouterOS
'socket_blocking' => 'boolean', // Set blocking mode on a socket stream
'socket_options' => 'array', // List of socket context options
'attempts' => 'integer', // Count of attempts to establish TCP session
'delay' => 'integer', // Delay between attempts in seconds
'ssh_port' => 'integer', // Number of SSH port
'ssh_timeout' => 'integer', // Max timeout for read from RouterOS via SSH proto (for "/export" command)
'ssh_private_key' => 'string', // Max timeout for read from RouterOS via SSH proto (for "/export" command)
];
/**
* Array of parameters (with some default values)
*
* @var array
*/
private $_parameters = [
'legacy' => self::LEGACY,
'ssl' => self::SSL,
'ssl_options' => self::SSL_OPTIONS,
'timeout' => self::TIMEOUT,
'socket_timeout' => self::SOCKET_TIMEOUT,
'socket_blocking' => self::SOCKET_BLOCKING,
'socket_options' => self::SOCKET_OPTIONS,
'attempts' => self::ATTEMPTS,
'delay' => self::ATTEMPTS_DELAY,
'ssh_port' => self::SSH_PORT,
'ssh_timeout' => self::SSH_TIMEOUT,
'ssh_private_key' => self::SSH_PRIVATE_KEY,
];
/**
* Config constructor.
*
* @param array $parameters List of parameters which can be set on object creation stage
*
* @throws \RouterOS\Exceptions\ConfigException
* @since 0.6
*/
public function __construct(array $parameters = [])
{
foreach ($parameters as $key => $value) {
$this->set($key, $value);
}
}
/**
* {@inheritdoc}
*
* @throws \RouterOS\Exceptions\ConfigException when name of configuration key is invalid or not allowed
*/
public function set(string $name, $value): ConfigInterface
{
// Check of key in array
if (ArrayHelper::checkIfKeyNotExist($name, self::ALLOWED)) {
throw new ConfigException("Requested parameter '$name' not found in list [" . implode(',', array_keys(self::ALLOWED)) . ']');
}
// Check what type has this value
if (TypeHelper::checkIfTypeMismatch(gettype($value), self::ALLOWED[$name])) {
throw new ConfigException("Parameter '$name' has wrong type '" . gettype($value) . "' but should be '" . self::ALLOWED[$name] . "'");
}
// Save value to array
$this->_parameters[$name] = $value;
return $this;
}
/**
* Return port number (get from defaults if port is not set by user)
*
* @param string $parameter
*
* @return null|int
*/
private function getPort(string $parameter): ?int
{
// If client need port number and port is not set
if ('port' === $parameter && (!isset($this->_parameters['port']) || null === $this->_parameters['port'])) {
// then use default with or without ssl encryption
return (isset($this->_parameters['ssl']) && $this->_parameters['ssl'])
? self::PORT_SSL
: self::PORT;
}
return null;
}
/**
* {@inheritdoc}
*
* @throws \RouterOS\Exceptions\ConfigException when parameter is not allowed
*/
public function delete(string $parameter): ConfigInterface
{
// Check of key in array
if (ArrayHelper::checkIfKeyNotExist($parameter, self::ALLOWED)) {
$list = implode(',', array_keys(self::ALLOWED));
throw new ConfigException("Requested parameter '$parameter' not found in list [$list]");
}
// Save value to array
unset($this->_parameters[$parameter]);
return $this;
}
/**
* {@inheritdoc}
*
* @throws \RouterOS\Exceptions\ConfigException when parameter is not allowed
*/
public function get(string $parameter)
{
// Check of key in array
if (ArrayHelper::checkIfKeyNotExist($parameter, self::ALLOWED)) {
$list = implode(',', array_keys(self::ALLOWED));
throw new ConfigException("Requested parameter '$parameter' not found in list [$list]");
}
return $this->getPort($parameter) ?? $this->_parameters[$parameter];
}
/**
* {@inheritdoc}
*/
public function getParameters(): array
{
return $this->_parameters;
}
}