<?php
/**
 * Copyright Zikula Foundation 2009 - Zikula Application Framework
 *
 * This work is contributed to the Zikula Foundation under one or more
 * Contributor Agreements and licensed to You under the following license:
 *
 * @license GNU/LGPLv3 (or at your option, any later version).
 * @package Zikula
 *
 * Please see the NOTICE file distributed with this source code for further
 * information regarding copyright and licensing.
 */

/**
 * SecurityCenter_Controller_Admin class.
 */
class SecurityCenter_Controller_Admin extends Zikula_AbstractController
{
    /**
     * Post initialise.
     *
     * @return void
     */
    protected function postInitialize()
    {
        // In this controller we do not want caching.
        $this->view->setCaching(Zikula_View::CACHE_DISABLED);
    }

    /**
     * The main administration function.
     *
     * This function is the default function, and is called whenever the
     * module is initiated without defining arguments.  As such it can
     * be used for a number of things, but most commonly it either just
     * shows the module menu and returns or calls whatever the module
     * designer feels should be the default function (often this is the
     * view() function).
     *
     * @return string HTML string.
     */
    public function main()
    {
        // Security check will be done in modifyconfig()
        $this->redirect(ModUtil::url('SecurityCenter', 'admin', 'modifyconfig'));
    }

    /**
     * This is a standard function to modify the configuration parameters of the module.
     *
     * @return string HTML string.
     */
    public function modifyconfig()
    {
        // Security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        $this->view->assign('itemsperpage', $this->getVar('itemsperpage'));

        $this->view->assign('idshtmlfields', implode(PHP_EOL, System::getVar('idshtmlfields')));
        $this->view->assign('idsjsonfields', implode(PHP_EOL, System::getVar('idsjsonfields')));
        $this->view->assign('idsexceptions', implode(PHP_EOL, System::getVar('idsexceptions')));

        // Return the output that has been generated by this function
        return $this->view->fetch('securitycenter_admin_modifyconfig.tpl');
    }

    /**
     * This is a standard function to update the configuration parameters of the
     * module given the information passed back by the modification form
     * @see securitycenter_admin_modifyconfig()
     *
     * @param int enableanticracker
     * @param int itemsperpage
     * @param int emailhackattempt
     * @param int loghackattempttodb
     * @param int onlysendsummarybyemail
     * @param int updatecheck
     * @param int updatefrequency
     * @param int keyexpiry
     * @param int sessionauthkeyua
     * @param string secure_domain
     * @param int signcookies
     * @param string signingkey
     * @param string seclevel
     * @param int secmeddays
     * @param int secinactivemins
     * @param int sessionstoretofile
     * @param string sessionsavepath
     * @param int gc_probability
     * @param int anonymoussessions
     * @param int sessionrandregenerate
     * @param int sessionregenerate
     * @param int sessionregeneratefreq
     * @param int sessionipcheck
     * @param string sessionname
     * @param int filtergetvars
     * @param int filterpostvars
     * @param int filtercookievars
     * @param int outputfilter
     * @param string summarycontent
     * @param string fullcontent
     *
     * @return bool true if successful, false otherwise.
     */
    public function updateconfig()
    {
        $this->checkCsrfToken();

        // Security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        $validates = true;

        // Update module variables.
        $updatecheck = (int)FormUtil::getPassedValue('updatecheck', 0, 'POST');
        System::setVar('updatecheck', $updatecheck);

        // if update checks are disabled, reset values to force new update check if re-enabled
        if ($updatecheck == 0) {
            System::setVar('updateversion', Zikula_Core::VERSION_NUM);
            System::setVar('updatelastchecked', 0);
        }

        $updatefrequency = (int)FormUtil::getPassedValue('updatefrequency', 30, 'POST');
        System::setVar('updatefrequency', $updatefrequency);

        $keyexpiry = (int)FormUtil::getPassedValue('keyexpiry', 0, 'POST');
        if ($keyexpiry < 0 || $keyexpiry > 3600) {
            $keyexpiry = 0;
        }
        System::setVar('keyexpiry', $keyexpiry);

        $sessionauthkeyua = (int)FormUtil::getPassedValue('sessionauthkeyua', 0, 'POST');
        System::setVar('sessionauthkeyua', $sessionauthkeyua);

        $secure_domain = FormUtil::getPassedValue('secure_domain', '', 'POST');
        System::setVar('secure_domain', $secure_domain);

        $signcookies = (int)FormUtil::getPassedValue('signcookies', 1, 'POST');
        System::setVar('signcookies', $signcookies);

        $signingkey = FormUtil::getPassedValue('signingkey', '', 'POST');
        System::setVar('signingkey', $signingkey);

        $seclevel = FormUtil::getPassedValue('seclevel', 'High', 'POST');
        System::setVar('seclevel', $seclevel);

        $secmeddays = (int)FormUtil::getPassedValue('secmeddays', 7, 'POST');
        if ($secmeddays < 1 || $secmeddays > 365) {
            $secmeddays = 7;
        }
        System::setVar('secmeddays', $secmeddays);

        $secinactivemins = (int)FormUtil::getPassedValue('secinactivemins', 20, 'POST');
        if ($secinactivemins < 1 || $secinactivemins > 1440) {
            $secinactivemins = 7;
        }
        System::setVar('secinactivemins', $secinactivemins);

        $sessionstoretofile = (int)FormUtil::getPassedValue('sessionstoretofile', 0, 'POST');
        $sessionsavepath = FormUtil::getPassedValue('sessionsavepath', '', 'POST');

        // check session path config is writable (if method is being changed to session file storage)
        $cause_logout = false;
        $storeTypeCanBeWritten = true;
        if ($sessionstoretofile == 1 && !empty($sessionsavepath)) {
            // fix path on windows systems
            $sessionsavepath = str_replace('\\', '/', $sessionsavepath);
            // sanitize the path
            $sessionsavepath = trim(stripslashes($sessionsavepath));

            // check if sessionsavepath is a dir and if it is writable
            // if yes, we need to logout
            $cause_logout = (is_dir($sessionsavepath)) ? is_writable($sessionsavepath) : false;

            if ($cause_logout == false) {
                // an error occured - we do not change the way of storing session data
                LogUtil::registerStatus($this->__('Error! Session path not writeable!'));
                $storeTypeCanBeWritten = false;
            }
        }
        if ($storeTypeCanBeWritten == true) {
            System::setVar('sessionstoretofile', $sessionstoretofile);
            System::setVar('sessionsavepath', $sessionsavepath);
        }

        if ((bool)$sessionstoretofile != (bool)System::getVar('sessionstoretofile')) {
            // logout if going from one storage to another one
            $cause_logout = true;
        }

        $gc_probability = (int)FormUtil::getPassedValue('gc_probability', 100, 'POST');
        if ($gc_probability < 1 || $gc_probability > 10000) {
            $gc_probability = 7;
        }
        System::setVar('gc_probability', $gc_probability);

        $anonymoussessions = (int)FormUtil::getPassedValue('anonymoussessions', 1, 'POST');
        System::setVar('anonymoussessions', $anonymoussessions);

        $sessionrandregenerate = (int)FormUtil::getPassedValue('sessionrandregenerate', 1, 'POST');
        System::setVar('sessionrandregenerate', $sessionrandregenerate);

        $sessionregenerate = (int)FormUtil::getPassedValue('sessionregenerate', 1, 'POST');
        System::setVar('sessionregenerate', $sessionregenerate);

        $sessionregeneratefreq = (int)FormUtil::getPassedValue('sessionregeneratefreq', 10, 'POST');
        if ($sessionregeneratefreq < 1 || $sessionregeneratefreq > 100) {
            $sessionregeneratefreq = 10;
        }
        System::setVar('sessionregeneratefreq', $sessionregeneratefreq);

        $sessionipcheck = (int)FormUtil::getPassedValue('sessionipcheck', 0, 'POST');
        System::setVar('sessionipcheck', $sessionipcheck);

        $sessionname = FormUtil::getPassedValue('sessionname', 'ZSID', 'POST');
        if (strlen($sessionname) < 3) {
            $sessionname = 'ZSID';
        }

        $sessioncsrftokenonetime = (int)FormUtil::getPassedValue('sessioncsrftokenonetime', 0, 'POST');
        System::setVar('sessioncsrftokenonetime', $sessioncsrftokenonetime);

        // cause logout if we changed session name
        if ($sessionname != System::getVar('sessionname')) {
            $cause_logout = true;
        }

        System::setVar('sessionname', $sessionname);
        System::setVar('sessionstoretofile', $sessionstoretofile);

        $outputfilter = FormUtil::getPassedValue('outputfilter', 0, 'POST');
        System::setVar('outputfilter', $outputfilter);

        $useids = (bool)FormUtil::getPassedValue('useids', 0, 'POST');
        System::setVar('useids', $useids);

        // create tmp directory for PHPIDS
        if ($useids == 1) {
            $idsTmpDir = CacheUtil::getLocalDir() . '/idsTmp';
            if (!file_exists($idsTmpDir)) {
                CacheUtil::clearLocalDir('idsTmp');
            }
        }

        $idssoftblock = (bool)FormUtil::getPassedValue('idssoftblock', 1, 'POST');
        System::setVar('idssoftblock', $idssoftblock);

        $idsmail = (bool)FormUtil::getPassedValue('idsmail', 1, 'POST');
        System::setVar('idsmail', $idsmail);

        $idsfilter = FormUtil::getPassedValue('idsfilter', 'xml', 'POST');
        System::setVar('idsfilter', $idsfilter);

        $idsrulepath = FormUtil::getPassedValue('idsrulepath', 'config/zikula_default.xml', 'POST');
        $idsrulepath = DataUtil::formatForOS($idsrulepath);
        if (is_readable($idsrulepath)) {
            System::setVar('idsrulepath', $idsrulepath);
        } else {
            LogUtil::registerError($this->__f('Error! PHPIDS rule file %s does not exist or is not readable.', $idsrulepath));
            $validates = false;
        }

        $idsimpactthresholdone = (int)FormUtil::getPassedValue('idsimpactthresholdone', 1, 'POST');
        System::setVar('idsimpactthresholdone', $idsimpactthresholdone);

        $idsimpactthresholdtwo = (int)FormUtil::getPassedValue('idsimpactthresholdtwo', 10, 'POST');
        System::setVar('idsimpactthresholdtwo', $idsimpactthresholdtwo);

        $idsimpactthresholdthree = (int)FormUtil::getPassedValue('idsimpactthresholdthree', 25, 'POST');
        System::setVar('idsimpactthresholdthree', $idsimpactthresholdthree);

        $idsimpactthresholdfour = (int)FormUtil::getPassedValue('idsimpactthresholdfour', 75, 'POST');
        System::setVar('idsimpactthresholdfour', $idsimpactthresholdfour);

        $idsimpactmode = (int)FormUtil::getPassedValue('idsimpactmode', 1, 'POST');
        System::setVar('idsimpactmode', $idsimpactmode);

        $idshtmlfields = FormUtil::getPassedValue('idshtmlfields', '', 'POST');
        $idshtmlfields = explode(PHP_EOL, $idshtmlfields);
        $idshtmlarray = array();
        foreach ($idshtmlfields as $idshtmlfield) {
            $idshtmlfield = trim($idshtmlfield);
            if (!empty($idshtmlfield)) {
                $idshtmlarray[] = $idshtmlfield;
            }
        }
        System::setVar('idshtmlfields', $idshtmlarray);

        $idsjsonfields = FormUtil::getPassedValue('idsjsonfields', '', 'POST');
        $idsjsonfields = explode(PHP_EOL, $idsjsonfields);
        $idsjsonarray = array();
        foreach ($idsjsonfields as $idsjsonfield) {
            $idsjsonfield = trim($idsjsonfield);
            if (!empty($idsjsonfield)) {
                $idsjsonarray[] = $idsjsonfield;
            }
        }
        System::setVar('idsjsonfields', $idsjsonarray);

        $idsexceptions = FormUtil::getPassedValue('idsexceptions', '', 'POST');
        $idsexceptions = explode(PHP_EOL, $idsexceptions);
        $idsexceptarray = array();
        foreach ($idsexceptions as $idsexception) {
            $idsexception = trim($idsexception);
            if (!empty($idsexception)) {
                $idsexceptarray[] = $idsexception;
            }
        }
        System::setVar('idsexceptions', $idsexceptarray);

        // clear all cache and compile directories
        ModUtil::apiFunc('Settings', 'admin', 'clearallcompiledcaches');

        // the module configuration has been updated successfuly
        if ($validates) {
            $this->registerStatus($this->__('Done! Saved module configuration.'));
        }

        // we need to auto logout the user if they changed from DB to FILE
        if ($cause_logout == true) {
            UserUtil::logout();
            $this->registerStatus($this->__('Session handling variables have changed. You must log in again.'));
            $returnPage = urlencode(ModUtil::url('SecurityCenter', 'admin', 'modifyconfig'));
            $this->redirect(ModUtil::url('Users', 'user', 'login', array('returnpage' => $returnPage)));
        }

        // This function generated no output, and so now it is complete we redirect
        // the user to an appropriate page for them to carry on their work
        return $this->redirect(ModUtil::url('SecurityCenter', 'admin', 'modifyconfig'));
    }

    /**
     * HTMLPurifier configuration.
     *
     * @return void
     */
    public function purifierconfig()
    {
        // Security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        $reset = (bool)(FormUtil::getPassedValue('reset', null, 'GET') == 'default');

        $this->view->assign('itemsperpage', $this->getVar('itemsperpage'));

        if ($reset) {
            $purifierconfig = SecurityCenter_Util::getPurifierConfig(true);
            LogUtil::registerStatus($this->__('Default values for HTML Purifier were successfully loaded. Please store them using the "Save" button at the bottom of this page'));
        } else {
            $purifierconfig = SecurityCenter_Util::getPurifierConfig(false);
        }

        $purifier = new HTMLPurifier($purifierconfig);

        $config = $purifier->config;

        if (is_array($config) && isset($config[0])) {
            $config = $config[1];
        }

        $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm(true, $config->def);

        // list of excluded directives, format is $namespace_$directive
        $excluded = array('Cache_SerializerPath');

        $purifierAllowed = array();
        foreach ($allowed as $allowedDirective) {
            list($namespace, $directive) = $allowedDirective;

            if (in_array($namespace . '_' . $directive, $excluded)) {
                continue;
            }

            if ($namespace == 'Filter') {
                if (
                // Do not allow Filter.Custom for now. Causing errors.
                // TODO research why Filter.Custom is causing exceptions and correct.
                        ($directive == 'Custom')
                        // Do not allow Filter.ExtractStyleBlock* for now. Causing errors.
                        // TODO Filter.ExtractStyleBlock* requires CSSTidy
                        || (stripos($directive, 'ExtractStyleBlock') !== false)
                ) {
                    continue;
                }
            }

            $directiveRec = array();
            $directiveRec['key'] = $namespace . '.' . $directive;
            $def = $config->def->info[$directiveRec['key']];
            $directiveRec['value'] = $config->get($directiveRec['key']);
            if (is_int($def)) {
                $directiveRec['allowNull'] = ($def < 0);
                $directiveRec['type'] = abs($def);
            } else {
                $directiveRec['allowNull'] = (isset($def->allow_null) && $def->allow_null);
                $directiveRec['type'] = (isset($def->type) ? $def->type : 0);
                if (isset($def->allowed)) {
                    $directiveRec['allowedValues'] = array();
                    foreach ($def->allowed as $val => $b) {
                        $directiveRec['allowedValues'][] = $val;
                    }
                }
            }
            if (is_array($directiveRec['value'])) {
                switch ($directiveRec['type']) {
                    case HTMLPurifier_VarParser::LOOKUP:
                        $value = array();
                        foreach ($directiveRec['value'] as $val => $b) {
                            $value[] = $val;
                        }
                        $directiveRec['value'] = implode(PHP_EOL, $value);
                        break;
                    case HTMLPurifier_VarParser::ALIST:
                        $directiveRec['value'] = implode(PHP_EOL, $value);
                        break;
                    case HTMLPurifier_VarParser::HASH:
                        $value = '';
                        foreach ($directiveRec['value'] as $i => $v) {
                            $value .= "{$i}:{$v}" . PHP_EOL;
                        }
                        $directiveRec['value'] = $value;
                        break;
                    default:
                        $directiveRec['value'] = '';
                }
            }
            // Editing for only these types is supported
            $directiveRec['supported'] = (($directiveRec['type'] == HTMLPurifier_VarParser::STRING)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::ISTRING)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::TEXT)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::ITEXT)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::INT)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::FLOAT)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::BOOL)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::LOOKUP)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::ALIST)
                    || ($directiveRec['type'] == HTMLPurifier_VarParser::HASH));

            $purifierAllowed[$namespace][$directive] = $directiveRec;
        }

        $this->view->assign('purifier', $purifier)
                ->assign('purifierTypes', HTMLPurifier_VarParser::$types)
                ->assign('purifierAllowed', $purifierAllowed);

        // Return the output that has been generated by this function
        return $this->view->fetch('securitycenter_admin_purifierconfig.tpl');
    }

    /**
     * Update HTMLPurifier configuration.
     *
     * @return void
     */
    public function updatepurifierconfig()
    {
        $this->checkCsrfToken();

        // Security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Load HTMLPurifier Classes
        $purifier = SecurityCenter_Util::getpurifier();

        // Update module variables.
        $config = FormUtil::getPassedValue('purifierConfig', null, 'POST');
        $config = HTMLPurifier_Config::prepareArrayFromForm($config, false, true, true, $purifier->config->def);
//echo "\r\n\r\n<pre>" . print_r($config, true) . "</pre>\r\n\r\n";

        $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm(true, $purifier->config->def);
        foreach ($allowed as $allowedDirective) {
            list($namespace, $directive) = $allowedDirective;

            $directiveKey = $namespace . '.' . $directive;
            $def = $purifier->config->def->info[$directiveKey];

            if (isset($config[$namespace])
                    && array_key_exists($directive, $config[$namespace])
                    && is_null($config[$namespace][$directive])) {
                unset($config[$namespace][$directive]);

                if (count($config[$namespace]) <= 0) {
                    unset($config[$namespace]);
                }
            }

            if (isset($config[$namespace]) && isset($config[$namespace][$directive])) {
                if (is_int($def)) {
                    $directiveType = abs($def);
                } else {
                    $directiveType = (isset($def->type) ? $def->type : 0);
                }

                switch ($directiveType) {
                    case HTMLPurifier_VarParser::LOOKUP:
                        $value = explode(PHP_EOL, $config[$namespace][$directive]);
                        $config[$namespace][$directive] = array();
                        foreach ($value as $val) {
                            $val = trim($val);
                            if (!empty($val)) {
                                $config[$namespace][$directive][$val] = true;
                            }
                        }
                        if (empty($config[$namespace][$directive])) {
                            unset($config[$namespace][$directive]);
                        }
                        break;
                    case HTMLPurifier_VarParser::ALIST:
                        $value = explode(PHP_EOL, $config[$namespace][$directive]);
                        $config[$namespace][$directive] = array();
                        foreach ($value as $val) {
                            $val = trim($val);
                            if (!empty($val)) {
                                $config[$namespace][$directive][] = $val;
                            }
                        }
                        if (empty($config[$namespace][$directive])) {
                            unset($config[$namespace][$directive]);
                        }
                        break;
                    case HTMLPurifier_VarParser::HASH:
                        $value = explode(PHP_EOL, $config[$namespace][$directive]);
                        $config[$namespace][$directive] = array();
                        foreach ($value as $val) {
                            list($i, $v) = explode(':', $val);
                            $i = trim($i);
                            $v = trim($v);
                            if (!empty($i) && !empty($v)) {
                                $config[$namespace][$directive][$i] = $v;
                            }
                        }
                        if (empty($config[$namespace][$directive])) {
                            unset($config[$namespace][$directive]);
                        }
                        break;
                }
            }

            if (isset($config[$namespace])
                    && array_key_exists($directive, $config[$namespace])
                    && is_null($config[$namespace][$directive])) {
                unset($config[$namespace][$directive]);

                if (count($config[$namespace]) <= 0) {
                    unset($config[$namespace]);
                }
            }
        }

        //echo "\r\n\r\n<pre>" . print_r($config, true) . "</pre>\r\n\r\n"; exit;
        $this->setVar('htmlpurifierConfig', serialize($config));

        $purifier = SecurityCenter_Util::getpurifier(true);

        // clear all cache and compile directories
        ModUtil::apiFunc('Settings', 'admin', 'clearallcompiledcaches');

        // the module configuration has been updated successfuly
        LogUtil::registerStatus($this->__('Done! Saved HTMLPurifier configuration.'));

        // This function generated no output, and so now it is complete we redirect
        // the user to an appropriate page for them to carry on their work
        $this->redirect(ModUtil::url('SecurityCenter', 'admin', 'modifyconfig'));
    }

    /**
     * Function to view ids log events.
     *
     * @return string HTML output string.
     */
    public function viewidslog()
    {
        // Security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_EDIT)) {
            return LogUtil::registerPermissionError();
        }

        $sort = FormUtil::getPassedValue('sort', 'date DESC', 'GETPOST');
        $filterdefault = array('uid' => null, 'name' => null, 'tag' => null, 'value' => null, 'page' => null, 'ip' => null, 'impact' => null);

        $filter = FormUtil::getPassedValue('filter', $filterdefault, 'GETPOST');
        $startnum = (int)FormUtil::getPassedValue('startnum', 0, 'GET');
        $pagesize = (int)$this->getVar('pagesize', 25);

        // instantiate object, generate where clause and select
        $class = 'SecurityCenter_DBObject_IntrusionArray';
        $objArray = new $class();
        $where = $objArray->genFilter($filter);
        $data = $objArray->get($where, $sort, $startnum, $pagesize);

        // unserialize filters data
        foreach ($data as $key => $idsdata) {
            $data[$key]['filters'] = unserialize($data[$key]['filters']);
        }

        // Create output object
        $this->view->assign('filter', $filter)
                   ->assign('sort', $sort)
                   ->assign('objectArray', $data);

        // Assign the values for the smarty plugin to produce a pager.
        $pager = array();
        $pager['numitems'] = $objArray->getCount($where);
        $pager['itemsperpage'] = $pagesize;

        $this->view->assign('startnum', $startnum)
                ->assign('pager', $pager);

        // fetch output from template
        return $this->view->fetch('securitycenter_admin_viewidslog.tpl');
    }

    /**
     * Export ids log.
     *
     * @return string
     */
    public function exportidslog()
    {
        // Security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_EDIT)) {
            return LogUtil::registerPermissionError();
        }

        // get input values
        $confirmed = (int)FormUtil::getPassedValue('confirmed', (isset($args['confirmed']) ? $args['confirmed'] : 0), 'POST');

        if ($confirmed == 1) {

            // export the titles ?
            $exportTitles = FormUtil::getPassedValue('exportTitles', (isset($args['exportTitles']) ? $args['exportTitles'] : null), 'POST');
            $exportTitles = (!isset($exportTitles) || $exportTitles !== '1') ? false : true;

            // name of the exported file
            $exportFile = FormUtil::getPassedValue('exportFile', (isset($args['exportFile']) ? $args['exportFile'] : null), 'POST');
            if (!isset($exportFile) || $exportFile == '') {
                $exportFile = 'idslog.csv';
            }
            if (!strrpos($exportFile, '.csv')) {
                $exportFile .= '.csv';
            }

            // delimeter
            $delimiter = FormUtil::getPassedValue('delimiter', (isset($args['delimiter']) ? $args['delimiter'] : null), 'POST');
            if (!isset($delimiter) || $delimiter == '') {
                $delimiter = 1;
            }
            switch ($delimiter) {
                case 1:
                    $delimiter = ",";
                    break;
                case 2:
                    $delimiter = ";";
                    break;
                case 3:
                    $delimiter = ":";
                    break;
                case 4:
                    $delimiter = chr(9);
            }

            // titles
            if ($exportTitles == 1) {
                $titles = array(
                        $this->__('Name'),
                        $this->__('Tag'),
                        $this->__('Value'),
                        $this->__('Page'),
                        $this->__('User Name'),
                        $this->__('IP'),
                        $this->__('Impact'),
                        $this->__('PHPIDS filters used'),
                        $this->__('Date')
                );
            } else {
                $titles = array();
            }


            // actual data
            $sort = 'ids_date DESC';
            $class = 'SecurityCenter_DBObject_IntrusionArray';
            $objArray = new $class();
            $objData = $objArray->get('', $sort);

            $data = array();
            $find = array("\r\n", "\n");
            $replace = array("", "");

            foreach ($objData as $key => $idsdata) {
                $objData[$key]['filters'] = unserialize($objData[$key]['filters']);

                $filtersused = '';
                foreach ($objData[$key]['filters'] as $filter) {
                    $filtersused .= $filter['id'] . " ";
                }

                $datarow = array(
                        $objData[$key]['name'],
                        $objData[$key]['tag'],
                        htmlspecialchars(str_replace($find, $replace, $objData[$key]['value']), ENT_COMPAT, 'UTF-8', false),
                        htmlspecialchars($objData[$key]['page'], ENT_COMPAT, 'UTF-8', false),
                        $objData[$key]['username'],
                        $objData[$key]['ip'],
                        $objData[$key]['impact'],
                        $filtersused,
                        $objData[$key]['date']
                );

                array_push($data, $datarow);
            }

            // export the csv file
            FileUtil::exportCSV($data, $titles, $delimiter, '"', $exportFile);
        }

        // fetch output from template
        return $this->view->fetch('securitycenter_admin_exportidslog.tpl');
    }

    /**
     * Purge ids log.
     *
     * @return void
     */
    public function purgeidslog()
    {
        // Security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_DELETE)) {
            return LogUtil::registerPermissionError();
        }

        $confirmation = FormUtil::getPassedValue('confirmation');

        // Check for confirmation
        if (empty($confirmation)) {
            // No confirmation yet - get one
            // Return the output that has been generated by this function
            return $this->view->fetch('securitycenter_admin_purgeidslog.tpl');
        }
        // Confirm authorisation code
        $this->checkCsrfToken();

        $redirect_url = ModUtil::url('SecurityCenter', 'admin', 'viewidslog');

        // delete all entries
        if (ModUtil::apiFunc('SecurityCenter', 'admin', 'purgeidslog')) {
            LogUtil::registerStatus($this->__('Done! Purged IDS Log.'));
        }

       $this->redirect($redirect_url);
    }

    /**
     * Display the allowed html form.
     *
     * @return string html output.
     */
    public function allowedhtml($args)
    {
        // security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        $this->view->assign('htmltags', $this->_gethtmltags())
                   ->assign('currenthtmltags', System::getVar('AllowableHTML'))
                   ->assign('htmlentities', System::getVar('htmlentities'));

        // check for HTML Purifier outputfilter
        $htmlpurifier = (bool)(System::getVar('outputfilter') == 1);
        $this->view->assign('htmlpurifier', $htmlpurifier);

        $this->view->assign('configurl', ModUtil::url('SecurityCenter', 'admin', 'modifyconfig'));

        return $this->view->fetch('securitycenter_admin_allowedhtml.tpl');
    }

    /**
     * Update allowed html settings.
     *
     * @return mixed true if successful, false if unsuccessful, error string otherwise.
     */
    public function updateallowedhtml($args)
    {
        $this->checkCsrfToken();

        // security check
        if (!SecurityUtil::checkPermission('SecurityCenter::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // update the allowed html settings
        $allowedhtml = array();
        $htmltags = $this->_gethtmltags();
        foreach ($htmltags as $htmltag => $usagetag) {
            $tagval = (int)FormUtil::getPassedValue('htmlallow' . $htmltag . 'tag', 0, 'POST');
            if (($tagval != 1) && ($tagval != 2)) {
                $tagval = 0;
            }
            $allowedhtml[$htmltag] = $tagval;
        }

        System::setVar('AllowableHTML', $allowedhtml);

        // one additonal config var is set on this page
        $htmlentities = FormUtil::getPassedValue('xhtmlentities', 0, 'POST');
        System::setVar('htmlentities', $htmlentities);

        // clear all cache and compile directories
        ModUtil::apiFunc('Settings', 'admin', 'clearallcompiledcaches');

        // all done successfully
        LogUtil::registerStatus($this->__('Done! Saved module configuration.'));

        $this->redirect(ModUtil::url('SecurityCenter', 'admin', 'allowedhtml'));
    }

    /**
     * Utility function to return the list of available tags.
     *
     * @return string html output.
     */
    private function _gethtmltags()
    {
        // Possible allowed HTML tags
        return array(
                '!--' => 'http://www.w3schools.com/html5/tag_comment.asp',
                'a' => 'http://www.w3schools.com/html5/tag_a.asp',
                'abbr' => 'http://www.w3schools.com/html5/tag_abbr.asp',
                'acronym' => 'http://www.w3schools.com/html5/tag_acronym.asp',
                'address' => 'http://www.w3schools.com/html5/tag_address.asp',
                'applet' => 'http://www.w3schools.com/tags/tag_applet.asp',
                'area' => 'http://www.w3schools.com/html5/tag_area.asp',
                'article' => 'http://www.w3schools.com/html5/tag_article.asp',
                'aside' => 'http://www.w3schools.com/html5/tag_aside.asp',
                'audio' => 'http://www.w3schools.com/html5/tag_audio.asp',
                'b' => 'http://www.w3schools.com/html5/tag_b.asp',
                'base' => 'http://www.w3schools.com/html5/tag_base.asp',
                'basefont' => 'http://www.w3schools.com/tags/tag_basefont.asp',
                'bdo' => 'http://www.w3schools.com/html5/tag_bdo.asp',
                'big' => 'http://www.w3schools.com/tags/tag_font_style.asp',
                'blockquote' => 'http://www.w3schools.com/html5/tag_blockquote.asp',
                'br' => 'http://www.w3schools.com/html5/tag_br.asp',
                'button' => 'http://www.w3schools.com/html5/tag_button.asp',
                'canvas' => 'http://www.w3schools.com/html5/tag_canvas.asp',
                'caption' => 'http://www.w3schools.com/html5/tag_caption.asp',
                'center' => 'http://www.w3schools.com/tags/tag_center.asp',
                'cite' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'code' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'col' => 'http://www.w3schools.com/html5/tag_col.asp',
                'colgroup' => 'http://www.w3schools.com/html5/tag_colgroup.asp',
                'command' => 'http://www.w3schools.com/html5/tag_command.asp',
                'datalist' => 'http://www.w3schools.com/html5/tag_datalist.asp',
                'dd' => 'http://www.w3schools.com/html5/tag_dd.asp',
                'del' => 'http://www.w3schools.com/html5/tag_del.asp',
                'details' => 'http://www.w3schools.com/html5/tag_details.asp',
                'dfn' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'dir' => 'http://www.w3schools.com/tags/tag_dir.asp',
                'div' => 'http://www.w3schools.com/html5/tag_div.asp',
                'dl' => 'http://www.w3schools.com/html5/tag_dl.asp',
                'dt' => 'http://www.w3schools.com/html5/tag_dt.asp',
                'em' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'embed' => 'http://www.w3schools.com/html5/tag_embed.asp',
                'fieldset' => 'http://www.w3schools.com/html5/tag_fieldset.asp',
                'figcaption' => 'http://www.w3schools.com/html5/tag_figcaption.asp',
                'figure' => 'http://www.w3schools.com/html5/tag_figure.asp',
                'font' => 'http://www.w3schools.com/tags/tag_font.asp',
                'footer' => 'http://www.w3schools.com/html5/tag_footer.asp',
                'form' => 'http://www.w3schools.com/html5/tag_form.asp',
                'h1' => 'http://www.w3schools.com/html5/tag_hn.asp',
                'h2' => 'http://www.w3schools.com/html5/tag_hn.asp',
                'h3' => 'http://www.w3schools.com/html5/tag_hn.asp',
                'h4' => 'http://www.w3schools.com/html5/tag_hn.asp',
                'h5' => 'http://www.w3schools.com/html5/tag_hn.asp',
                'h6' => 'http://www.w3schools.com/html5/tag_hn.asp',
                'header' => 'http://www.w3schools.com/html5/tag_header.asp',
                'hgroup' => 'http://www.w3schools.com/html5/tag_hgroup.asp',
                'hr' => 'http://www.w3schools.com/html5/tag_hr.asp',
                'i' => 'http://www.w3schools.com/html5/tag_i.asp',
                'iframe' => 'http://www.w3schools.com/html5/tag_iframe.asp',
                'img' => 'http://www.w3schools.com/html5/tag_img.asp',
                'input' => 'http://www.w3schools.com/html5/tag_input.asp',
                'ins' => 'http://www.w3schools.com/html5/tag_ins.asp',
                'keygen' => 'http://www.w3schools.com/html5/tag_keygen.asp',
                'kbd' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'label' => 'http://www.w3schools.com/html5/tag_label.asp',
                'legend' => 'http://www.w3schools.com/html5/tag_legend.asp',
                'li' => 'http://www.w3schools.com/html5/tag_li.asp',
                'map' => 'http://www.w3schools.com/html5/tag_map.asp',
                'mark' => 'http://www.w3schools.com/html5/tag_mark.asp',
                'menu' => 'http://www.w3schools.com/html5/tag_menu.asp',
                'marquee' => '',
                'meter' => 'http://www.w3schools.com/html5/tag_meter.asp',
                'nav' => 'http://www.w3schools.com/html5/tag_nav.asp',
                'nobr' => '',
                'object' => 'http://www.w3schools.com/html5/tag_object.asp',
                'ol' => 'http://www.w3schools.com/html5/tag_ol.asp',
                'optgroup' => 'http://www.w3schools.com/html5/tag_optgroup.asp',
                'option' => 'http://www.w3schools.com/html5/tag_option.asp',
                'output' => 'http://www.w3schools.com/html5/tag_output.asp',
                'p' => 'http://www.w3schools.com/html5/tag_p.asp',
                'param' => 'http://www.w3schools.com/html5/tag_param.asp',
                'pre' => 'http://www.w3schools.com/html5/tag_pre.asp',
                'progress' => 'http://www.w3schools.com/html5/tag_progress.asp',
                'q' => 'http://www.w3schools.com/html5/tag_q.asp',
                'rp' => 'http://www.w3schools.com/html5/tag_rp.asp',
                'rt' => 'http://www.w3schools.com/html5/tag_rt.asp',
                'ruby' => 'http://www.w3schools.com/html5/tag_ruby.asp',
                's' => 'http://www.w3schools.com/tags/tag_strike.asp',
                'samp' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'script' => 'http://www.w3schools.com/html5/tag_script.asp',
                'section' => 'http://www.w3schools.com/html5/tag_section.asp',
                'select' => 'http://www.w3schools.com/html5/tag_select.asp',
                'small' => 'http://www.w3schools.com/html5/tag_small.asp',
                'source' => 'http://www.w3schools.com/html5/tag_source.asp',
                'span' => 'http://www.w3schools.com/html5/tag_span.asp',
                'strike' => 'http://www.w3schools.com/tags/tag_strike.asp',
                'strong' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'sub' => 'http://www.w3schools.com/html5/tag_sup.asp',
                'summary' => 'http://www.w3schools.com/html5/tag_summary.asp',
                'sup' => 'http://www.w3schools.com/html5/tag_sup.asp',
                'table' => 'http://www.w3schools.com/html5/tag_table.asp',
                'tbody' => 'http://www.w3schools.com/html5/tag_tbody.asp',
                'td' => 'http://www.w3schools.com/html5/tag_td.asp',
                'textarea' => 'http://www.w3schools.com/html5/tag_textarea.asp',
                'tfoot' => 'http://www.w3schools.com/html5/tag_tfoot.asp',
                'th' => 'http://www.w3schools.com/html5/tag_th.asp',
                'thead' => 'http://www.w3schools.com/html5/tag_thead.asp',
                'time' => 'http://www.w3schools.com/html5/tag_time.asp',
                'tr' => 'http://www.w3schools.com/html5/tag_tr.asp',
                'tt' => 'http://www.w3schools.com/tags/tag_font_style.asp',
                'u' => 'http://www.w3schools.com/tags/tag_u.asp',
                'ul' => 'http://www.w3schools.com/html5/tag_ul.asp',
                'var' => 'http://www.w3schools.com/html5/tag_phrase_elements.asp',
                'video' => 'http://www.w3schools.com/html5/tag_video.asp',
                'wbr' => 'http://www.w3schools.com/html5/tag_wbr.asp');
    }

}
