/** * Update gpg Signature check for a single module * @param {string} $modulename Raw Module Name */ public function updateSignature($modulename) { try { $mod = FreePBX::GPG()->verifyModule($modulename); $revoked = $mod['status'] & GPG::STATE_REVOKED; //if revoked then disable if ($revoked) { $this->disable($modulename); } $sql = "UPDATE `modules` SET signature = ? WHERE modulename = ?"; $sth = FreePBX::Database()->prepare($sql); $sth->execute(array(json_encode($mod), $modulename)); } catch (\Exception $e) { $mod = null; } return $mod; }
private function refreshsignatures() { \FreePBX::GPG(); $fpbxmodules = \FreePBX::Modules(); $list = $fpbxmodules->getActiveModules(); $this->writeln(_("Getting Data from Online Server...")); $modules_online = $this->mf->getonlinexml(); if (empty($modules_online)) { $this->writeln(_('Cant Reach Online Server')); exit(1); } else { $this->writeln(_("Done")); } $this->writeln(_("Checking Signatures of Modules...")); foreach ($list as $m) { //Check signature status, then if its online then if its signed online then redownload (through force) $this->writeln(sprintf(_("Checking %s..."), $m['rawname'])); if (isset($m['signature']['status']) && ~$m['signature']['status'] & \FreePBX\GPG::STATE_GOOD) { $this->writeln(_("Signature Invalid")); if (isset($modules_online[$m['rawname']]) && isset($modules_online[$m['rawname']]['signed'])) { $this->writeln("\t" . sprintf(_("Refreshing %s"), $m['rawname'])); $modulename = $m['rawname']; $modules = $fpbxmodules->getinfo($modulename); $this->doUpgrade($modulename, true); $this->writeln("\t" . _("Verifying GPG...")); $this->mf->updateSignature($modulename); $this->writeln(_("Done")); } else { $this->writeln("\t" . _("Could not find signed module on remote server!"), "error", false); } } else { $this->writeln(_("Good")); } } $this->writeln(_("Done")); }
break; case MODULE_STATUS_DISABLED: $headerclass .= ' disabled'; break; case MODULE_STATUS_ENABLED: $headerclass .= ' enabled'; break; case MODULE_STATUS_NEEDUPGRADE: $headerclass .= ' needupgrade'; break; case MODULE_STATUS_BROKEN: $headerclass .= ' broken'; break; } if (FreePBX::Config()->get('SIGNATURECHECK')) { FreePBX::GPG(); if (!empty($modules[$name]['signature']) && is_int($modules[$name]['signature']['status']) && ~$modules[$name]['signature']['status'] & \FreePBX\GPG::STATE_GOOD) { switch (true) { case $modules[$name]['signature']['status'] & \FreePBX\GPG::STATE_TAMPERED: $headerclass .= " tampered"; $module_display[$category]['data'][$name]['signature']['message'] = _("Module has been tampered. Please redownload"); break; case $modules[$name]['signature']['status'] & \FreePBX\GPG::STATE_UNSIGNED: $headerclass .= " unsigned"; $module_display[$category]['data'][$name]['signature']['message'] = _("Module is Unsigned"); break; case $modules[$name]['signature']['status'] & \FreePBX\GPG::STATE_INVALID: $headerclass .= " invalid"; $module_display[$category]['data'][$name]['signature']['message'] = _("Module has been signed with an invalid key"); break; case $modules[$name]['signature']['status'] & \FreePBX\GPG::STATE_REVOKED:
protected function execute(InputInterface $input, OutputInterface $output) { global $amp_conf; /* This makes pandas sad. :( */ if (version_compare(PHP_VERSION, '5.3.3', '<')) { //charset=utf8 requires php 5.3.6 (http://php.net/manual/en/mysqlinfo.concepts.charset.php) $output->writeln("<error>FreePBX Requires PHP Version 5.3.3 or Higher, you have: " . PHP_VERSION . "</error>"); return false; } //still needed for module_admin and retrieve_conf $filePath = stream_resolve_include_path('Console/Getopt.php'); if ($filePath === false) { $output->writeln("<error>PEAR must be installed (requires Console/Getopt.php)</error>"); return false; } $this->rootPath = dirname(__DIR__); date_default_timezone_set('America/Los_Angeles'); $style = new OutputFormatterStyle('white', 'black', array('bold')); $output->getFormatter()->setStyle('bold', $style); //STATIC??? define("AMP_CONF", "/etc/amportal.conf"); define("ODBC_INI", "/etc/odbc.ini"); define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf"); define("FREEPBX_CONF", "/etc/freepbx.conf"); define("FILES_DIR", $this->rootPath . "/installlib/files"); define("SQL_DIR", $this->rootPath . "/installlib/SQL"); define("MODULE_DIR", $this->rootPath . "/amp_conf/htdocs/admin/modules"); define("UPGRADE_DIR", $this->rootPath . "/upgrades"); // Fail if !root $euid = posix_getpwuid(posix_geteuid()); if ($euid['name'] != 'root') { $output->writeln("<error>" . $this->getName() . " must be run as root</error>"); exit(1); } foreach ($this->settings as $key => $setting) { $answers[$key] = $input->getOption($key); } if ($input->isInteractive()) { $helper = $this->getHelper('question'); foreach ($this->settings as $key => $setting) { if (isset($setting['default'])) { $question = new Question($setting['description'] . ($setting['default'] ? ' [' . $setting['default'] . ']' : '') . ': ', $answers[$key]); $answers[$key] = $helper->ask($input, $output, $question); } } } $dbroot = $input->getOption('rootdb'); $force = $input->getOption('force'); if ($force) { $output->writeln("<info>Force Install. This will reset everything!</info>"); } if ($dbroot || $answers['dbuser'] == 'root') { $output->writeln("<info>Assuming you are Database Root</info>"); $dbroot = true; } // Make sure SELinux is disabled $output->write("Checking if SELinux is enabled..."); exec("getenforce 2>/dev/null", $tmpout, $ret); if (isset($tmpout[0]) && ($tmpout[0] === "Enabled" || $tmpout[0] === "Enforcing")) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>SELinux is enabled. Please disable SELinux before installing FreePBX.</error>"); exit(1); } $output->writeln("Its not (good)!"); unset($tmpout); require_once 'installlib/installer.class.php'; $installer = new Installer($input, $output); // Copy asterisk.conf if (!file_exists(ASTERISK_CONF)) { $output->write("No " . ASTERISK_CONF . " file detected. Installing..."); $aconf = $installer->asterisk_conf_read(FILES_DIR . "/asterisk.conf"); if (empty($aconf['directories'])) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Unable to read " . FILES_DIR . "/asterisk.conf or it was missing a directories section</error>"); exit(1); } $aconf['directories']['astmoddir'] = file_exists('/usr/lib64/asterisk/modules') ? '/usr/lib64/asterisk/modules' : '/usr/lib/asterisk/modules'; $installer->asterisk_conf_write(ASTERISK_CONF, $aconf); $asterisk_conf = $aconf['directories']; $output->writeln("Done!"); } else { $output->write("Reading " . ASTERISK_CONF . "..."); $aconf = $installer->asterisk_conf_read(ASTERISK_CONF); if (empty($aconf['directories'])) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Unable to read " . ASTERISK_CONF . " or it was missing a directories section</error>"); exit(1); } $output->writeln("Done"); $asterisk_conf = $aconf['directories']; $asterisk_defaults_conf = array('astetcdir' => '/etc/asterisk', 'astmoddir' => file_exists('/usr/lib64/asterisk/modules') ? '/usr/lib64/asterisk/modules' : '/usr/lib/asterisk/modules', 'astvarlibdir' => '/var/lib/asterisk', 'astagidir' => '/var/lib/asterisk/agi-bin', 'astspooldir' => '/var/spool/asterisk', 'astrundir' => '/var/run/asterisk', 'astlogdir' => '/var/log/asterisk'); foreach ($asterisk_defaults_conf as $key => $value) { if (!isset($asterisk_conf[$key])) { $asterisk_conf[$key] = $value; } } } //Check Asterisk (before file writes) $output->write("Checking if Asterisk is running and we can talk to it as the '" . $answers['user'] . "' user..."); $c = 0; $determined = false; while ($c < 5) { exec("sudo -u " . $answers['user'] . " asterisk -rx 'core show version' 2>&1", $tmpout, $ret); if ($ret != 0) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Error communicating with Asterisk. Ensure that Asterisk is properly installed and running as the " . $answers['user'] . " user</error>"); if (file_exists($asterisk_conf['astrundir'] . "/asterisk.ctl")) { $info = posix_getpwuid(fileowner($asterisk_conf['astrundir'] . "/asterisk.ctl")); $output->writeln("<error>Asterisk appears to be running as " . $info['name'] . "</error>"); } else { $output->writeln("<error>Asterisk does not appear to be running</error>"); } $output->writeln("<error>Try starting Asterisk with the './start_asterisk start' command in this directory</error>"); exit(1); } else { $astver = $tmpout[0]; unset($tmpout); // Parse Asterisk version. if (preg_match('/^Asterisk (?:SVN-|GIT-)?(?:branch-)?(\\d+(\\.\\d+)*)(-?(.*)) built/', $astver, $matches)) { $determined = true; if (version_compare($matches[1], "11") < 0 || version_compare($matches[1], "15", "ge")) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Unsupported Version of " . $matches[1] . "</error>"); $output->writeln("<error>Supported Asterisk versions: 11, 12, 13, 14</error>"); exit(1); } break; } } sleep(1); $c++; } if (!$determined) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Could not determine Asterisk version (got: " . $astver . "). Please report this.</error>"); } $output->writeln("Done!"); if (file_exists(FREEPBX_CONF) && !file_exists(AMP_CONF) || !file_exists(FREEPBX_CONF) && file_exists(AMP_CONF)) { if (file_exists(FREEPBX_CONF)) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Half-baked install previously detected. " . FREEPBX_CONF . " should not exist if " . AMP_CONF . " does not exist</error>"); } else { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Half-baked install previously detected. " . AMP_CONF . " should not exist if " . FREEPBX_CONF . " does not exist</error>"); } exit(1); } $output->writeln("Preliminary checks done. Starting FreePBX Installation"); // Copy default amportal.conf $output->write("Checking if this is a new install..."); if (!file_exists(AMP_CONF) || $force) { $output->writeln("Yes (No " . AMP_CONF . " file detected)"); $newinstall = true; require_once 'amp_conf/htdocs/admin/functions.inc.php'; } else { $output->writeln("No (" . AMP_CONF . " file detected)"); $bootstrap_settings['freepbx_auth'] = false; $restrict_mods = true; if (!@(include_once getenv('FREEPBX_CONF') ? getenv('FREEPBX_CONF') : '/etc/freepbx.conf')) { include_once '/etc/asterisk/freepbx.conf'; } } if (isset($answers['dbengine'])) { $amp_conf['AMPDBENGINE'] = $answers['dbengine']; } if (isset($answers['dbname'])) { $amp_conf['AMPDBNAME'] = $answers['dbname']; } if (isset($answers['cdrdbname'])) { $amp_conf['CDRDBNAME'] = $answers['cdrdbname']; } if (isset($answers['webroot'])) { $amp_conf['AMPWEBROOT'] = $answers['webroot']; } if (isset($answers['user'])) { $amp_conf['AMPASTERISKUSER'] = $answers['user']; $amp_conf['AMPASTERISKWEBUSER'] = $answers['user']; $amp_conf['AMPDEVUSER'] = $answers['user']; } if (isset($answers['group'])) { $amp_conf['AMPASTERISKGROUP'] = $answers['group']; $amp_conf['AMPASTERISKWEBGROUP'] = $answers['group']; $amp_conf['AMPDEVGROUP'] = $answers['group']; } if (!isset($amp_conf['AMPMANAGERHOST'])) { $amp_conf['AMPMANAGERHOST'] = 'localhost'; } if ($newinstall || $force) { $amp_conf['AMPMGRUSER'] = '******'; $amp_conf['AMPMGRPASS'] = md5(uniqid()); $amp_conf['AMPDBUSER'] = $answers['dbuser']; $amp_conf['AMPDBPASS'] = $answers['dbpass']; $amp_conf['AMPDBHOST'] = 'localhost'; if ($dbroot) { $output->write("Database Root installation checking credentials and permissions.."); } else { $output->write("Database installation checking credentials and permissions.."); } $dsn = $amp_conf['AMPDBENGINE'] . ":host=" . $amp_conf['AMPDBHOST']; try { $pdodb = new \PDO($dsn, $amp_conf['AMPDBUSER'], $amp_conf['AMPDBPASS']); } catch (\Exception $e) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Invalid Database Permissions. The error was: " . $e->getMessage() . "</error>"); exit(1); } $output->writeln("Connected!"); } if (!file_exists(ODBC_INI)) { $output->write("No " . ODBC_INI . " file detected. Installing..."); if (!copy(FILES_DIR . "/odbc.ini", ODBC_INI)) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Unable to copy " . FILES_DIR . "/odbc.ini to " . ODBC_INI . "</error>"); exit(1); } $output->writeln("Done"); } elseif (file_exists(ODBC_INI)) { $conf = file_get_contents(ODBC_INI); $conf = trim($conf); if (empty($conf)) { $output->write("Blank " . ODBC_INI . " file detected. Installing..."); if (!copy(FILES_DIR . "/odbc.ini", ODBC_INI)) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Unable to copy " . FILES_DIR . "/odbc.ini to " . ODBC_INI . "</error>"); exit(1); } $output->writeln("Done"); } } if (isset($asterisk_conf['astetcdir'])) { $amp_conf['ASTETCDIR'] = $asterisk_conf['astetcdir']; } if (isset($asterisk_conf['astmoddir'])) { $amp_conf['ASTMODDIR'] = $asterisk_conf['astmoddir']; } if (isset($asterisk_conf['astvarlibdir'])) { $amp_conf['ASTVARLIBDIR'] = $asterisk_conf['astvarlibdir']; } if (isset($asterisk_conf['astagidir'])) { $amp_conf['ASTAGIDIR'] = $asterisk_conf['astagidir']; } if (isset($asterisk_conf['astspooldir'])) { $amp_conf['ASTSPOOLDIR'] = $asterisk_conf['astspooldir']; } if (isset($asterisk_conf['astrundir'])) { $amp_conf['ASTRUNDIR'] = $asterisk_conf['astrundir']; } if (isset($asterisk_conf['astlogdir'])) { $amp_conf['ASTLOGDIR'] = $asterisk_conf['astlogdir']; } // Create database(s). if ($newinstall) { global $db; require_once 'amp_conf/htdocs/admin/libraries/BMO/FreePBX.class.php'; require_once 'amp_conf/htdocs/admin/libraries/DB.class.php'; if ($dbroot) { $amp_conf['AMPDBUSER'] = '******'; $amp_conf['AMPDBPASS'] = md5(uniqid()); } else { $amp_conf['AMPDBUSER'] = $answers['dbuser']; $amp_conf['AMPDBPASS'] = $answers['dbpass']; } if ($dbroot) { if ($force) { $pdodb->query("DROP DATABASE IF EXISTS " . $amp_conf['AMPDBNAME']); } $pdodb->query("CREATE DATABASE IF NOT EXISTS " . $amp_conf['AMPDBNAME'] . " DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci"); $sql = "GRANT ALL PRIVILEGES ON " . $amp_conf['AMPDBNAME'] . ".* TO '" . $amp_conf['AMPDBUSER'] . "'@'localhost' IDENTIFIED BY '" . $amp_conf['AMPDBPASS'] . "'"; $pdodb->query($sql); } else { //check collate } $bmo = new \FreePBX($amp_conf); $dsn = $amp_conf['AMPDBENGINE'] . ":host=" . $amp_conf['AMPDBHOST']; $db = new \DB(new \FreePBX\Database($dsn, $answers['dbuser'], $answers['dbpass'])); $db->query("USE " . $amp_conf['AMPDBNAME']); $sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '" . $amp_conf['AMPDBNAME'] . "';"; if (!$db->getOne($sql)) { $output->writeln("Empty " . $amp_conf['AMPDBNAME'] . " Database going to populate it"); $installer->install_sql_file(SQL_DIR . '/asterisk.sql'); } if ($dbroot) { if ($force) { $db->query("DROP DATABASE IF EXISTS " . $amp_conf['CDRDBNAME']); } $db->query("CREATE DATABASE IF NOT EXISTS " . $amp_conf['CDRDBNAME'] . " DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci"); $sql = "GRANT ALL PRIVILEGES ON " . $amp_conf['CDRDBNAME'] . ".* TO '" . $amp_conf['AMPDBUSER'] . "'@'localhost' IDENTIFIED BY '" . $amp_conf['AMPDBPASS'] . "'"; $db->query($sql); } else { //check collate } $db->query("USE " . $amp_conf['CDRDBNAME']); $sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '" . $amp_conf['CDRDBNAME'] . "';"; if (!$db->getOne($sql)) { $output->writeln("Empty " . $amp_conf['CDRDBNAME'] . " Database going to populate it"); $installer->install_sql_file(SQL_DIR . '/cdr.sql'); } $db->query("USE " . $amp_conf['AMPDBNAME']); } // Get version of FreePBX. $version = $installer->get_version(); $output->writeln("Initializing FreePBX Settings"); $installer_amp_conf = $amp_conf; // freepbx_settings_init(); $installer->freepbx_settings_init(true); // Use the installer defined amp_conf settings $freepbx_conf =& \freepbx_conf::create(); foreach ($installer_amp_conf as $keyword => $value) { if ($freepbx_conf->conf_setting_exists($keyword) && $amp_conf[$keyword] != $value) { $output->writeln("\tChanging " . $keyword . " to match what was given at install time"); $freepbx_conf->set_conf_values(array($keyword => $value), false, true); } } $freepbx_conf->commit_conf_settings(); $output->writeln("Finished initalizing settings"); if (!file_exists($amp_conf['AMPWEBROOT'])) { @mkdir($amp_conf['AMPWEBROOT'], 0777, true); } if (!is_writeable($amp_conf['AMPWEBROOT'])) { throw new \Exception($amp_conf['AMPWEBROOT'] . " is NOT writable!"); } chown($amp_conf['AMPWEBROOT'], $amp_conf['AMPASTERISKWEBUSER']); // Copy amp_conf/ $verb = $answers['dev-links'] ? "Linking" : "Copying"; $output->writeln($verb . " files (this may take a bit)...."); if (is_dir($this->rootPath . "/amp_conf")) { $total_files = $this->getFileCount($this->rootPath . "/amp_conf"); $progress = new ProgressBar($output, $total_files); $progress->setRedrawFrequency(100); $progress->start(); $this->recursive_copy($input, $output, $progress, $this->rootPath . "/amp_conf", "", $newinstall, $answers['dev-links']); $progress->finish(); } $output->writeln(""); $output->writeln("Done"); //Last minute symlinks $sbin = \FreePBX::Config()->get("AMPSBIN"); $bin = \FreePBX::Config()->get("AMPBIN"); //Put new fwconsole into place if (!file_exists($sbin . "/fwconsole")) { $output->write("Symlinking " . $bin . "/fwconsole to " . $sbin . "/fwconsole ..."); if (!symlink($bin . "/fwconsole", $sbin . "/fwconsole")) { $output->writeln("<error>Error</error>"); } $output->writeln("Done"); } elseif (file_exists($sbin . "/fwconsole") && (!is_link($sbin . "/fwconsole") || readlink($sbin . "/fwconsole") != $bin . "/fwconsole")) { unlink($sbin . "/fwconsole"); $output->write("Symlinking " . $bin . "/fwconsole to " . $sbin . "/fwconsole ..."); if (!symlink($bin . "/fwconsole", $sbin . "/fwconsole")) { $output->writeln("<error>Error</error>"); } $output->writeln("Done"); } //put old amportal into place if (!file_exists($sbin . "/amportal")) { if (is_link($sbin . "/amportal")) { unlink($sbin . "/amportal"); } $output->write("Symlinking " . $bin . "/amportal to " . $sbin . "/amportal ..."); if (!symlink($bin . "/amportal", $sbin . "/amportal")) { $output->writeln("<error>Error</error>"); } $output->writeln("Done"); } elseif (file_exists($sbin . "/amportal") && (!is_link($sbin . "/amportal") || readlink($sbin . "/amportal") != $bin . "/amportal")) { unlink($sbin . "/amportal"); $output->write("Symlinking " . $bin . "/amportal to " . $sbin . "/amportal ..."); if (!symlink($bin . "/amportal", $sbin . "/amportal")) { $output->writeln("<error>Error</error>"); } $output->writeln("Done"); } $output->write("Finishing up directory processes..."); $binFiles = array($bin . "/freepbx_engine" => 0755, $bin . "/freepbx_setting" => 0755, $bin . "/fwconsole" => 0755, $bin . "/gen_amp_conf" => 0755, $bin . "/retrieve_conf" => 0755, $sbin . "/amportal" => 0755, $sbin . "/fwconsole" => 0755); foreach ($binFiles as $file => $perms) { if (file_exists($file)) { chmod($file, $perms); } } // Create dirs // /var/www/html/admin/modules/framework/ // /var/www/html/admin/modules/_cache/ // ./amp_conf/htdocs/admin/modules/_cache/ $extraDirs = array($amp_conf['AMPWEBROOT'] . "/admin/modules/_cache" => 0777, $amp_conf['AMPWEBROOT'] . "/admin/modules/framework" => 0777, $amp_conf['ASTSPOOLDIR'] . "/voicemail/device" => 0755, $amp_conf['ASTSPOOLDIR'] . "/fax" => 0766, $amp_conf['ASTSPOOLDIR'] . "/monitor" => 0766); foreach ($extraDirs as $dir => $perms) { if (!file_exists($dir)) { mkdir($dir, $perms, true); } } $copyFrameworkFiles = array("module.xml", "module.sig", "install.php", "LICENSE", "README.md"); foreach ($copyFrameworkFiles as $file) { if (file_exists($this->rootPath . "/" . $file)) { copy($this->rootPath . "/" . $file, $amp_conf['AMPWEBROOT'] . "/admin/modules/framework/" . $file); } } // Copy /etc/asterisk/voicemail.conf.template // ... to /etc/asterisk/voicemail.conf if (!file_exists($amp_conf['ASTETCDIR'] . "/voicemail.conf")) { copy($amp_conf['ASTETCDIR'] . "/voicemail.conf.template", $amp_conf['ASTETCDIR'] . "/voicemail.conf"); } $output->writeln("Done!"); // Create missing #include files. $output->write("Creating missing #include files..."); foreach (glob($amp_conf['ASTETCDIR'] . "/*.conf") as $file) { $data = file_get_contents($file); if (preg_match_all("/#include\\s(.*)/", $data, $matches)) { if (!empty($matches[1])) { foreach ($matches[1] as $include) { if (!file_exists($amp_conf['ASTETCDIR'] . "/" . $include)) { touch($amp_conf['ASTETCDIR'] . "/" . $include); } } } } } $output->writeln("Done"); //File variable replacement $rfiles = array($amp_conf['ASTETCDIR'] . "/manager.conf", $amp_conf['ASTETCDIR'] . "/cdr_adaptive_odbc.conf", ODBC_INI); $output->write("Running variable replacement..."); foreach ($rfiles as $file) { if (!file_exists($file) || !is_writable($file)) { continue; } $conf = file_get_contents($file); $replace = array('AMPMGRUSER' => $amp_conf['AMPMGRUSER'], 'AMPMGRPASS' => $amp_conf['AMPMGRPASS'], 'CDRDBNAME' => $amp_conf['CDRDBNAME'], 'AMPDBUSER' => $amp_conf['AMPDBUSER'], 'AMPDBPASS' => $amp_conf['AMPDBPASS']); $conf = str_replace(array_keys($replace), array_values($replace), $conf); file_put_contents($file, $conf); } $output->writeln("Done"); //setup and get manager working $output->write("Setting up Asterisk Manager Connection..."); exec("sudo -u " . $answers['user'] . " asterisk -rx 'module reload manager'", $o, $r); if ($r !== 0) { $output->writeln("<error>Unable to reload Asterisk Manager</error>"); exit(127); } //TODO: we should check to make sure manager worked at this stage.. $output->writeln("Done"); $output->writeln("Running through upgrades..."); // Upgrade framework (upgrades/ dir) $installer->install_upgrades($version); $output->writeln("Finished upgrades"); $fwxml = simplexml_load_file($this->rootPath . '/module.xml'); //setversion to whatever is in framework.xml forever for here on out. $fwver = (string) $fwxml->version; $output->write("Setting FreePBX version to " . $fwver . "..."); $installer->set_version($fwver); $output->writeln("Done"); $output->write("Writing out " . AMP_CONF . "..."); if (!file_put_contents(AMP_CONF, $freepbx_conf->amportal_generate(true))) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Unable to write to file</error>"); exit(1); } $output->writeln("Done"); if ($newinstall) { /* Write freepbx.conf */ $conf = "<?php\n\$amp_conf['AMPDBUSER'] = '******'AMPDBUSER']}';\n\$amp_conf['AMPDBPASS'] = '******'AMPDBPASS']}';\n\$amp_conf['AMPDBHOST'] = '{$amp_conf['AMPDBHOST']}';\n\$amp_conf['AMPDBNAME'] = '{$amp_conf['AMPDBNAME']}';\n\$amp_conf['AMPDBENGINE'] = '{$amp_conf['AMPDBENGINE']}';\n\$amp_conf['datasource'] = ''; //for sqlite3\n\nrequire_once('{$amp_conf['AMPWEBROOT']}/admin/bootstrap.php');\n"; $output->write("Writing out " . FREEPBX_CONF . "..."); if (!file_put_contents(FREEPBX_CONF, $conf)) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Unable to write to file</error>"); exit(1); } $output->writeln("Done"); } //run this here so that we make sure everything is square for asterisk passthru($amp_conf['AMPSBIN'] . "/fwconsole chown"); if (!$answers['dev-links']) { // install_modules() $included_modules = array(); /* read modules list from MODULE_DIR */ if (file_exists(MODULE_DIR)) { $dir = opendir(MODULE_DIR); while ($file = readdir($dir)) { if ($file[0] != "." && $file[0] != "_" && is_dir(MODULE_DIR . "/" . $file)) { $included_modules[] = $file; } } closedir($dir); $output->write("Installing all modules..."); $this->install_modules($included_modules); $output->writeln("Done installing modules"); } } // module_admin install framework $output->writeln("Installing framework..."); $this->install_modules(array('framework')); $output->writeln("Done"); // generate_configs(); $output->writeln("Generating default configurations..."); passthru("sudo -u " . $amp_conf['AMPASTERISKUSER'] . " " . $amp_conf["AMPBIN"] . "/retrieve_conf --skip-registry-checks"); $output->writeln("Finished generating default configurations"); // GPG setup - trustFreePBX(); $output->write("Trusting FreePBX..."); try { \FreePBX::GPG()->trustFreePBX(); } catch (\Exception $e) { $output->writeln("<error>Error!</error>"); $output->writeln("<error>Error while trusting FreePBX: " . $e->getMessage() . "</error>"); exit(1); } $output->writeln("Trusted"); //run this here so that we make sure everything is square for asterisk passthru($amp_conf['AMPSBIN'] . "/fwconsole chown"); $output->writeln("<info>You have successfully installed FreePBX</info>"); }
public function testLocalValidation() { $gpg = \FreePBX::GPG(); $modulexml = base64_decode("PG1vZHVsZT4KCTxyYXduYW1lPmdwZ3Rlc3Q8L3Jhd25hbWU+Cgk8bmFtZT5Vbml0IFRlc3QgTW9kdWxlPC9uYW1lPgoJPHZlcnNpb24+MTMuMC4xPC92ZXJzaW9uPgoJPHB1Ymxpc2hlcj5TYW5nb21hIFRlY2hub2xvZ2llcyBDb3Jwb3JhdGlvbjwvcHVibGlzaGVyPgoJPGxpY2Vuc2U+QUdQTHYzKzwvbGljZW5zZT4KCTxsaWNlbnNlbGluaz5odHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC0zLjAudHh0PC9saWNlbnNlbGluaz4KCTxkZXNjcmlwdGlvbj5Vc2VkIG9ubHkgZm9yIFVuaXQgVGVzdGluZzwvZGVzY3JpcHRpb24+Cgk8Y2hhbmdlbG9nPioxMy4wLjEqIFJlbGVhc2U8L2NoYW5nZWxvZz4KCTxtZW51aXRlbXM+PGdwZ3Rlc3Q+RmlyZXdhbGw8L2dwZ3Rlc3Q+PC9tZW51aXRlbXM+Cgk8c3VwcG9ydGVkPjx2ZXJzaW9uPjEzLjA8L3ZlcnNpb24+PC9zdXBwb3J0ZWQ+CjwvbW9kdWxlPgo="); $finc = base64_decode("PD9waHAKLy8gdGhpcyBmaWxlIGRvZXMgbm90aGluZwpyZXR1cm4gZmFsc2U7Cg=="); $root = "/var/www/html/admin/modules/gpgtest"; `rm -rf {$root}`; @unlink("/etc/freepbx.secure/gpgtest.sig"); mkdir($root); file_put_contents("{$root}/module.xml", $modulexml); file_put_contents("{$root}/functions.inc.php", $finc); // Various module.sig files $unsigned = gzuncompress(base64_decode("eJydUk1z2jAQvetXKJNLOy3ENvJXOj44YBsIeOwYktBMDpIlG8VGBn+Aya+vCXR6aC/NXqTV7tu3+7S9Xmd3jjfxYeAFMJp4vjOCcyeKbM85xXpgjKv1LYzGtgzAj+v/tA4BL+aWjAV3z3Be0CZnMOKpwHVTMujyzv1t15/jGBVQFDXEec1KWK8ZjAtRM1FXsEg6n1cw6ViuIJwkZ44/j7A7a7zZspJReOD1+vtHgc25zQPP8wsiwTyHe5xzimteCIgFhaRLxGXWIXEFufiIXn12DvDSdZ3w9BXsWVl1FJYC1p36VrXGiqqBqpOM0VOLFpJUw1A0TTds3XSH6BIjR+t06W/XW1CybWFtsGhwDkp8EHjDrHSb1qyqQX3cMmvbkJzH4OVEwapXkDQiPg1WneDQgmqMsWnGipwQrOIBlSRGVUKoyQxTxgM16XxkyirRJJ3pxJBkZCBNi3VNkk2iUnCWsN9u8q7agCWIUZ0SwyBU1lSDGURLKNUGKFExijVk6FjRTF2WqSbhmMYmolhhSKKJTFT59AOOoKD398bai+XDZVkfz8LdQk80gQf3Sl/qywh+8fzlzYyLpv0KAJ8eHDt0hra9cu18lUfz0B6mWRi6fPhTcCGMaLpLA9NdzSovJJm7coyqGZRqGXtLFbXgzTve8OLQTldOkSqRsvHfA7YW+uJOT1Fr5Hq0dx9yubLps1OjZZu4bVNk95Nj1EYkIE9gqr/76Ml73+TOOHNjKQsP99Wu3uW1F38bJdq0Sxr5AxaWM+Y/zH3XLHePQsyq1Cmni7cV8Bd2lqqr4GmYHe/8uSHCwgLWWLjJWR/HH/1LnV+kbBsi")); $signed = gzuncompress(base64_decode("eJydU8m2ozYQ3fMV9OlNcpz3DJixc7wAgw0eGIzx1KcXEgiQLQYz2OCvD+73crJINunaSKWrqlt1pXp7G0wzFpZNuwuX9q2Fbej0xvB9dWG8sDfKBHX6jfZNlaWoP7/+Txsi6E+bVwi52pHeFFFLEO3jJAdNWyF6jgf3b/v6axx6QedFQwPSoIpuUkSHRd6gvKnpIh58XNPxwPKFpq34g+OfQ3pYG5CVqEIR/cBN+sfPBNlHmQ9MyGdEDDCh74DgCDS4yGmQRzQcLoLqOkSCmsb5T/TLr/ZBfR+qjnHyg7qjqh4ophyVDupP6xRwgkjVg2QoepU4Fdi5oImyzgmsIOgz7ROD/fS1eS/TkqpQWUwzkLeAUBV45CBD06RMGlQ3VNOXaFq2kOCQ+v6iQPUPKm7z8NVY/Y7z8JWCntJCCICihBwbQyCAScQwKBIgjBQkKyyYCPHg8worQJGRkARlhuVlXhRDSWRYBQoR9SHje5eRIdsExTyKpAjKMoxYUZCRDMU4isQJHwuAD0VelgAnKhLLRiIDwihU+AhwiGeimIUC+3oFI4+ot3//WnUXbD8/7P5DvG/0Im/dBX3n3pl3lqd/W9jBeI3ztvudorBnhZpqaGqiLjRveVgespmqFktjbrJNwZD5frJu9MIdcwXXrgRVAbdtse5GaZss6o2qUZtj2dlaeb6O2AFlDM2SDhlhrw5YZlDk+EWRBHYN1+VT6O2+bAyF3aRYZYm6ZHoTXCnbAS0h50dKVi3UFen23G7llb4OknrLna18LK12mcKoj3N0XWnShb0gL/Bl7cS36Y3cV1TceMsJYNeCWp+a2wRXx/6CZ7hBfGV2MQHbw7X2yEyThf345OzIk+G7p3/f9+vzVT8edWq8D4gQBSdptwHczeuN8f4wI7Ml2s8T09QUrRdEdbxtH5cSL8KOiWCXqdDLVSkweei2lHme8ZV7Xx0IvlnAPekSmB3O+8XBGSUrfHd7eEPsg3Q+xMTxb+DCe/2xjcx43ey32zFPabITVgGL0hmYhfXD0Wc+a6lj4iELx9bWNLYwcff71lm5zGh1uUsJQVJd+SN86khfzSllJpx7ZhxG6fNZqZuVXU3yYx+NjaM4OimGzcLqWjo53lTc/O4Y8CCWwXUeS92t5ws1PlFNmV6SKjhcU8jsi+OukcKk6opwXhXqfIUXpv0s8lsEL1Z/ljlzLW28UNcgWiqlkTe7lupF9uobGPoP+Q4fQdD1cng/+tpVarCKrEc8dmUmK0DlWcX6JNlmGU5GT9/xt66ztrYJVd55qdTZ2y3QeeNY4drLJbteZgrgZa8xS4tj5t7tpCtHxR1JTS1Uu72Tb0h8dqJN5iZUpxG5KtV0lmvpLludbCHVqGnAVYuPOTFs/b+m5C+M4chs")); $localsecure = gzuncompress(base64_decode("eJydUstymzAU3esrlMmmndYOYJ7psIAYE6cxfhDbMZksJCRAMRYEgV9fXxy700W7ac5Gujq699x7pE6nhev5wwBO/AkMh37g9eHIC0PH905cB9wjkd3C8N6RAfhx/Z9oM+AFg4rSifsMRwVpcgpDlnJUNxWFA9aGv3H9OY1+AXlRQ5TXtIJ1RmFc8JryWsAiaWMmYNKqXEE4TM4afw5hu9ZoU9KKErhjdfb9o8Dm3OaO5fklI0Esh1uUM4JqVnCIOIG4vYiqdZuJBGT8g7367Bzgpe06Yekr2NJKtBK2ArLWfVtkSNF0IFrLKDm1aKuSZpqKrhumY1iDO/XC4YN92nTLrAQVLQt7g3iDclChHUcbaqdlWlNRg/pQUjsv4pZ6OSlQ8QqShsenuUSX8fhUAdpQixGyrFiRE4w01COSRImGMbGoacmopyVtrFqyhnXJoAY2JVk1VV2PDV2SLawRcHaxu9/kbbUeTVRKDIJNExNZ10xqYj0hRO+piYbUWFdNAym6Zcgy0SUUk9hSCVKoKpFExpp8egSPE9D5+9M6T/PZ5b8uzt7dQp83Ex9ula7UlVX4xQ/mN4+MN/uvALCHnedMvTvHWQ2cfJVHSuzcpevpdMDuIs44N8P+ejr5NpamaSXGkirezc2TNWrenfCngg3grpVy6bG5G1izkHvbanus6pCjfd8VmeiVRvOsHKPigcz8BW4Wbrb0ZDRbvg0CYj37mQXG/fJ4GAbHN+wQfbhcYS1/6HE/XtfNIZX0d+vejTyFaonYPw6LtIyWZmA2kTGIhHZTH/cgOLqHUZnSSHubL4zZWPq2soGNNsXk7I8X9P/lzi+vixtj")); $modsecure = gzuncompress(base64_decode("eJydUstymzAU3esrlMmmndYPMC+nwwI7gJ3ExDYktpPJQoAAxbLAILDp11eO3emi3TRno/s+955RpyMwst2pB+fuHPpT17Nv4cz2fcu1T7kOmKAqu4H+xJIA+HH9nxAd8AKnxHg+WsNZHtcUQ5+kDPG6xNAhwv2N689x3OaQ5RwiynEJeYZhlDOOGa9gngifVDARLFcQTpMzx58gFC9HuwKXOIYHwrPvHwN25zUPhNJLR4IIhQ2iJEac5AwiFsNQFKJyKzpRBQn7yF599g7wKrZOSPoGGlxWgsKUQSbUN6sMyaoGKiEZjk8rmkpfNQxZ03TD0ofOWLnkwtY8Gd0iK0CJi9ykeYQo4G2BL+braSCu3kBapBxXvCvqoQlRiA1Jj/VEDYfISFSkRNpADbVkYCiSgmRZiuJBrISKpsu6hOIwEXF1GA+URB7Kugw6f38kK3haXv7Q8/meG+iyeu7CRu72u5ICv7jeU++BsPr4FQByd7CthT22rI1j0Q19kSNrnG4XC4eMXxhhzFhmqTXv4R5a5a6GDO19Pw3KPgtWW/3FaQFV0ju9T1SvlB4SNzvaQU2dcE+dxA3qb/Lo57E/3tgsraPGdatq+Gi14WwfqdnaP8zSbwNQSOSeT+VBMm4X4VHymkheFV6zTb2A7lz/zp748W5tl/WuQZMHZRJy7ljLvvMetvrg3dkAun4eNe1qHuyz+2Vv2D7NFiYwe/rj7qyP7d3+S51f1s75KA==")); // Now put them in place and check their status. file_put_contents("{$root}/module.sig", $unsigned); $check = $gpg->verifyModule("gpgtest"); $this->assertTrue(($check['status'] & FreePBX\GPG::STATE_TAMPERED) == FreePBX\GPG::STATE_TAMPERED, "Not Tampered"); file_put_contents("{$root}/module.sig", $signed); $check = $gpg->verifyModule("gpgtest"); $good = FreePBX\GPG::STATE_GOOD | FreePBX\GPG::STATE_TRUSTED; $this->assertTrue($check['status'] === $good, "Not trusted"); file_put_contents("{$root}/module.sig", $modsecure); try { $check = $gpg->verifyModule("gpgtest", true); $this->assertFalse($check['status'] === $good, "Local shouldn't be trusted, but it is"); $this->fail("This shouldn't have been reached"); } catch (\Exception $e) { // Passed $this->assertTrue(true, "threw when it should have"); } file_put_contents("/etc/freepbx.secure/gpgtest.sig", $localsecure); $check = $gpg->verifyModule("gpgtest"); $this->assertTrue($check['status'] === $good, "Local Not trusted when it should be"); // Check tampered status file_put_contents("{$root}/functions.inc.php", "{$finc}\n\n"); $check = $gpg->verifyModule("gpgtest", true); $this->assertTrue(($check['status'] & FreePBX\GPG::STATE_TAMPERED) == FreePBX\GPG::STATE_TAMPERED, "Not Tampered"); file_put_contents("{$root}/module.sig", $signed); $check = $gpg->verifyModule("gpgtest"); $this->assertTrue(($check['status'] & FreePBX\GPG::STATE_TAMPERED) == FreePBX\GPG::STATE_TAMPERED, "Not Tampered"); unlink("/etc/freepbx.secure/gpgtest.sig"); }
protected function execute(InputInterface $input, OutputInterface $output, $quiet = false) { if (posix_geteuid() != 0) { $output->writeln("<error>" . _("You need to be root to run this command") . "</error>"); exit(1); } $this->quiet = $quiet; if (!$this->quiet) { $output->writeln(_("Setting Permissions") . "..."); } $freepbx_conf = \freepbx_conf::create(); $conf = $freepbx_conf->get_conf_settings(); foreach ($conf as $key => $val) { ${$key} = $val['value']; } /* * These are files Framework is responsible for This list can be * reduced by moving responsibility to other modules as a hook * where appropriate. * * Types: * file: Set permissions/ownership on a single item * dir: Set permissions/ownership on a single directory * rdir: Set permissions/ownership on a single directory then recursively on * files within less the execute bit. If the dir is 755, child files will be 644, * child directories will be set the same as the parent. * execdir: Same as rdir but the execute bit is not stripped. */ $sessdir = session_save_path(); $sessdir = !empty($session) ? $session : '/var/lib/php/session'; $args = array(); if ($input) { $args = $input->getArgument('args'); $this->moduleName = !empty($this->moduleName) ? $this->moduleName : strtolower($args[0]); } // Always update hooks before running a Chown \FreePBX::Hooks()->updateBMOHooks(); if (!empty($this->moduleName) && $this->moduleName != 'framework') { $mod = $this->moduleName; $this->modfiles[$mod][] = array('type' => 'rdir', 'path' => $AMPWEBROOT . '/admin/modules/' . $mod, 'perms' => 0755); $hooks = $this->fwcChownFiles(); $current = isset($hooks[ucfirst($mod)]) ? $hooks[ucfirst($mod)] : false; if (is_array($current)) { $this->modfiles[$mod] = array_merge_recursive($this->modfiles[$mod], $current); } } else { $webuser = \FreePBX::Freepbx_conf()->get('AMPASTERISKWEBUSER'); $web = posix_getpwnam($webuser); if (!$web) { throw new \Exception(sprintf(_("I tried to find out about %s, but the system doesn't think that user exists"), $webuser)); } $home = trim($web['dir']); if (is_dir($home)) { $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $home, 'perms' => 0755); // SSH folder needs non-world-readable permissions (otherwise ssh complains, and refuses to work) $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => "{$home}/.ssh", 'perms' => 0700); } $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $sessdir, 'perms' => 0744); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/amportal.conf', 'perms' => 0640); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/freepbx.conf', 'perms' => 0640); $this->modfiles['framework'][] = array('type' => 'dir', 'path' => $ASTRUNDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => \FreePBX::GPG()->getGpgLocation(), 'perms' => 0755); //we may wish to declare these manually or through some automated fashion $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTETCDIR, 'perms' => 0750); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $ASTVARLIBDIR . '/.ssh/id_rsa', 'perms' => 0600); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTLOGDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTSPOOLDIR, 'perms' => 0755); //I have added these below individually, $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBXDBUGFILE, 'perms' => 0644); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBX_LOG_FILE, 'perms' => 0644); //We may wish to declare files individually rather than touching everything $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/' . $MOHDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/sounds', 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/obdc.ini', 'perms' => 0644); //we were doing a recursive on this which I think is not needed. //Changed to just be the directory //^ Needs to be the whole shebang, doesnt work otherwise $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $AMPWEBROOT, 'perms' => 0755); //Anything in bin and agi-bin should be exec'd //Should be after everything except but before hooks //So that we dont get overwritten by ampwebroot $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $AMPBIN, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $ASTAGIDIR, 'perms' => 0755); //Merge static files and hook files, then act on them as a single unit $fwcCF = $this->fwcChownFiles(); if (!empty($this->modfiles) && !empty($fwcCF)) { $this->modfiles = array_merge_recursive($this->modfiles, $fwcCF); } } $ampowner = $AMPASTERISKWEBUSER; /* Address concerns carried over from amportal in FREEPBX-8268. If the apache user is different * than the Asterisk user we provide permissions that allow both. */ $ampgroup = $AMPASTERISKWEBUSER != $AMPASTERISKUSER ? $AMPASTERISKGROUP : $AMPASTERISKWEBGROUP; foreach ($this->modfiles as $moduleName => $modfilelist) { foreach ($modfilelist as $file) { if (!isset($file['path']) || !isset($file['perms']) || !file_exists($file['path'])) { continue; } //Handle custom ownership (optional) $owner = isset($file['owner']) ? $file['owner'] : $ampowner; $group = isset($file['group']) ? $file['group'] : $ampgroup; //Set warning for bad permissions and move on $this->padPermissions($file['path'], $file['perms']); $file['type'] = isset($file['type']) ? $file['type'] : 'file'; switch ($file['type']) { case 'file': case 'dir': $path = \ForceUTF8\Encoding::toLatin1($file['path']); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } break; case 'rdir': $fileperms = $this->stripExecute($file['perms']); $files = $this->recursiveDirList($file['path']); $path = \ForceUTF8\Encoding::toLatin1($file['path']); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } foreach ($files as $f) { if (is_dir($f)) { $path = \ForceUTF8\Encoding::toLatin1($f); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } } else { $path = \ForceUTF8\Encoding::toLatin1($f); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $fileperms)); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } } } break; case 'execdir': $files = $this->recursiveDirList($file['path']); $path = \ForceUTF8\Encoding::toLatin1($file['path']); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } foreach ($files as $f) { $path = \ForceUTF8\Encoding::toLatin1($f); $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); $json = @json_encode(array($path, $owner, $group, $file['perms'])); $err = $this->jsonError(); if (empty($err)) { $this->actions->enqueue($json); } else { $this->errors[] = sprintf(_('An error occurred while adding file %s because %s'), $f, $err); } } break; } } } $actioncount = count($this->actions); if (!$this->quiet) { $progress = new ProgressBar($output, $actioncount); $progress->setRedrawFrequency(100); $progress->start(); } foreach ($this->actions as $action) { $action = json_decode($action, true); //Ignore call files, Asterisk may process/delete them before we get to them. if (pathinfo($action[0], PATHINFO_EXTENSION) == 'call') { continue; } $this->singleChown($action[0], $action[1], $action[2]); $this->singlePerms($action[0], $action[3]); if (!$this->quiet) { $progress->advance(); } } if (!$this->quiet) { $progress->finish(); $output->writeln(""); $output->writeln("Finished setting permissions"); foreach ($this->errors as $error) { $output->writeln("<error>" . $error . "</error>"); } foreach ($this->infos as $error) { $output->writeln("<info>" . $error . "</info>"); } } }
protected function execute(InputInterface $input, OutputInterface $output, $quiet = false) { $this->output = $output; if (posix_geteuid() != 0) { $output->writeln("<error>" . _("You need to be root to run this command") . "</error>"); exit(1); } $this->quiet = $quiet; $etcdir = \FreePBX::Config()->get('ASTETCDIR'); if (!$this->quiet) { if (!file_exists($etcdir . '/freepbx_chown.conf')) { $output->writeln("<info>" . sprintf(_("Taking too long? Customize the chown command, See %s"), "http://wiki.freepbx.org/display/FOP/FreePBX+Chown+Conf") . "</info>"); } $output->writeln(_("Setting Permissions") . "..."); } $freepbx_conf = \freepbx_conf::create(); $conf = $freepbx_conf->get_conf_settings(); foreach ($conf as $key => $val) { ${$key} = $val['value']; } /* * These are files Framework is responsible for This list can be * reduced by moving responsibility to other modules as a hook * where appropriate. * * Types: * file: Set permissions/ownership on a single item * dir: Set permissions/ownership on a single directory * rdir: Set permissions/ownership on a single directory then recursively on * files within less the execute bit. If the dir is 755, child files will be 644, * child directories will be set the same as the parent. * execdir: Same as rdir but the execute bit is not stripped. */ $sessdir = session_save_path(); $sessdir = !empty($sessdir) ? $sessdir : '/var/lib/php/session'; $args = array(); if ($input) { $args = $input->getArgument('args'); $mname = isset($args[0]) ? $args[0] : ''; $this->moduleName = !empty($this->moduleName) ? $this->moduleName : strtolower($mname); } // Always update hooks before running a Chown \FreePBX::Hooks()->updateBMOHooks(); if (!empty($this->moduleName) && $this->moduleName != 'framework') { $mod = $this->moduleName; $this->modfiles[$mod][] = array('type' => 'rdir', 'path' => $AMPWEBROOT . '/admin/modules/' . $mod, 'perms' => 0755); $hooks = $this->fwcChownFiles(); $current = isset($hooks[ucfirst($mod)]) ? $hooks[ucfirst($mod)] : false; if (is_array($current)) { $this->modfiles[$mod] = array_merge_recursive($this->modfiles[$mod], $current); } } else { $webuser = \FreePBX::Freepbx_conf()->get('AMPASTERISKWEBUSER'); $web = posix_getpwnam($webuser); if (!$web) { throw new \Exception(sprintf(_("I tried to find out about %s, but the system doesn't think that user exists"), $webuser)); } $home = trim($web['dir']); if (is_dir($home)) { $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $home, 'perms' => 0755); // SSH folder needs non-world-readable permissions (otherwise ssh complains, and refuses to work) $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => "{$home}/.ssh", 'perms' => 0700); } $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $sessdir, 'perms' => 0744, 'always' => true); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/amportal.conf', 'perms' => 0640, 'always' => true); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/freepbx.conf', 'perms' => 0640, 'always' => true); $this->modfiles['framework'][] = array('type' => 'dir', 'path' => $ASTRUNDIR, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => \FreePBX::GPG()->getGpgLocation(), 'perms' => 0755, 'always' => true); //we may wish to declare these manually or through some automated fashion $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTETCDIR, 'perms' => 0750, 'always' => true); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $ASTVARLIBDIR . '/.ssh/id_rsa', 'perms' => 0600); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTLOGDIR, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTSPOOLDIR, 'perms' => 0755); //I have added these below individually, $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBXDBUGFILE, 'perms' => 0644); $this->modfiles['framework'][] = array('type' => 'file', 'path' => $FPBX_LOG_FILE, 'perms' => 0644); //We may wish to declare files individually rather than touching everything $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/' . $MOHDIR, 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $ASTVARLIBDIR . '/sounds', 'perms' => 0755); $this->modfiles['framework'][] = array('type' => 'file', 'path' => '/etc/obdc.ini', 'perms' => 0644); //we were doing a recursive on this which I think is not needed. //Changed to just be the directory //^ Needs to be the whole shebang, doesnt work otherwise $this->modfiles['framework'][] = array('type' => 'rdir', 'path' => $AMPWEBROOT, 'perms' => 0755); //Anything in bin and agi-bin should be exec'd //Should be after everything except but before hooks //So that we dont get overwritten by ampwebroot $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $AMPBIN, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $ASTAGIDIR, 'perms' => 0755, 'always' => true); $this->modfiles['framework'][] = array('type' => 'execdir', 'path' => $ASTVARLIBDIR . "/bin", 'perms' => 0755, 'always' => true); //Merge static files and hook files, then act on them as a single unit $fwcCF = $this->fwcChownFiles(); if (!empty($this->modfiles) && !empty($fwcCF)) { foreach ($fwcCF as $key => $value) { $this->modfiles[$key] = $value; } //$this->modfiles = array_merge_recursive($this->modfiles,$fwcCF); } } //Let's move the custom array to the end so it happens last //FREEPBX-12515 //Store in a temporary variable. If Null we make it an empty array $holdarray = $this->modfiles['byconfig']; //Unset it from the array unset($this->modfiles['byconfig']); //Add it back to the array $this->modfiles['byconfig'] = $holdarray; $ampowner = $AMPASTERISKWEBUSER; /* Address concerns carried over from amportal in FREEPBX-8268. If the apache user is different * than the Asterisk user we provide permissions that allow both. */ $ampgroup = $AMPASTERISKWEBUSER != $AMPASTERISKUSER ? $AMPASTERISKGROUP : $AMPASTERISKWEBGROUP; $fcount = 0; if (!$this->quiet) { $output->write("\t" . _("Collecting Files...")); } $exclusive = $input->hasOption('file') ? $input->getOption('file') : null; $process = array(); foreach ($this->modfiles as $moduleName => $modfilelist) { if (!is_array($modfilelist)) { continue; } foreach ($modfilelist as $file) { switch ($file['type']) { case 'file': case 'dir': if (empty($exclusive) || $exclusive == $file['path']) { $file['files'] = array($file['path']); $fcount++; } else { continue 2; } break; case 'execdir': case 'rdir': $files = $this->recursiveDirList($file['path']); $children = false; if (empty($exclusive) || $exclusive == $file['path']) { $file['files'] = array($file['path']); $fcount++; $children = true; } foreach ($files as $f) { if (empty($exclusive) || $children || $exclusive == $f) { $file['files'][] = $f; $fcount++; } else { continue; } } if (empty($file['files'])) { continue 2; } break; } $process[$file['type']][] = $file; } } $verbose = $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE; if (!$this->quiet) { $output->writeln(_("Done")); if (!$verbose) { $progress = new ProgressBar($output, $fcount); $progress->setRedrawFrequency(100); $progress->start(); } } foreach ($process as $type => $modfilelist) { foreach ($modfilelist as $file) { if (!isset($file['path']) || !isset($file['perms']) || !file_exists($file['path'])) { if (!$this->quiet && !$verbose) { $progress->advance(); } continue; } //Handle custom ownership (optional) $owner = isset($file['owner']) ? $file['owner'] : $ampowner; $group = isset($file['group']) ? $file['group'] : $ampgroup; $owner = \ForceUTF8\Encoding::toLatin1($owner); $group = \ForceUTF8\Encoding::toLatin1($group); foreach ($file['files'] as $path) { if ($this->checkBlacklist($path)) { $this->infos[] = sprintf(_('%s skipped by configuration'), $path); continue; } switch ($file['type']) { case 'file': case 'dir': $this->setPermissions(array($path, $owner, $group, $file['perms'])); break; case 'rdir': if (is_dir($path)) { $this->setPermissions(array($path, $owner, $group, $file['perms'])); } else { $fileperms = $this->stripExecute($file['perms']); $this->setPermissions(array($path, $owner, $group, $fileperms)); } break; case 'execdir': $this->setPermissions(array($path, $owner, $group, $file['perms'])); break; } if (!$this->quiet && !$verbose) { $progress->advance(); } } } } if (!$this->quiet && !$verbose) { $progress->finish(); } if (!$this->quiet) { $output->writeln(""); $output->writeln("Finished setting permissions"); $errors = array_unique($this->errors); foreach ($errors as $error) { $output->writeln("<error>" . $error . "</error>"); } $infos = array_unique($this->infos); foreach ($infos as $error) { $output->writeln("<info>" . $error . "</info>"); } } }
out(_('Version from Framework was empty, cant continue')); return false; } //sbin is not set correctly starting in 2.9, this is a stop-gap till we fix the installer in 13 exec('export PATH=/usr/local/sbin:$PATH && which -a amportal', $output, $return_var); $file = null; foreach ($output as $f) { if (!is_link($f)) { $file = $f; break; } } if (!empty($file)) { $sbin = dirname($file); if (is_dir($sbin) && $amp_conf['AMPSBIN'] !== $sbin) { $freepbx_conf =& freepbx_conf::create(); out(sprintf(_("Setting sbin to the correct location of: %s"), $sbin)); $freepbx_conf->set_conf_values(array("AMPSBIN" => $sbin), true, true); } } exec($amp_conf['AMPBIN'] . '/retrieve_conf 2>&1', $ret); //need to invalidate module_xml at this point if (function_exists("sql")) { sql("DELETE FROM module_xml WHERE id = 'modules'"); } // Make sure our GPG keys are up to date try { \FreePBX::GPG()->refreshKeys(); } catch (\Exception $e) { out(sprintf(_("Error updating GPG Keys: %s"), $e->getMessage())); }