/** * translate a text * @param OPNsense\Core\Config $cnf config handle * @return Gettext */ public function getTranslator($cnf) { $lang = 'en_US'; foreach ($cnf->object()->system->children() as $key => $node) { if ($key == 'language') { $lang = $node->__toString(); break; } } $lang_encoding = $lang . '.UTF-8'; $ret = new Gettext(array('directory' => '/usr/local/share/locale', 'defaultDomain' => 'OPNsense', 'locale' => $lang_encoding)); /* this isn't being done by Phalcon */ putenv('LANG=' . $lang_encoding); return $ret; }
/** * Constructor */ public function __construct() { // Request handle to configuration $this->config = Core\Config::getInstance(); // keep a link to the shell object $this->shell = new Core\Shell(); }
/** * generate closure tag, block all traffic coming from captiveportal interfaces * rule number range 6001..6999 */ private function generateClosure() { $cpinterfaces = []; # find all cp interfaces foreach ($this->config->object()->captiveportal->children() as $cpzonename => $zone) { if (isset($zone->enable)) { // search interface $interface = $zone->interface->xpath("//" . $zone->interface); if (count($interface) > 0) { $interface = $interface[0]; if ($interface->if != null) { // check if interface exists before appending it. $cpinterfaces[$interface->if->__toString()] = 1; } } } } // generate accept rules for every interface not in captive portal $ruleid = 6001; $this->rules[] = "#======================================================================================"; $this->rules[] = "# accept traffic from all interfaces not used by captive portal (5001..5999) "; $this->rules[] = "#======================================================================================"; foreach ($this->config->object()->interfaces->children() as $interface => $content) { if (!isset($cpinterfaces[$content->if->__toString()])) { $this->rules[] = "add " . $ruleid++ . " allow all from any to any via " . $content->if; } } $this->rules[] = "# let the responses from the captive portal web server back out"; $this->rules[] = "add " . $ruleid++ . " pass tcp from any to any out"; // block every thing else (not mentioned before) $this->rules[] = "# block everything else"; $this->rules[] = "add " . $ruleid . " skipto 65534 all from any to any"; $this->rules[] = "add 65534 deny all from any to any"; }
/** * generate validation data (list of interfaces and well know ports) */ public function eventPostLoading() { if (!array_key_exists($this->internalCacheKey, self::$internalOptionList)) { self::$internalOptionList[$this->internalCacheKey] = array(); $allInterfaces = array(); $configObj = Config::getInstance()->object(); // Iterate over all interfaces configuration and collect data foreach ($configObj->interfaces->children() as $key => $value) { $allInterfaces[$key] = $value; } foreach ($allInterfaces as $key => $value) { // use filters to determine relevance $isMatched = true; foreach ($this->internalFilters as $filterKey => $filterData) { if (isset($value->{$filterKey})) { $fieldData = $value->{$filterKey}; } else { // not found, might be a boolean. $fieldData = "0"; } if (!preg_match($filterData, $fieldData)) { $isMatched = false; } } if ($isMatched) { if ($value->descr == '') { self::$internalOptionList[$this->internalCacheKey][$key] = $key; } else { self::$internalOptionList[$this->internalCacheKey][$key] = $value->descr->__toString(); } } } } }
/** * authenticate user against local database (in config.xml) * @param string $username username to authenticate * @param string $password user password * @return bool authentication status */ public function authenticate($username, $password) { // search local user in database $configObj = Config::getInstance()->object(); $userObject = null; foreach ($configObj->system->children() as $key => $value) { if ($key == 'user' && !empty($value->name) && (string) $value->name == $username) { // user found, stop search $userObject = $value; break; } } if ($userObject != null) { if (isset($userObject->disabled)) { // disabled user return false; } if (!empty($userObject->expires) && strtotime("-1 day") > strtotime(date("m/d/Y", strtotime((string) $userObject->expires)))) { // expired user return false; } $passwd = crypt($password, (string) $userObject->password); if ($passwd == (string) $userObject->password) { // password ok, return successfully authentication return true; } } return false; }
/** * generate validation data (list of certificates) */ public function eventPostLoading() { if (count($this->internalOptionList) == 0) { $configObj = Config::getInstance()->object(); foreach ($configObj->{$this->certificateType} as $cert) { self::$internalOptionList[(string) $cert->refid] = (string) $cert->descr; } } }
private function getInterfaceNames() { // collect interface names $intfmap = array(); $config = Config::getInstance()->object(); if ($config->interfaces != null) { foreach ($config->interfaces->children() as $key => $node) { $intfmap[(string) $node->if] = !empty((string) $node->descr) ? (string) $node->descr : $key; } } return $intfmap; }
/** * request list of configured servers, the factory needs to be aware of it's options and settings to * be able to instantiate useful connectors. * @return array list of configured servers */ public function listServers() { $servers = array(); $servers['Local Database'] = array("name" => "Local Database", "type" => "local"); $configObj = Config::getInstance()->object(); foreach ($configObj->system->children() as $key => $value) { if ($key == 'authserver' && !empty($value->type) && !empty($value->name)) { $authServerSettings = array(); foreach ($value as $itemKey => $itemValue) { $authServerSettings[$itemKey] = (string) $itemValue; } $servers[$authServerSettings['name']] = $authServerSettings; } } return $servers; }
/** * update HelloWorld settings * @return array status */ public function setAction() { $result = array("result" => "failed"); if ($this->request->isPost()) { // load model and update with provided data $mdlHelloWorld = new HelloWorld(); $mdlHelloWorld->setNodes($this->request->getPost("helloworld")); // perform validation $valMsgs = $mdlHelloWorld->performValidation(); foreach ($valMsgs as $field => $msg) { if (!array_key_exists("validations", $result)) { $result["validations"] = array(); } $result["validations"]["helloworld." . $msg->getField()] = $msg->getMessage(); } // serialize model to config and save if ($valMsgs->count() == 0) { $mdlHelloWorld->serializeToConfig(); Config::getInstance()->save(); $result["result"] = "saved"; } } return $result; }
/** * shared functionality for all components * @param $dispatcher * @return bool * @throws \Exception */ public function beforeExecuteRoute($dispatcher) { // only handle input validation on first request. if (!$dispatcher->wasForwarded()) { // Authentication // - use authentication of legacy OPNsense. if (!$this->doAuth()) { return false; } // check for valid csrf on post requests if ($this->request->isPost() && !$this->security->checkToken()) { // post without csrf, exit. return false; } // REST type calls should be implemented by inheriting ApiControllerBase. // because we don't check for csrf on these methods, we want to make sure these aren't used. if ($this->request->isHead() || $this->request->isPut() || $this->request->isDelete() || $this->request->isPatch() || $this->request->isOptions()) { throw new \Exception('request type not supported'); } } // include csrf for volt view rendering. $this->view->setVars(['csrf_tokenKey' => $this->security->getTokenKey(), 'csrf_token' => $this->security->getToken()]); // set translator $this->view->setVar('lang', $this->getTranslator()); // link menu system to view, append /ui in uri because of rewrite $menu = new Menu\MenuSystem(); // add interfaces to "Interfaces" menu tab... kind of a hack, may need some improvement. $cnf = Config::getInstance(); $ifarr = array(); foreach ($cnf->object()->interfaces->children() as $key => $node) { $ifarr[$key] = $node; } ksort($ifarr); $ordid = 0; foreach ($ifarr as $key => $node) { $menu->appendItem('Interfaces', $key, array('url' => '/interfaces.php?if=' . $key, 'order' => $ordid++, 'visiblename' => $node->descr ? $node->descr : strtoupper($key))); } unset($ifarr); $this->view->menuSystem = $menu->getItems("/ui" . $this->router->getRewriteUri()); // set theme in ui_theme template var, let template handle its defaults (if there is no theme). if ($cnf->object()->theme != null && !empty($cnf->object()->theme) && is_dir('/usr/local/opnsense/www/themes/' . (string) $cnf->object()->theme)) { $this->view->ui_theme = $cnf->object()->theme; } // append ACL object to view $this->view->acl = new \OPNsense\Core\ACL(); }
/** * create new cron item for remote acl or return already available one * @return array status action */ public function fetchRBCronAction() { $result = array("result" => "failed"); if ($this->request->isPost()) { $mdlProxy = new Proxy(); if ((string) $mdlProxy->forward->acl->remoteACLs->UpdateCron == "") { $mdlCron = new Cron(); // update cron relation (if this doesn't break consistency) $uuid = $mdlCron->newDailyJob("Proxy", "proxy fetchacls", "fetch proxy acls", "1"); $mdlProxy->forward->acl->remoteACLs->UpdateCron = $uuid; if ($mdlCron->performValidation()->count() == 0) { $mdlCron->serializeToConfig(); // save data to config, do not validate because the current in memory model doesn't know about the // cron item just created. $mdlProxy->serializeToConfig($validateFullModel = false, $disable_validation = true); Config::getInstance()->save(); $result['result'] = "new"; $result['uuid'] = $uuid; } else { $result['result'] = "unable to add cron"; } } else { $result['result'] = "existing"; $result['uuid'] = (string) $mdlProxy->forward->acl->remoteACLs->UpdateCron; } } return $result; }
/** * toggle zone by uuid (enable/disable) * @param $uuid item unique id * @param $enabled desired state enabled(1)/disabled(1), leave empty for toggle * @return array status */ public function toggleZoneAction($uuid, $enabled = null) { $result = array("result" => "failed"); if ($this->request->isPost()) { $mdlCP = new CaptivePortal(); if ($uuid != null) { $node = $mdlCP->getNodeByReference('zones.zone.' . $uuid); if ($node != null) { if ($enabled == "0" || $enabled == "1") { $node->enabled = (string) $enabled; } elseif ((string) $node->enabled == "1") { $node->enabled = "0"; } else { $node->enabled = "1"; } $result['result'] = $node->enabled; // if item has toggled, serialize to config and save $mdlCP->serializeToConfig(); Config::getInstance()->save(); } } } return $result; }
/** * authenticate user against local database (in config.xml) * @param string $username username to authenticate * @param string $password user password * @return bool authentication status */ public function authenticate($username, $password) { // reset auth properties $this->lastAuthProperties = array(); // search local user in database $configObj = Config::getInstance()->object(); $userObject = null; $apiKey = null; $apiSecret = null; foreach ($configObj->system->children() as $key => $value) { if ($key == 'user') { if (!empty($value->apikeys)) { foreach ($value->apikeys->children() as $apikey) { if (!empty($apikey->key) && (string) $apikey->key == $username) { // api key found, stop search $userObject = $value; $apiSecret = (string) $apikey->secret; break; } } } } } if ($userObject != null) { if (isset($userObject->disabled)) { // disabled user return false; } if (!empty($userObject->expires) && strtotime("-1 day") > strtotime(date("m/d/Y", strtotime((string) $userObject->expires)))) { // expired user return false; } $passwd = crypt($password, $apiSecret); if ($passwd == $apiSecret) { // password ok, return successfully authentication $this->lastAuthProperties['username'] = (string) $userObject->name; return true; } } return false; }
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ // use legacy code to generate certs and ca's // eventually we need to replace this. require_once "config.inc"; require_once "certs.inc"; require_once "legacy_bindings.inc"; use OPNsense\Core\Config; global $config; // traverse captive portal zones $configObj = Config::getInstance()->object(); if (isset($configObj->OPNsense->captiveportal->zones)) { foreach ($configObj->OPNsense->captiveportal->zones->children() as $zone) { $cert_refid = (string) $zone->certificate; $zone_id = (string) $zone->zoneid; // if the zone has a certificate attached, search for its contents if ($cert_refid != "") { foreach ($configObj->cert as $cert) { if ($cert_refid == (string) $cert->refid) { // generate cert pem file $pem_content = str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string) $cert->crt))); $pem_content .= str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string) $cert->prv))); $output_pem_filename = "/var/etc/cert-cp-zone" . $zone_id . ".pem"; file_put_contents($output_pem_filename, $pem_content); chmod($output_pem_filename, 0600); echo "certificate generated " . $output_pem_filename . "\n";
/** * request user context sensitive menu (items) * @param string $selected_uri selected uri * @return array menu items */ private function getMenu($selected_uri) { // construct menu and acl and merge collected info $menu = new Menu\MenuSystem(); $acl = new ACL(); // get username into context if ($this->session->has("Username")) { $this->username = $this->session->get("Username"); } // add interfaces to "Interfaces" menu tab... kind of a hack, may need some improvement. $cnf = Config::getInstance(); $ifarr = array(); foreach ($cnf->object()->interfaces->children() as $key => $node) { $ifarr[$key] = $node->descr ? $node->descr->__toString() : strtoupper($key); } natcasesort($ifarr); $ordid = 0; foreach ($ifarr as $key => $descr) { $menu->appendItem('Interfaces', $key, array('url' => '/interfaces.php?if=' . $key, 'visiblename' => '[' . $descr . ']', 'cssclass' => 'fa fa-sitemap', 'order' => $ordid++)); } unset($ifarr); // fetch menu items and apply acl $menu_items = $menu->getItems($selected_uri); $this->applyACL($menu_items, $acl); return $menu_items; }
/** * toggle job by uuid (enable/disable) * @param $uuid item unique id * @return array status */ public function toggleJobAction($uuid) { $result = array("result" => "failed"); if ($this->request->isPost()) { $mdlCron = new Cron(); if ($uuid != null) { $node = $mdlCron->getNodeByReference('jobs.job.' . $uuid); if ($node != null) { if ($node->enabled->__toString() == "1") { $result['result'] = "Disabled"; $node->enabled = "0"; } else { $result['result'] = "Enabled"; $node->enabled = "1"; } // if item has toggled, serialize to config and save $mdlCron->serializeToConfig(); Config::getInstance()->save(); } } } return $result; }
/** * update IDS settings * @return array status */ public function setAction() { $result = array("result" => "failed"); if ($this->request->isPost()) { // load model and update with provided data $mdlIDS = $this->getModel(); $mdlIDS->setNodes($this->request->getPost("ids")); $validations = $mdlIDS->validate(null, "ids."); if (count($validations)) { $result['validations'] = $validations; } else { $mdlIDS->serializeToConfig(); Config::getInstance()->save(); $result["result"] = "saved"; } } return $result; }
/** * serialize model singleton to config object */ private function internalSerializeToConfig() { // setup config handle to singleton config singleton $internalConfigHandle = Config::getInstance(); $config_xml = $internalConfigHandle->object(); // serialize this model's data to xml $data_xml = $this->toXML(); // Locate source node (in theory this must return a valid result, delivered by toXML). // Because toXML delivers the actual xml including the full path, we need to find the root of our data. $source_node = $data_xml->xpath($this->internal_mountpoint); // find parent of mountpoint (create if it doesn't exists) $target_node = $config_xml; $str_parts = explode("/", str_replace("//", "/", $this->internal_mountpoint)); for ($i = 0; $i < count($str_parts) - 1; $i++) { if ($str_parts[$i] != "") { if (count($target_node->xpath($str_parts[$i])) == 0) { $target_node = $target_node->addChild($str_parts[$i]); } else { $target_node = $target_node->xpath($str_parts[$i])[0]; } } } // copy model data into config $toDom = dom_import_simplexml($target_node); $fromDom = dom_import_simplexml($source_node[0]); // remove old model data and write new foreach ($toDom->getElementsByTagName($fromDom->nodeName) as $oldNode) { $toDom->removeChild($oldNode); } $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true)); }
/** * delete template by uuid * @param $uuid item unique id * @return array status */ public function delTemplateAction($uuid) { $result = array("result" => "failed"); if ($this->request->isPost()) { $mdlCP = new CaptivePortal(); if ($uuid != null) { if ($mdlCP->templates->template->del($uuid)) { // if item is removed, serialize to config and save $mdlCP->serializeToConfig(); Config::getInstance()->save(); $result['result'] = 'deleted'; } else { $result['result'] = 'not found'; } } } return $result; }
/** * delete rule by uuid * @param $uuid item unique id * @return array status */ public function delRuleAction($uuid) { $result = array("result" => "failed"); if ($this->request->isPost()) { $mdlShaper = new TrafficShaper(); if ($uuid != null) { if ($mdlShaper->rules->rule->del($uuid)) { // if item is removed, serialize to config and save $mdlShaper->serializeToConfig($disable_validation = true); Config::getInstance()->save(); $result['result'] = 'deleted'; } else { $result['result'] = 'not found'; } } } return $result; }
/** * reconfigure IDS */ public function reconfigureAction() { $status = "failed"; if ($this->request->isPost()) { // close session for long running action $this->sessionClose(); $mdlIDS = new IDS(); $runStatus = $this->statusAction(); // we should always have a cron item configured for IDS, let's create one upon first reconfigure. if ((string) $mdlIDS->general->UpdateCron == "") { $mdlCron = new Cron(); // update cron relation (if this doesn't break consistency) $mdlIDS->general->UpdateCron = $mdlCron->newDailyJob("IDS", "ids update", "ids rule updates", "0"); if ($mdlCron->performValidation()->count() == 0) { $mdlCron->serializeToConfig(); // save data to config, do not validate because the current in memory model doesn't know about the // cron item just created. $mdlIDS->serializeToConfig($validateFullModel = false, $disable_validation = true); Config::getInstance()->save(); } } if ($runStatus['status'] == "running" && (string) $mdlIDS->general->enabled == 0) { $this->stopAction(); } $backend = new Backend(); $bckresult = trim($backend->configdRun("template reload OPNsense.IDS")); if ($bckresult == "OK") { if ((string) $mdlIDS->general->enabled == 1) { $bckresult = trim($backend->configdRun("ids install rules")); if ($bckresult == "OK") { if ($runStatus['status'] == 'running') { $status = $this->restartAction()['response']; } else { $status = $this->startAction()['response']; } } else { $status = "error installing ids rules (" . $bckresult . ")"; } } else { $status = "OK"; } } else { $status = "error generating ids template (" . $bckresult . ")"; } } return array("status" => $status); }
/** * Example save action * @throws \Phalcon\Validation\Exception */ public function saveAction() { // save action should be a post if ($this->request->isPost() == true) { // create model(s) $mdlSample = new Sample(); // update model with request data $this->updateModelWithPost($mdlSample); if ($this->request->getPost("form_action") == "add") { // implement addRow, append new model row and serialize to config if form is valid $mdlSample->childnodes->section->add(); if ($this->performFormValidation($mdlSample) == false) { return false; } $mdlSample->serializeToConfig(); } elseif ($this->request->getPost("form_action") == "save") { // implement save, possible removing if ($this->request->hasPost("delete")) { // delete selected Rows, cannot combine with add because of the index numbering foreach ($this->request->getPost("delete") as $node_ref => $option_key) { $refparts = explode(".", $node_ref); $delete_key = array_pop($refparts); $parentNode = $mdlSample->getNodeByReference(implode(".", $refparts)); if ($parentNode != null) { $parentNode->del($delete_key); } } } // form validation if ($this->performFormValidation($mdlSample) == false) { return false; } // save data to config $mdlSample->serializeToConfig(); $cnf = Config::getInstance(); $cnf->save(); } } // redirect to index $this->dispatcher->forward(array("action" => "index")); return true; }