Passed
Push — develop ( fe499f...dd242c )
by Nikolay
05:43 queued 12s
created

System::nginxGenerateConf()   C

Complexity

Conditions 15
Paths 180

Size

Total Lines 79
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 59
dl 0
loc 79
rs 5.25
c 0
b 0
f 0
cc 15
nc 180
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Copyright © MIKO LLC - All Rights Reserved
4
 * Unauthorized copying of this file, via any medium is strictly prohibited
5
 * Proprietary and confidential
6
 * Written by Alexey Portnov, 7 2020
7
 */
8
9
namespace MikoPBX\Core\System;
10
11
use MikoPBX\Common\Models\CustomFiles;
12
use MikoPBX\Core\Asterisk\Configs\{QueueConf};
13
use MikoPBX\Core\Workers\Cron\WorkerSafeScriptsCore;
14
use Phalcon\Di;
15
use function MikoPBX\Common\Config\appPath;
16
17
/**
18
 *
19
 */
20
class System
21
{
22
    private MikoPBXConfig $mikoPBXConfig;
23
    /**
24
     * @var mixed|\Phalcon\Di\DiInterface|null
25
     */
26
    private $di;
27
28
    /**
29
     * System constructor.
30
     */
31
    public function __construct()
32
    {
33
        $this->di = Di::getDefault();
34
35
        // Класс / обертка для работы с настройками.
36
        $this->mikoPBXConfig = new MikoPBXConfig();
37
    }
38
39
    /**
40
     * Relocate PHP error log to storage mount
41
     */
42
    public static function setupPhpLog(): void
43
    {
44
        $src_log_file = '/var/log/php_error.log';
45
        $dst_log_file = self::getPhpFile();
46
        if ( ! file_exists($src_log_file)) {
47
            file_put_contents($src_log_file, '');
48
        }
49
        $options = file_exists($dst_log_file) ? '>' : '';
50
        $catPath = Util::which('cat');
51
        Util::mwExec("{$catPath} {$src_log_file} 2> /dev/null >{$options} {$dst_log_file}");
52
        Util::createUpdateSymlink($dst_log_file, $src_log_file);
53
    }
54
55
    /**
56
     * @return string
57
     */
58
    public static function getPhpFile(): string
59
    {
60
        $logdir = self::getLogDir() . '/php';
61
        Util::mwMkdir($logdir);
62
        return "$logdir/error.log";
63
    }
64
65
    /**
66
     * @return string
67
     */
68
    public static function getLogDir(): string
69
    {
70
        $di     = Di::getDefault();
71
        if ($di !== null){
72
            return $di->getConfig()->path('core.logsPath');
73
        }
74
        return '/var/log';
75
    }
76
77
    /**
78
     *
79
     */
80
    public static function rotatePhpLog(): void
81
    {
82
        $asteriskPath = Util::which('asterisk');
83
        $logrotatePath = Util::which('logrotate');
84
85
        $max_size    = 2;
86
        $f_name      = self::getPhpFile();
87
        $text_config = (string)($f_name) . " {
88
    nocreate
89
    nocopytruncate
90
    delaycompress
91
    nomissingok
92
    start 0
93
    rotate 9
94
    size {$max_size}M
95
    missingok
96
    noolddir
97
    postrotate
98
        {$asteriskPath} -rx 'logger reload' > /dev/null 2> /dev/null
99
    endscript
100
}";
101
        $di     = Di::getDefault();
102
        if ($di !== null){
103
            $varEtcPath = $di->getConfig()->path('core.varEtcPath');
104
        } else {
105
            $varEtcPath = '/var/etc';
106
        }
107
        $path_conf   = $varEtcPath . '/php_logrotate_' . basename($f_name) . '.conf';
108
        file_put_contents($path_conf, $text_config);
109
        $mb10 = $max_size * 1024 * 1024;
110
111
        $options = '';
112
        if (Util::mFileSize($f_name) > $mb10) {
113
            $options = '-f';
114
        }
115
        Util::mwExecBg("{$logrotatePath} {$options} '{$path_conf}' > /dev/null 2> /dev/null");
116
    }
117
118
    /**
119
     *
120
     */
121
    public static function gnatsLogRotate(): void
122
    {
123
        $log_dir = self::getLogDir() . '/nats';
124
        $gnatsdPath = Util::which('gnatsd');
125
        $pid     = Util::getPidOfProcess($gnatsdPath, 'custom_modules');
126
        $max_size = 1;
127
        if (empty($pid)) {
128
            $system = new System();
129
            $system->gnatsStart();
130
            sleep(1);
131
        }
132
        $text_config = "{$log_dir}/gnatsd.log {
133
    start 0
134
    rotate 9
135
    size {$max_size}M
136
    maxsize 1M
137
    daily
138
    missingok
139
    notifempty
140
    sharedscripts
141
    postrotate
142
        {$gnatsdPath} -sl reopen=$pid > /dev/null 2> /dev/null
143
    endscript
144
}";
145
146
        $mb10 = $max_size * 1024 * 1024;
147
148
        $options = '';
149
        if (Util::mFileSize("{$log_dir}/gnatsd.log") > $mb10) {
150
            $options = '-f';
151
        }
152
        $di     = Di::getDefault();
153
        if ($di !== null){
154
            $varEtcPath = $di->getConfig()->path('core.varEtcPath');
155
        } else {
156
            $varEtcPath = '/var/etc';
157
        }
158
        $path_conf  = $varEtcPath . '/gnatsd_logrotate.conf';
159
        file_put_contents($path_conf, $text_config);
160
        if (file_exists("{$log_dir}/gnatsd.log")) {
161
            $logrotatePath = Util::which('logrotate');
162
            Util::mwExecBg("{$logrotatePath} $options '{$path_conf}' > /dev/null 2> /dev/null");
163
        }
164
    }
165
166
    /**
167
     * Старт сервера обработки очередей задач.
168
     *
169
     * @return array
170
     */
171
    public function gnatsStart(): array
172
    {
173
        $confdir = '/etc/nats';
174
        Util::mwMkdir($confdir);
175
        $logdir = self::getLogDir() . '/nats';
176
        Util::mwMkdir($logdir);
177
178
        $pid_file = '/var/run/gnatsd.pid';
179
        $settings = [
180
            'port'             => '4223',
181
            'http_port'        => '8223',
182
            'debug'            => 'false',
183
            'trace'            => 'false',
184
            'logtime'          => 'true',
185
            'pid_file'         => $pid_file,
186
            'max_connections'  => '1000',
187
            'max_payload'      => '1000000',
188
            'max_control_line' => '512',
189
            'sessions_path'    => $logdir,
190
            'log_file'         => "{$logdir}/gnatsd.log",
191
        ];
192
        $config   = '';
193
        foreach ($settings as $key => $val) {
194
            $config .= "{$key}: {$val} \n";
195
        }
196
        $conf_file = "{$confdir}/natsd.conf";
197
        Util::fileWriteContent($conf_file, $config);
198
199
        $lic = $this->mikoPBXConfig->getGeneralSettings('PBXLicense');
200
        file_put_contents($logdir . '/license.key', $lic);
201
202
        if (file_exists($pid_file)) {
203
            $killPath = Util::which('kill');
204
            $catPath = Util::which('kill');
205
            Util::mwExec("{$killPath} $({$catPath} {$pid_file})");
206
        }
207
        $gnatsdPath = Util::which('gnatsd');
208
        Util::mwExecBg("{$gnatsdPath} --config {$conf_file}", "{$logdir}/gnats_process.log");
209
210
        return [
211
            'result' => 'Success',
212
        ];
213
    }
214
215
    /**
216
     * Рестарт сетевых интерфейсов.
217
     */
218
    public static function networkReload(): void
219
    {
220
        $system = new System();
221
        $system->hostnameConfigure();
222
223
        $network = new Network();
224
        $network->resolvConfGenerate();
225
        $network->loConfigure();
226
        $network->lanConfigure();
227
    }
228
229
    /**
230
     *    Устанавливаем имя хост текущей машины.
231
     **/
232
    public function hostnameConfigure(): int
233
    {
234
        $data       = Network::getHostName();
235
        $hosts_conf = "127.0.0.1 localhost\n" .
236
            "127.0.0.1 {$data['hostname']}\n";
237
        if ( ! empty($data['domain'])) {
238
            $hosts_conf .= "127.0.0.1 {$data['hostname']}.{$data['domain']}\n";
239
        }
240
        Util::fileWriteContent('/etc/hosts', $hosts_conf);
241
242
        $hostnamePath = Util::which('hostname');
243
        return Util::mwExec($hostnamePath.' '. escapeshellarg("{$data['hostname']}"));
0 ignored issues
show
Bug Best Practice introduced by
The expression return MikoPBX\Core\Syst...arg($data['hostname'])) could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
244
    }
245
246
247
248
    /**
249
     * Обновление кофнигурации кастомных файлов.
250
     *
251
     * @return array
252
     */
253
    public static function updateCustomFiles()
254
    {
255
        $actions = [];
256
        /** @var \MikoPBX\Common\Models\CustomFiles $res_data */
257
        $res_data = CustomFiles::find("changed = '1'");
258
        foreach ($res_data as $file_data) {
259
            // Всегда рестрартуем все модули asterisk (только чтение конфигурации).
260
            $actions['asterisk_coreReload'] = 100;
261
            $filename                       = basename($file_data->filepath);
262
            switch ($filename) {
263
                case 'manager.conf':
264
                    $actions['manager'] = 10;
265
                    break;
266
                case 'musiconhold.conf':
267
                    $actions['musiconhold'] = 100;
268
                    break;
269
                case 'modules.conf':
270
                    $actions['modules'] = 10;
271
                    break;
272
                case 'http.conf':
273
                    $actions['manager'] = 10;
274
                    break;
275
                case 'root': // crontabs
276
                    $actions['cron'] = 10;
277
                    break;
278
                case 'queues.conf':
279
                    $actions['queues'] = 10;
280
                    break;
281
                case 'features.conf':
282
                    $actions['features'] = 10;
283
                    break;
284
                case 'ntp.conf':
285
                    $actions['systemtime'] = 100;
286
                    break;
287
                case 'jail.local': // fail2ban
288
                    $actions['firewall'] = 100;
289
                    break;
290
            }
291
        }
292
293
        asort($actions);
294
        $result = self::invokeActions($actions);
295
        if ($result['result'] !== 'ERROR') {
296
            // Зафиксируем результат работы.
297
            foreach ($res_data as $file_data) {
298
                /** @var \MikoPBX\Common\Models\CustomFiles $file_data */
299
                $file_data->writeAttribute("changed", '0');
300
                $file_data->save();
301
            }
302
        }
303
304
        return $result;
305
    }
306
307
    /**
308
     * Выполнение набора действий по рестарту модулей системы.
309
     *
310
     * @param $actions
311
     *
312
     * @return array|mixed
313
     */
314
    public static function invokeActions($actions)
315
    {
316
        $result = [
317
            'result' => 'Success',
318
        ];
319
        foreach ($actions as $action => $value) {
320
            $res = null;
321
            switch ($action) {
322
                case 'manager':
323
                    $res = PBX::managerReload();
324
                    break;
325
                case 'musiconhold':
326
                    $res = PBX::musicOnHoldReload();
327
                    break;
328
                case 'modules':
329
                    $res = PBX::modulesReload();
330
                    break;
331
                case 'cron':
332
                    $system = new System();
333
                    $system->cronConfigure();
334
                    break;
335
                case 'queues':
336
                    $res = QueueConf::queueReload();
337
                    break;
338
                case 'features':
339
                    $res = PBX::managerReload();
340
                    break;
341
                case 'systemtime':
342
                    $res = TimeManagement::setDate('');
343
                    break;
344
                case 'firewall':
345
                    $res = Firewall::reloadFirewall();
346
                    break;
347
                case 'asterisk_coreReload':
348
                    PBX::sipReload();
349
                    PBX::iaxReload();
350
                    PBX::dialplanReload();
351
                    $res = PBX::coreReload();
352
                    break;
353
            }
354
            if ($res !== null && $res['result'] === 'ERROR') {
355
                $result = $res['result'];
356
                break;
357
            }
358
        }
359
360
        return $result;
361
    }
362
363
    /**
364
     * Настройка cron. Запуск демона.
365
     *
366
     * @return int
367
     */
368
    public function cronConfigure(): int
369
    {
370
        $booting = $this->di->getRegistry()->booting;
0 ignored issues
show
Bug introduced by
The method getRegistry() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

370
        $booting = $this->di->/** @scrutinizer ignore-call */ getRegistry()->booting;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
371
        $this->cronGenerate($booting);
372
        if (Util::isSystemctl()) {
373
            $systemctlPath = Util::which('systemctl');
374
            Util::mwExec("{$systemctlPath} restart cron");
375
        } else {
376
            $crondPath = Util::which('crond');
377
            Util::killByName($crondPath);
378
            Util::mwExec("{$crondPath} -L /dev/null -l 8");
379
        }
380
        return 0;
381
    }
382
383
    /**
384
     * Генератор конфига cron.
385
     *
386
     * @param bool $boot
387
     */
388
    private function cronGenerate($boot = true): void
389
    {
390
        $additionalModules = $this->di->getShared('pbxConfModules');
391
        $mast_have         = [];
392
393
        if (Util::isSystemctl()) {
394
            $mast_have[]   = "SHELL=/bin/sh\n";
395
            $mast_have[]   = "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n\n";
396
            $cron_filename = '/etc/cron.d/mikopbx';
397
            $cron_user     = 'root ';
398
        } else {
399
            $cron_filename = '/var/spool/cron/crontabs/root';
400
            $cron_user     = '';
401
        }
402
403
404
        $workerSafeScriptsPath = Util::getFilePathByClassName(WorkerSafeScriptsCore::class);
405
        $phpPath = Util::which('php');
406
        $WorkerSafeScripts = "{$phpPath} -f {$workerSafeScriptsPath} start > /dev/null 2> /dev/null";
407
408
        $workersPath = appPath('src/Core/Workers');
409
410
        $restart_night = $this->mikoPBXConfig->getGeneralSettings('RestartEveryNight');
411
        $asteriskPath = Util::which('asterisk');
412
        $ntpdPath = Util::which('ntpd');
413
        $shPath = Util::which('sh');
414
        if ($restart_night === '1') {
415
            $mast_have[] = '0 1 * * * ' . $cron_user .$asteriskPath.' -rx"core restart now" > /dev/null 2> /dev/null' . "\n";
416
        }
417
        $mast_have[] = '*/5 * * * * ' . $cron_user . $ntpdPath.' -q > /dev/null 2> /dev/null' . "\n";
418
        $mast_have[] = '*/6 * * * * ' . $cron_user . "{$shPath} {$workersPath}/Cron/cleaner_download_links.sh > /dev/null 2> /dev/null\n";
419
        $mast_have[] = '*/1 * * * * ' . $cron_user . "{$WorkerSafeScripts}\n";
420
421
        $tasks = [];
422
        // Дополнительные модули также могут добавить задачи в cron.
423
        foreach ($additionalModules as $appClass) {
424
            /** @var \MikoPBX\Modules\Config\ConfigClass $appClass */
425
            $appClass->createCronTasks($tasks);
426
        }
427
        $conf = implode('', array_merge($mast_have, $tasks));
428
429
        if (Util::isSystemctl()) {
430
            // Обеспечим совместимость всех существующих модулей с Debian.
431
            $conf = str_replace(' * * * * /', ' * * * * root /', $conf);
432
        }
433
434
        if ($boot === true) {
435
            Util::mwExecBg($WorkerSafeScripts);
436
        }
437
438
        Util::fileWriteContent($cron_filename, $conf);
439
    }
440
441
    /**
442
     * Подгрузка дополнительных модулей ядра.
443
     */
444
    public function loadKernelModules(): void
445
    {
446
        $modprobePath = Util::which('modprobe');
447
        $ulimitPath = Util::which('ulimit');
448
449
        Util::mwExec("{$modprobePath} -q dahdi");
450
        Util::mwExec("{$modprobePath} -q dahdi_transcode");
451
        Util::mwExec("{$ulimitPath} -n 4096");
452
        Util::mwExec("{$ulimitPath} -p 4096");
453
    }
454
455
    /**
456
     *   Start Nginx and php-fpm
457
     **/
458
    public function nginxStart(): void
459
    {
460
        if (Util::isSystemctl()) {
461
            Util::mwExec('systemctl restart php7.4-fpm');
462
            Util::mwExec('systemctl restart nginx.service');
463
        } else {
464
            Util::killByName('php-fpm');
465
            Util::killByName('nginx');
466
            Util::mwExec('php-fpm -c /etc/php.ini');
467
            Util::mwExec('nginx');
468
        }
469
    }
470
471
    /**
472
     * Write additional settings the nginx.conf
473
     *
474
     * @param bool $not_ssl
475
     * @param int  $level
476
     */
477
    public function nginxGenerateConf($not_ssl = false, $level = 0): void
478
    {
479
        $configPath      = '/etc/nginx/mikopbx/conf.d';
480
        $httpConfigFile  = "{$configPath}/http-server.conf";
481
        $httpsConfigFile = "{$configPath}/https-server.conf";
482
483
        $dns_server = '127.0.0.1';
484
485
        $net = new Network();
486
        $dns = $net->getHostDNS();
487
        foreach ($dns as $ns) {
488
            if (Verify::isIpAddress($ns)) {
489
                $dns_server = trim($ns);
490
                break;
491
            }
492
        }
493
494
        // HTTP
495
        $WEBPort      = $this->mikoPBXConfig->getGeneralSettings('WEBPort');
496
        $WEBHTTPSPort = $this->mikoPBXConfig->getGeneralSettings('WEBHTTPSPort');
497
498
        $config = file_get_contents("{$httpConfigFile}.original");
499
        $config = str_replace(['<DNS>', '<WEBPort>'], [$dns_server, $WEBPort], $config);
500
501
        $RedirectToHttps = $this->mikoPBXConfig->getGeneralSettings('RedirectToHttps');
502
        if ($RedirectToHttps === '1' && $not_ssl === false) {
503
            $conf_data = 'if ( $remote_addr != "127.0.0.1" ) {' . PHP_EOL
504
                . '        ' . 'return 301 https://$host:' . $WEBHTTPSPort . '$request_uri;' . PHP_EOL
505
                . '       }' . PHP_EOL;
506
            $config    = str_replace('include mikopbx/locations/*.conf;', $conf_data, $config);
507
        }
508
        file_put_contents($httpConfigFile, $config);
509
510
        // SSL
511
        $WEBHTTPSPublicKey  = $this->mikoPBXConfig->getGeneralSettings('WEBHTTPSPublicKey');
512
        $WEBHTTPSPrivateKey = $this->mikoPBXConfig->getGeneralSettings('WEBHTTPSPrivateKey');
513
        if (
514
            $not_ssl === false
515
            && ! empty($WEBHTTPSPublicKey)
516
            && ! empty($WEBHTTPSPrivateKey)
517
        ) {
518
            $public_filename  = '/etc/ssl/certs/nginx.crt';
519
            $private_filename = '/etc/ssl/private/nginx.key';
520
            file_put_contents($public_filename, $WEBHTTPSPublicKey);
521
            file_put_contents($private_filename, $WEBHTTPSPrivateKey);
522
            $config = file_get_contents("{$httpsConfigFile}.original");
523
            $config = str_replace(['<DNS>', '<WEBHTTPSPort>'], [$dns_server, $WEBHTTPSPort], $config);
524
            file_put_contents($httpsConfigFile, $config);
525
        } elseif (file_exists($httpsConfigFile)) {
526
            unlink($httpsConfigFile);
527
        }
528
529
        // Test work
530
        $nginxPath = Util::which('nginx');
531
        $out = [];
532
        Util::mwExec("{$nginxPath} -t", $out);
533
        $res = implode($out);
534
        if ($level < 1 && false !== strpos($res, 'test failed')) {
535
            ++$level;
536
            Util::sysLogMsg('nginx', 'Failed test config file. SSL will be disable...');
537
            $this->nginxGenerateConf(true, $level);
538
        }
539
540
        // Add additional rules from modules
541
        $locationsPath      = '/etc/nginx/mikopbx/locations';
542
        $additionalModules = $this->di->getShared('pbxConfModules');
543
        $rmPath = Util::which('rm');
544
        foreach ($additionalModules as $appClass) {
545
           if (method_exists($appClass, 'createNginxLocations')){
546
               $locationContent = $appClass->createNginxLocations();
547
               if (!empty($locationContent)){
548
                   $confFileName = "{$locationsPath}/{$appClass->moduleUniqueId}.conf";
549
                   file_put_contents($confFileName, $locationContent);
550
                   $out = [];
551
                   Util::mwExec("{$nginxPath} -t", $out);
552
                   $res = implode($out);
553
                   if (false !== strpos($res, 'test failed')) {
554
                       Util::mwExec("{$rmPath} {$confFileName}");
555
                       Util::sysLogMsg('nginx', 'Failed test config file for module'.$appClass->moduleUniqueId);
556
                   }
557
               }
558
           }
559
        }
560
    }
561
562
    public function syslogDaemonStart(): void
563
    {
564
        $syslog_file = '/var/log/messages';
565
        $log_file    = self::getSyslogFile();
566
        if ( ! file_exists($syslog_file)) {
567
            file_put_contents($syslog_file, '');
568
        }
569
        $syslogdPath = Util::which('syslogd');
570
        $busyboxPath = Util::which('busybox');
571
        $logreadPath = Util::which('logread');
572
        $killPath = Util::which('kill');
573
        $pid = Util::getPidOfProcess($syslogdPath);
574
        if ( ! empty($pid)) {
575
            $options = file_exists($log_file) ? '>' : '';
576
            Util::mwExec("{$busyboxPath} {$logreadPath} 2> /dev/null >" . $options . $log_file);
577
            // Завершаем процесс.
578
            Util::mwExec("{$busyboxPath} {$killPath} '$pid'");
579
        }
580
581
        Util::createUpdateSymlink($log_file, $syslog_file);
582
        Util::mwExec("{$syslogdPath} -O {$log_file} -b 10 -s 10240");
583
    }
584
585
    public static function getSyslogFile(): string
586
    {
587
        $logdir = self::getLogDir() . '/system';
588
        Util::mwMkdir($logdir);
589
        return "$logdir/messages";
590
    }
591
592
    /**
593
     * Будет вызван после старта asterisk.
594
     */
595
    public function onAfterPbxStarted(): void
596
    {
597
        $additionalModules = $this->di->getShared('pbxConfModules');
598
        foreach ($additionalModules as $appClass) {
599
            /** @var \MikoPBX\Modules\Config\ConfigClass $appClass */
600
            $appClass->onAfterPbxStarted();
601
        }
602
    }
603
604
    /**
605
     * Запуск SSH сервера.
606
     **/
607
    public function sshdConfigure(): array
608
    {
609
        $result       = [
610
            'result' => 'Success',
611
        ];
612
        $dropbear_dir = '/etc/dropbear';
613
        Util::mwMkdir($dropbear_dir);
614
615
        $keytypes = [
616
            "rsa"   => "SSHRsaKey",
617
            "dss"   => "SSHDssKey",
618
            "ecdsa" => "SSHecdsaKey" // SSHecdsaKey // SSHEcdsaKey
619
        ];
620
        // Получаем ключ из базы данных.
621
        // $config = array();
622
        foreach ($keytypes as $keytype => $db_key) {
623
            $res_keyfilepath = "{$dropbear_dir}/dropbear_" . $keytype . "_host_key";
624
            $key             = $this->mikoPBXConfig->getGeneralSettings($db_key);
625
            $key             = (isset($key) && is_string($key)) ? trim($key) : "";
626
            if (strlen($key) > 100) {
627
                // Сохраняем ключ в файл.
628
                file_put_contents($res_keyfilepath, base64_decode($key));
629
            }
630
            // Если ключ не существует, создадим его и обновим информацию в базе данных.
631
            if ( ! file_exists($res_keyfilepath)) {
632
                // Генерация.
633
                $dropbearkeyPath = Util::which('dropbearkey');
634
                Util::mwExec("{$dropbearkeyPath} -t $keytype -f $res_keyfilepath");
635
                // Сохранение.
636
                $new_key = base64_encode(file_get_contents($res_keyfilepath));
637
                $this->mikoPBXConfig->setGeneralSettings("$db_key", "$new_key");
638
            }
639
        }
640
        $ssh_port = escapeshellcmd($this->mikoPBXConfig->getGeneralSettings('SSHPort'));
641
        // Перезапускаем сервис dropbear;
642
        Util::killByName('dropbear');
643
        usleep(500000);
644
        Util::mwExec("dropbear -p '{$ssh_port}' -c /etc/rc/hello > /var/log/dropbear_start.log");
645
        $this->generateAuthorizedKeys();
646
647
        $result['data'] = @file_get_contents('/var/log/dropbear_start.log');
648
        if ( ! empty($result['data'])) {
649
            $result['result'] = 'ERROR';
650
        }
651
652
        // Устанавливаем пароль на пользователя ОС.
653
        $this->updateShellPassword();
654
655
        return $result;
656
    }
657
658
    /**
659
     * Сохранение ключей аторизации.
660
     */
661
    public function generateAuthorizedKeys(): void
662
    {
663
        $ssh_dir = '/root/.ssh';
664
        Util::mwMkdir($ssh_dir);
665
666
667
        $conf_data = $this->mikoPBXConfig->getGeneralSettings('SSHAuthorizedKeys');
668
        file_put_contents("{$ssh_dir}/authorized_keys", $conf_data);
669
    }
670
671
    /**
672
     * Устанавливаем пароль для пользователя системы.
673
     **/
674
    public function updateShellPassword(): void
675
    {
676
        $password = $this->mikoPBXConfig->getGeneralSettings('SSHPassword');
677
        $echoPath = Util::which('echo');
678
        $chpasswdPath = Util::which('chpasswd');
679
        Util::mwExec("{$echoPath} \"root:$password\" | {$chpasswdPath}");
680
    }
681
682
    /**
683
     * Запуск open vmware tools.
684
     */
685
    public function vmwareToolsConfigure(): void
686
    {
687
        Util::killByName("vmtoolsd");
688
        $virtualHW = $this->mikoPBXConfig->getGeneralSettings('VirtualHardwareType');
689
        if ('VMWARE' === $virtualHW) {
690
            $conf = "[logging]\n"
691
                . "log = false\n"
692
                . "vmtoolsd.level = none\n"
693
                . ";vmsvc.data = /dev/null\n"
694
                . "vmsvc.level = none\n";
695
696
            $dirVM = '/etc/vmware-tools';
697
            if(!file_exists($dirVM)){
698
                Util::mwMkdir($dirVM);
699
            }
700
701
            file_put_contents("{$dirVM}/tools.conf", $conf);
702
            $vmtoolsdPath = Util::which('vmtoolsd');
703
            Util::mwExec("{$vmtoolsdPath} --background=/var/run/vmtoolsd.pid > /dev/null 2> /dev/null");
704
        }
705
    }
706
707
    /**
708
     * Reboots the system after calling system_reboot_cleanup()
709
     *
710
     */
711
    public static function rebootSync(): void
712
    {
713
        $mikopbx_rebootPath = Util::which('mikopbx_reboot');
714
        Util::mwExec("{$mikopbx_rebootPath} > /dev/null 2>&1");
715
    }
716
717
    /**
718
     * Reboots the system after calling system_reboot_cleanup()
719
     *
720
     */
721
    public static function rebootSyncBg(): void
722
    {
723
        $mikopbx_rebootPath = Util::which('mikopbx_reboot');
724
        Util::mwExecBg("{$mikopbx_rebootPath} > /dev/null 2>&1");
725
    }
726
727
    /**
728
     * Shutdown the system.
729
     */
730
    public static function shutdown(): void
731
    {
732
        $shutdownPath = Util::which('shutdown');
733
        Util::mwExec("{$shutdownPath} > /dev/null 2>&1");
734
    }
735
}
736