/** * execute() execute a sql-query. * * A standard sql-query wrapper using prepared statements to minimize the * danger for SQL-injection attacks. * * It supports both named and unnamed placeholders. * * Named placeholders: * $data = araray(); * $data['id'] = 1; * $res = MDB2Wrapper::execute('SELECT * FROM table WHERE id=:id', * null, * $data); * * Unnamed placeholders: * $res = MDB2Wrapper::execute('SELECT * FROM table WHERE id==', * array('text'), * array(1)); * * @param String $query The query to execute * @param Array|null $types The datatypes that goes with the query * @param Array|null $data The data to pass along with the query. * @param Boolean $update Flag to indicate if the query is an * update or not. If true, no data will be * fetched from the resultset. */ public static function execute($query, $types, $data, $update = false) { if (!isset(MDB2Wrapper::$conn)) { MDB2Wrapper::create(); } $stmnt = MDB2Wrapper::$conn->prepare($query, $types, MDB2_PREPARE_RESULT); if (PEAR::isError($stmnt)) { Logger::log_event(LOG_NOTICE, "query failed " . $stmnt->getMessage() . "."); throw new DBStatementException("query failed: " . $stmnt->getMessage() . "."); } $res = $stmnt->execute($data); if (PEAR::isError($res)) { $errorCode = PW::create(8); $logMsg = "[{$errorCode}] Query failed: " . $res->getMessage() . " - " . $res->getUserInfo(); if (Config::get_config('debug')) { $logMsg .= "[Debug]: " . $res->getDebugInfo(); } Logger::log_event(LOG_NOTICE, $logMsg); $stmnt->free(); throw new DBQueryException("Error-code: [{$errorCode}] " . $res->getMessage()); } $stmnt->free(); if ($update) { return; } $results = array(); $i = 0; while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)) { $results[$i] = $row; $i = $i + 1; } MDB2Wrapper::$connCounter += 1; return $results; }
public function run() { $page = $this->getInput('page'); $this->page = $page < 1 ? 1 : intval($page); list($start, $limit) = Pw::page2limit($this->page, $this->perpage); $timestamp = PW::getTime(); $startTime = $timestamp - 7 * 86400; $endTime = $timestamp; $total = $this->_getPollDs()->countPollByTime($startTime, $endTime); $pollInfo = array(); if ($total) { Wind::import('SRV:poll.srv.dataSource.PwFetchPollByTime'); $pollDisplay = new PwPollDisplay(new PwFetchPollByTime($startTime, $endTime, $limit, $start, array('voter_num' => 0, 'created_time' => 0))); $pollInfo = $this->_buildPoll($pollDisplay->gather()); } $latestPollDisplay = new PwPollDisplay(new PwFetchPollByOrder(10, 0, array('created_time' => '0'))); $latestPoll = $latestPollDisplay->gather(); $this->setOutput($total, 'total'); $this->setOutput($pollInfo, 'pollInfo'); $this->setOutput($latestPoll, 'latestPoll'); $this->setOutput($this->page, 'page'); $this->setOutput($this->perpage, 'perpage'); $this->setOutput(array('allowview' => $this->loginUser->getPermission('allow_view_vote'), 'allowvote' => $this->loginUser->getPermission('allow_participate_vote')), 'pollGroup'); // seo设置 Wind::import('SRV:seo.bo.PwSeoBo'); $seoBo = PwSeoBo::getInstance(); $lang = Wind::getComponent('i18n'); if ($this->page > 1) { $seoBo->setCustomSeo($lang->getMessage('SEO:vote.hot.run.page.title', array($this->page)), $lang->getMessage('vote.hot.run.description'), ''); } else { $seoBo->setCustomSeo($lang->getMessage('SEO:vote.hot.run.title'), '', $lang->getMessage('SEO:vote.hot.run.description')); } Wekit::setV('seo', $seoBo); }
private static function getError() { if (!isset(Robot::$log_error_code)) { Robot::$log_error_code = PW::create(8); } return Robot::$log_error_code; }
/** * 回复列表 */ public function replyAction() { list($page, $perpage) = $this->getInput(array('page', 'perpage')); $page = $page ? $page : 1; $perpage = $perpage ? $perpage : $this->perpage; list($start, $limit) = Pw::page2limit($page, $perpage); $count = $this->_getThreadExpandDs()->countDisabledPostByUid($this->loginUser->uid); if ($count) { $tmpPosts = $this->_getThreadExpandDs()->getDisabledPostByUid($this->loginUser->uid, $limit, $start); $posts = $tids = array(); foreach ($tmpPosts as $v) { $tids[] = $v['tid']; } $threads = $this->_getThreadDs()->fetchThread($tids); foreach ($tmpPosts as $v) { $v['threadSubject'] = Pw::substrs($threads[$v['tid']]['subject'], 30); $v['content'] = Pw::substrs($v['content'], 30); $v['created_time'] = PW::time2str($v['created_time'], 'auto'); $posts[] = $v; } } $this->setOutput($count, 'count'); $this->setOutput($page, 'page'); $this->setOutput($perpage, 'perpage'); $this->setOutput($posts, 'posts'); // seo设置 Wind::import('SRV:seo.bo.PwSeoBo'); $seoBo = PwSeoBo::getInstance(); $lang = Wind::getComponent('i18n'); $seoBo->setCustomSeo($lang->getMessage('SEO:bbs.article.reply.title'), '', ''); Wekit::setV('seo', $seoBo); }
/** * Instance of the plugin * * @since 1.0.0 * @static * @staticvar array $instance * @return Instance */ public static function instance() { if (!isset(self::$instance) && !self::$instance instanceof PW) { self::$instance = new PW(); self::$instance->define_constants(); add_action('plugins_loaded', array(self::$instance, 'load_textdomain')); self::$instance->includes(); self::$instance->init = new PW_Init(); } return self::$instance; }
/** * 添加草稿 * * @return void */ public function doAddAction() { list($title, $content) = $this->getInput(array('atc_title', 'atc_content')); if (!$title || !$content) { $this->showError('BBS:draft.content.empty'); } if ($this->_getDraftDs()->countByUid($this->loginUser->uid) >= $this->maxNum) { $this->showError('BBS:draft.num.max'); } $draftDm = new PwDraftDm(); $draftDm->setTitle($title)->setContent($content)->setCreatedUserid($this->loginUser->uid)->setCreatedTime(PW::getTime()); $this->_getDraftDs()->addDraft($draftDm); $this->showMessage('success'); }
/** * 我的回复 * */ public function postAction() { list($page, $perpage) = $this->getInput(array('page', 'perpage')); $page = $page ? $page : 1; $perpage = 20; list($start, $limit) = Pw::page2limit($page, $perpage); $count = $this->_getCountPost($this->space->spaceUid, $this->loginUser->uid); if ($count) { $tmpPosts = $this->_getPost($this->space->spaceUid, $this->loginUser->uid, $limit, $start); $posts = $tids = array(); foreach ($tmpPosts as $v) { $tids[] = $v['tid']; } $threads = $this->_getThreadDs()->fetchThread($tids); foreach ($tmpPosts as $v) { $v['threadSubject'] = Pw::substrs($threads[$v['tid']]['subject'], 30); $v['content'] = Pw::substrs($v['content'], 30); $v['created_time'] = PW::time2str($v['created_time'], 'auto'); $posts[] = $v; } } $args = array('uid' => $this->space->spaceUid); $this->setOutput($args, 'args'); $this->setOutput($count, 'count'); $this->setOutput($page, 'page'); $this->setOutput($perpage, 'perpage'); $this->setOutput($posts, 'posts'); $this->setOutput('thread', 'src'); // seo设置 Wind::import('SRV:seo.bo.PwSeoBo'); $seoBo = PwSeoBo::getInstance(); $lang = Wind::getComponent('i18n'); $des = $lang->getMessage('SEO:space.thread.post.description', array($this->space->spaceUser['username'])); if ($page <= 1) { $seoBo->setCustomSeo($lang->getMessage('SEO:space.thread.post.title', array($this->space->spaceUser['username'], $this->space->space['space_name'])), '', $des); } else { $seoBo->setCustomSeo($lang->getMessage('SEO:space.thread.post.page.title', array($this->space->spaceUser['username'], $page, $this->space->space['space_name'])), '', $des); } Wekit::setV('seo', $seoBo); }
/** * __construct() create the subscriber * * @param String $idp_name The name of the subscriber returned by the IdP. * @param NREN $nren the associated NREN * @param String $dn_name The organization-name (that goes into the cert DN) * @param String $org_state * @return void */ function __construct($idp_name, $nren, $dn_name = null, $org_state = null, $db_id = null) { if (is_null($nren)) { $errorCode = PW::create(8); $msg = "[{$errorCode}] " . __FILE__ . ":" . __LINE__; $msg .= "Subscriber must be given a reference to an NREN. Cannot continue."; Logger::log_event(LOG_NOTICE, $msg); throw new ConfusaGenException($msg); } /* ugly hack to circumvent the missing constructor overloading of PHP5 */ $this->nren = $nren; /* NREN-object */ $this->idp_name = htmlentities($idp_name); if (isset($dn_name) && isset($org_state)) { $this->setOrgName($dn_name); $this->setState($org_state); $this->setDBID($db_id); } else { $this->valid = $this->updateFromDB(); if ($this->valid) { $this->retrieveMap(); } } }
/** * save() store updated results to the database, encrypting the password * before storage. */ public function save($validate = true) { if (!$this->changed) { return false; } if ($validate && !CAHandler::getCA($this->person)->verifyCredentials($this->login_name, $this->password)) { /* FIXME: l10n */ throw new ConfusaGenException("Invalid username/password, Comodo will not accept!"); } /* We create a new ivector every time we save the password */ $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB); $iv = mcrypt_create_iv($size, MCRYPT_DEV_URANDOM); $cryptpw = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, Config::get_config('capi_enc_pw'), base64_encode($this->password), MCRYPT_MODE_CFB, $iv)); if (MDB2Wrapper::testColumn('nrens', 'login_name') && MDB2Wrapper::testColumn('nrens', 'password') && MDB2Wrapper::testColumn('nrens', 'ivector') && MDB2Wrapper::testColumn('nrens', 'ap_name')) { $sql = " UPDATE nrens SET login_name=?, password=?, ivector=?, ap_name=?"; $sql .= " WHERE nren_id = ?"; Logger::log_event(LOG_DEBUG, "Using the new database-schema for account-details"); } else { if (isset($this->account_id)) { $sql = "UPDATE account_map SET login_name=?, password=?, ivector=?, ap_name=?"; $sql .= " WHERE nren_id = ?"; } else { $sql = "INSERT INTO account_map (login_name, password, ivector, ap_name, nren_id) "; $sql .= "VALUES(?, ?, ?, ?, ?)"; } } $params = array('text', 'text', 'text', 'text', 'integer'); $data = array($this->login_name, $cryptpw, base64_encode($iv), $this->ap_name, $this->nren->getID()); try { MDB2Wrapper::update($sql, $params, $data); Logger::log_event(LOG_NOTICE, "account-data updated for NREN " . $this->nren->getID()); } catch (DBQueryException $dqe) { $errorTag = PW::create(); Logger::log_event(LOG_ERR, "Could not update the login-account with ID " . $this->account_id . " for " . $this->nren->getID() . "(" . $this->login_name . ")"); return false; } catch (DBStatementException $dse) { $errorTag = PW::create(); Logger::log_event(LOG_ERR, "Could not update the login-account for NREN " . $this->nren->getID() . " to new value {$login_name} " . $dse->getMessage()); return false; } $this->changed = false; return true; }
<?php require_once 'confusa_include.php'; require_once 'Robot.php'; require_once 'MDB2Wrapper.php'; require_once 'cert_lib.php'; require_once 'Logger.php'; require_once 'Person.php'; require_once 'CA.php'; $log_error_code = PW::create(8); /** * assertEnvironment() make sure that we are operating safely * * Assert that we are on SSL and on appropriate level before continuing. If any * of the requirements are not met, we abort and close the connection. * * @param void * @return void */ function assertEnvironment() { global $log_error_code; /* * are we on SSL */ if (is_null($_SERVER['HTTPS'])) { Logger::log_event(LOG_NOTICE, "[RI] ({$log_error_code}) Environment-variable 'HTTP' not available."); exit(0); } if (strtolower($_SERVER['HTTPS']) != 'on') { Logger::log_event(LOG_NOTICE, "[RI] ({$log_error_code}) Server is not running on SSL. Blocking robot-connections.");
protected function modelPostList($limit, $page) { $ds = Wekit::load('forum.PwThread'); list($offset, $limit) = Pw::page2limit($page, $limit); $count = $ds->countPostByUid($this->spaceUid); if ($count) { $tmpPosts = $ds->getPostByUid($this->spaceUid, $limit, $offset); $posts = $tids = array(); foreach ($tmpPosts as $v) { $tids[] = $v['tid']; } $threads = $this->_getThreadDs()->fetchThread($tids); foreach ($tmpPosts as $v) { $v['threadSubject'] = Pw::substrs($threads[$v['tid']]['subject'], 30); $v['content'] = Pw::substrs($v['content'], 30); $v['created_time'] = PW::time2str($v['created_time'], 'auto'); $posts[] = $v; } } return array($count, $posts); }
/** * 获取某个生活服务版块下的帖子列表 * @access public * @return string <pre> /index.php?m=native&c=life&a=life&fid=生活服务分类id&page=1&_json=1 response: </pre> */ public function lifeAction() { list($page, $fid) = $this->getInput(array('page', 'fid'), 'get'); !$fid && $this->showError('NATIVE:args.error'); $page = intval($page) > 1 ? intval($page) : 1; $pos = ($page - 1) * $this->perpage; //获取单个版块信息 $forum = Wekit::loadDao('forum.dao.PwForumDao')->getForum($fid); $forum_life = Wekit::loadDao('native.dao.PwForumLifeDao')->getForumLife($fid); $forum['address'] = isset($forum_life['address']) ? $forum_life['address'] : ''; $forum['url'] = isset($forum_life['url']) ? $forum_life['url'] : ''; $user_fids = array(); if ($this->uid) { $user_fids = Wekit::loadDao('forum.dao.PwForumUserDao')->getFroumByUid($this->uid); } $isjoin = array_key_exists($fid, $user_fids) ? true : false; $count = Wekit::loadDao('forum.dao.PwThreadsDao')->countThreadByFidAndType($fid, 0); $threads = Wekit::loadDao('forum.dao.PwThreadsDao')->getThreadByFid($fid, $this->perpage, $pos); $tids = array_keys($threads); $threads_list = Wekit::load('native.srv.PwDynamicService')->fetchThreadsList($tids, $this->uid); // $result = array('forumInfo'=>$forum,'threadsList'=>$threads_list); // var_dump($result);exit; ($max_page = ceil($count / $this->perpage)) || ($max_page = 1); $page_info = array('page' => $page, 'perpage' => $this->perpage, 'count' => $count, 'max_page' => $max_page); $data = array('page_info' => $page_info, 'user_info' => array('uid' => $this->uid, 'isjoin' => $isjoin), 'forum_info' => $page == 1 ? $forum : '', 'threads_list' => $threads_list); $this->setOutput($data, 'data'); $this->showMessage('NATIVE:data.success'); exit; /* 测试pw提供获取帖子内容service */ $thread_content = Wekit::load('forum.PwThread')->fetchThread(array(26, 45, 43, 44), PwThread::FETCH_ALL); //PW 提供的获取帖子内容方法 var_dump($thread_content); exit; PW::getTime(); //PW工具类 // $thread_content = Wekit::loadDao('forum.dao.PwThreadsContentDao')->getThread(81); // var_dump($thread_content);exit; }
public function process() { if (!$this->person->isNRENAdmin()) { $errorTag = PW::create(); Logger::logEvent(LOG_NOTICE, "Accountant", "process()", "User " . stripslashes($this->person->getX509ValidCN()) . " tried to access the accountant.", __LINE__, $errorTag); $this->tpl->assign('reason', "[{$errorTag}] You are not an NREN-admin"); $this->tpl->assign('content', $this->tpl->fetch('restricted_access.tpl')); return; } else { if (Config::get_config('ca_mode') != CA_COMODO) { $errorTag = PW::create(); Logger::logEvent(LOG_NOTICE, "Accountant", "process()", "User " . stripslashes($this->person->getX509ValidCN()) . "tried to access the accountant, " . "even though Confusa is not using the Comodo CA.", __LINE__, $errorTag); $this->tpl->assign('reason', "[{$errorTag}] Confusa is not using Comodo CA"); $this->tpl->assign('content', $this->tpl->fetch('restricted_access.tpl')); return; } } /* set fields in template */ if (!$this->account->getLoginName()) { $this->tpl->assign('login_name', $this->translateTag('l10n_fieldval_undefined', 'accountant')); } else { $this->tpl->assign('login_name', $this->account->getLoginName()); } if (!$this->account->getPassword()) { $this->tpl->assign('password', $this->translateTag('l10n_fieldval_undefined', 'accountant')); } else { $this->tpl->assign('password', $this->translateTag('l10n_label_passwhidden', 'accountant')); } if (!$this->account->getAPName()) { $this->tpl->assign('ap_name', $this->translateTag('l10n_fieldval_undefined', 'accountant')); } else { $this->tpl->assign('ap_name', $this->account->getAPName()); } $this->tpl->assign('verify_ca', 'yes'); $this->tpl->assign('content', $this->tpl->fetch('accountant.tpl')); }
/** * Verify if the subject DN matches the received sets of attributes. * Sign a key using the local CA-key. * Store the public key of the request in the database. * * @throws: KeySignException */ public function signKey($csr) { if (!$this->person->getSubscriber()->isSubscribed()) { throw new KeySignException("Subscriber not subscribed, cannot create certificate!"); } $auth_key = $csr->getAuthToken(); if ($this->verifyCSR($csr->getPEMContent())) { $cert_file_name = tempnam("/tmp/", "REV_CERT_"); $cert_file = fopen($cert_file_name, "w"); fclose($cert_file); $path = dirname(dirname(dirname(__FILE__))) . "/cert_handle/sign_key.sh"; if (!file_exists($path)) { throw new KeySignException("sign_key.sh does not exist!"); } $cmd = "{$path} {$auth_key} {$cert_file_name} " . ConfusaConstants::$OPENSSL_SERIAL_FILE . " " . $this->validityDays; $res = shell_exec($cmd); $val = explode("\n", $res); /* FIXME: add better logic here. */ switch ((int) $val[0]) { case 0: break; default: throw new KeySignException("Unable to sign certificate (" . $val[1] . ")"); } if (!file_exists($cert_file_name)) { $errorCode = PW::create(8); $msg = "Cannot find temporar certificate file. Please forward the following "; $msg .= "error-code to the aministrators: [{$errorCode}]"; $logMsg = "Temporary certificate file vanished before it could be read. "; $logMsg .= "Please investigate."; Logger::log_event(LOG_ALERT, __FILE__ . ":" . __LINE__ . "[errorCode] {$logMsg}"); throw new FileNotFoundException($msg); } $cert = file_get_contents($cert_file_name); unlink($cert_file_name); if ($cert == null || $cert == "") { $msg = "Unable to sign certificate using backend scripts.<br />\n"; $msg .= "The certificate was not found in local file ({$cert_file_name}) where it was expected to be.<br />\n"; throw new KeySignException($msg); } $cert_array = openssl_x509_parse($cert); $diff = (int) $cert_array['validTo_time_t'] - (int) $cert_array['validFrom_time_t']; $timeout = array($diff, 'SECOND'); try { $insert = "INSERT INTO cert_cache (cert, auth_key, cert_owner, organization, valid_untill) "; $insert .= "VALUES(?, ?, ?, ?, timestampadd({$timeout['1']}, {$timeout['0']},current_timestamp()))"; MDB2Wrapper::update($insert, array('text', 'text', 'text', 'text'), array($cert, $auth_key, $this->person->getX509ValidCN(), $this->person->getSubscriber()->getIdPName())); } catch (DBStatementException $dbse) { $error_key = PW::create(8); Logger::log_event(LOG_NOTICE, __FILE__ . ":" . __LINE__ . " Error in query-syntax. Make sure the query matches the db-schema. ({$error_key})"); throw new KeySignException("Cannot insert certificate into database.<BR />error-reference: {$error_key}"); } catch (DBQueryException $dbqe) { $error_key = PW::create(8); Logger::log_event(LOG_NOTICE, __FILE__ . ":" . __LINE__ . " Error with values passed to the query. Check for constraint-violations"); throw new KeySignException("Cannot insert certificate into database.<BR />error-reference: {$error_key}"); } $timezone = new DateTimeZone($this->person->getTimezone()); $dt = new DateTime("now", $timezone); CA::sendMailNotification($auth_key, $dt->format('Y-m-d H:i T'), $_SERVER['REMOTE_ADDR'], $this->person, $this->getFullDN()); Logger::log_event(LOG_INFO, "Certificate successfully signed for " . stripslashes($this->person->getX509ValidCN()) . " Contacting us from " . $_SERVER['REMOTE_ADDR']); } else { Logger::log_event(LOG_INFO, "Will not sign invalid CSR for user " . stripslashes($this->person->getX509ValidCN()) . " from ip " . $_SERVER['REMOTE_ADDR']); throw new KeySignException("CSR subject verification failed!"); } }
/** * getSubscribers - get an array with subscriber and state * * Find all subscribers for the current NREN and return an array containing * - subscriber name * - subscriber state (subscribed | unsubscribed | suspended) * */ private function getSubscribers() { try { return $this->person->getNREN()->getSubscriberList(); } catch (DBStatementException $dbse) { $errorTag = PW::create(); $msg = "Error in query-syntax. Verify that the query matches the database!"; Logger::logEvent(LOG_NOTICE, "NRENAdmin", "getSubscribers()", $msg, __LINE__, $errorTag); $msg .= "<br />Server said: " . htmlentities($dbse->getMessage()); Framework::error_output("[{$errorTag}]" . $msg); return; } catch (DBQueryException $dbqe) { $errorTag = PW::create(); $msg = "Possible constraint-violation in query. Compare query to db-schema"; Logger::logEvent(LOG_NOTICE, "NRENAdmin", "getSubscribers()", $msg, __LINE__, $errorTag); $msg .= "<br />Server said: " . htmlentities($dbse->getMessage()); Framework::error_output("[{$errorTag}]" . $msg); } }
/** * insertNewCertificate() insert the new certificate into the robot hold * * Take a string holding the certificate and insert it into the keyhold * given that the string is actually holding a valid certificate. * * @param String base64 encoded PEM formatted X.509 certificate * @return boolean indicating the success of the opreation (true means inserted OK) */ private function insertCertificate($certificate, $comment) { /* validate certificate */ try { $cert = new Certificate($certificate); } catch (KeyNotFoundException $knfe) { Framework::error_output(htmlentities($knfe->getMessage())); return false; } catch (CertificateException $ce) { Framework::error_output(htmlentities($ce->getMessage())); return false; } /* Find valid_until for cert */ try { $query = "SELECT subscriber_id, uploaded_by, uploaded_date, valid_until, fingerprint "; $query .= "FROM robot_certs WHERE fingerprint = ? OR serial=?"; $res = MDB2Wrapper::execute($query, array('text', 'text'), array($cert->getFingerprint(), $cert->getSerial())); if (count($res) > 0) { Framework::error_output($this->translateTag('l10n_err_certalrthere', 'robot')); return false; } } catch (Exception $e) { /* FIXME, add better exception mask & handling */ Framework::error_output(__FILE__ . ":" . __LINE__ . " FIXME: " . htmlentities($e->getMessage())); return false; } /* Get subscriber, nren and admin_id */ try { $query = "SELECT * FROM admins WHERE admin=? AND subscriber=? AND nren=? "; $params = array('text', 'text', 'text'); $data = array($this->person->getEPPN(), $this->person->getSubscriber()->getDBID(), $this->person->getNREN()->getID()); $res = MDB2Wrapper::execute($query, $params, $data); switch (count($res)) { case 0: /* * Strange error. User is admin, yet not admin. * * Fixme: better error-reporting here, even * though we cannot do much about it. */ $error_code = strtoupper(PW::create(8)); $error_msg = "[error_code: {$error_code}]<br /><br />\n"; $log_msg = "[{$error_code}] "; $query = "SELECT * FROM admins WHERE admin=? AND admin_level=? AND subscriber IS NULL"; $params = array('text', 'text'); $data = array($this->person->getEPPN(), SUBSCRIBER_ADMIN); $admin_query_res = MDB2Wrapper::execute($query, $params, $data); if (count($admin_query_res) != 0) { $error_msg .= "The subscriber-admin (" . htmlentites($this->person->getEPPN()) . ") is not properly connected "; $error_msg .= "to any database. This is due to a database inconsistency "; $error_msg .= "and is a direct result of someone manually adding the admin to the database "; $error_msg .= "without connecting the admin to a subscriber."; $log_msg .= "Subscriber-admin " . $this->person->getEPPN(); $log_msg .= " has not set any affilitated subscriber in the database."; $log_msg .= " It should be " . $this->person->getSubscriber()->getOrgName(); $log_msg .= ", but is NULL. Please update the database."; } else { $error_msg .= "For some reason, the subscriber (" . $this->person->getSubscriber()->getOrgName() . ") "; $error_msg .= "is not properly configured in the database. "; $error_msg .= "The exact reason is unknown. Please contact operational support."; $log_msg .= "Subscriber " . $this->person->getSubscriber()->getOrgName(); $log_msg .= " is not properly configured in the database."; } $error_msg .= "<br /><br />\nThis event has been logged, please contact operational support (provide the error-code) "; $error_msg .= "to resolve this issue."; Framework::error_output($error_msg); Logger::log_event(LOG_ALERT, $log_msg); return false; case 1: $admin_id = $res[0]['admin_id']; $nren_id = $res[0]['nren']; $subscriber_id = $res[0]['subscriber']; break; default: /* FIXME: DB-inconsistency */ $error_code = strtoupper(PW::create(8)); $error_msg = "[error_code: {$error_code}] multiple instances of admin ("; $error_msg .= $this->person->getEPPN() . ") found in the database."; $log_msg = "[{$error_code}] multiple hits (" . count($res) . ")on "; $log_msg .= $this->person->getEPPN() . " in admins-table."; Framework::error_output($error_msg); Logger::log_event(LOG_ALERT, $log_msg); return false; } } catch (Exception $e) { Framework::error_output(hmtlentities($e->getMessage())); /* FIXME, add proper exception handling */ return false; } try { if (!isset($comment) || $comment == "") { $comment = " "; } $update = "INSERT INTO robot_certs (subscriber_id, uploaded_by, uploaded_date, valid_until, cert, fingerprint, serial, comment)"; $update .= " VALUES(?, ?, current_timestamp(), ?, ?, ?, ?, ?)"; $params = array('text', 'text', 'text', 'text', 'text', 'text', 'text'); $data = array($subscriber_id, $admin_id, $cert->getEndDate(), $cert->getPEMContent(), $cert->getFingerprint(), $cert->getSerial(), $comment); MDB2Wrapper::update($update, $params, $data); Logger::log_event(LOG_INFO, "[RI] Added new certificate (" . $cert->getSerial() . ") for subscriber " . $this->person->getSubscriber()->getOrgName() . " associated with admin " . $this->person->getEPPN()); } catch (Exception $e) { /* FIXME */ Framework::error_output("Couldn't update robot_certs, server said:<br />\n" . htmlentities($e->getMessage())); return false; } Framework::success_output($this->translateTag('l10n_suc_insertcert1', 'robot') . " " . $cert->getSerial() . $this->translateTag('l10n_suc_insertcert2', 'robot')); return true; }
/** * verifyCredentials() validate username/password to Comodo * * @param String $username * @param String $password * @return Boolean true if username/password was ok */ function verifyCredentials($username, $password) { require_once "pw.php"; require_once "CurlWrapper.php"; $pf = $this->bs_pf(); $pf["commonName"] = "" . PW::create(32); $data = CurlWrapper::curlContact(ConfusaConstants::$CAPI_LISTING_ENDPOINT, "post", $pf); parse_str($data, $params); if (array_key_exists('errorCode', $params) && $params['errorCode'] === "0") { return true; } return false; }
/** * Sign the CSR with the passed authToken. If signing succeeds, the class * member authKey is set to the orderNumber/certHash. If not, an error is * displayer * @param $authToken pubkey hash of the CSR that is to be signed */ private function signCSR($authToken) { $csr = CSR::getFromDB($this->person->getX509ValidCN(), $authToken); if (!isset($csr) || !$csr) { $errorTag = PW::create(); Framework::error_output("[{$errorTag}] Did not find CSR with auth_token " . htmlentities($auth_token)); $msg = "User " . $this->person->getEPPN() . " "; $msg .= "tried to delete CSR with auth_token " . $authToken . " but was unsuccessful"; Logger::logEvent(LOG_NOTICE, "Process_CSR", "approveCSR({$authToken})", $msg, __LINE__, $errorTag); return false; } try { if (!isset($this->ca)) { Framework::error_output($this->translateTag('l10n_err_noca', 'processcsr')); return false; } $permission = $this->person->mayRequestCertificate(); if ($permission->isPermissionGranted() === false) { Framework::error_output($this->translateTag('l10n_err_noperm1', 'processcsr') . "<br /><br />" . $permission->getFormattedReasons() . "<br />" . $this->translateTag('l10n_err_noperm2', 'processcsr')); return; } $this->authKey = $this->ca->signKey($csr); } catch (CGE_ComodoAPIException $capie) { Framework::error_output($this->translateTag('l10n_sign_error', 'processcsr') . htmlentities($capie)); return false; } catch (ConfusaGenException $e) { $msg = $this->translateTag('l10n_sign_error', 'processcsr') . "<br /><br /><i>" . htmlentities($e->getMessage()) . "</i><br />"; Framework::error_output($msg); return false; } catch (KeySigningException $kse) { Framework::error_output($this->translateTag('l10n_sign_error', 'processcsr') . htmlentites($kse->getMessage())); return false; } CSR::deleteFromDB($this->person, $authToken); }
public function start() { /* From OWASP (prevent clickjacking): * * This new (nonstandard) X-FRAME-OPTIONS header is used to mark * responses that shouldn't be framed. There are two options with * X-FRAME-OPTIONS. The first is DENY, which prevents everyone from * framing the content. * * This can also be done by apache itself: * a2enmod headers * Add to the Virtualhost, directory that hosts confusa: * Header set X-Frame-Options "DENY" */ header('X-Frame-Options: DENY'); /* * Strict-Transport-Security (RFC 6797) * Once page has been accessed over HTTPS and this header was present, * confirmant browsers will force subsequent requests over HTTPS aswell. */ header('Strict-Transport-Security: max-age=31536000'); /* Set tpl object to content page */ $this->contentPage->setTpl($this->tpl); /* check the authentication-thing, catch the login-hook * This is done via confusa_auth */ try { $this->authenticate(); } catch (CGE_CriticalAttributeException $cae) { $msg = "<b>" . $this->contentPage->translateMessageTag('fw_error_critical_attribute1') . "</b><br /><br />"; $msg .= htmlentities($cae->getMessage()) . "<br /><br />"; $msg .= $this->contentPage->translateMessageTag('fw_error_critical_attribute2'); Framework::error_output($msg); $this->renderError = true; } catch (MapNotFoundException $mnfe) { $msg = $this->contentPage->translateMessageTag('fw_error_map_notfound'); /* if user is admin */ if ($this->person->isNRENAdmin()) { $msg .= "<br /><br />"; $msg .= "<a href=\"attributes.php?mode=admin&anticsrf=" . Framework::getAntiCSRF() . "\">"; $msg .= $this->contentPage->translateMessageTag('fw_error_map_updatemap'); $msg .= "</>\n"; } Framework::error_output($msg); $this->renderError = true; } catch (ConfusaGenException $cge) { Framework::error_output($this->contentPage->translateMessageTag('fw_error_auth') . htmlentities($cge->getMessage())); $this->renderError = true; } if ($this->isCSRFAttempt()) { Framework::error_output($this->contentPage->translateMessageTag('fw_anticsrf_msg')); $this->tpl->assign('instance', Config::get_config('system_name')); $this->tpl->assign('errors', self::$errors); $this->tpl->display('site.tpl'); exit(0); } /* Create a new anti CSRF token and export to the template engine */ $this->current_anticsrf = self::getAntiCSRF(); $this->tpl->assign('ganticsrf', 'anticsrf=' . $this->current_anticsrf); $this->tpl->assign('panticsrf', '<input type="hidden" name="anticsrf" value="' . $this->current_anticsrf . '" />'); /* * Try to run the pre-processing */ try { $res = $this->contentPage->pre_process($this->person); if ($res) { $this->tpl->assign('extraHeader'); } } catch (CGE_RemoteCredentialException $rce) { $msg = $this->contentPage->translateMessageTag('fw_error_remote_credential1'); $msg .= "<i>" . htmlentities($rce->getMessage()) . "</i><br /><br />"; if ($this->person->isNRENAdmin()) { $msg .= "<div style=\"text-align: center\">"; $msg .= self::translateMessageTag('fw_error_remote_credential2') . "</div>"; } else { $msg .= Framework::error_output($this->contentPage->translateMessageTag('fw_error_remote_credential3')); $this->renderError = true; } Framework::warning_output($msg); } catch (KeyNotFoundException $knfe) { $this->renderError = true; $errorTag = PW::create(8); $msg = "[{$errorTag}] " . $this->contentPage->translateMessageTag('fw_keynotfound1'); Logger::logEvent(LOG_NOTICE, "Framework", "start()", "Config-file not properly configured: " . $knfe->getMessage(), __LINE__, $errorTag); $msg .= htmlentities($knfe->getMessage()); $msg .= "<br />" . $this->contentPage->translateMessageTag('fw_keynotfound2'); Framework::error_output($msg); } catch (Exception $e) { Framework::error_output($this->contentPage->translateMessageTag('fw_unhandledexp1') . "<br />" . htmlentities($e->getMessage())); $this->renderError = true; } /* ---------------------------------------------------------------- * Admin messages, trigger on missing elements */ if ($this->person->isNRENAdmin()) { $this->triggerAdminIssues(); } /* Mode-hook, to catch mode-change regardless of target-page (not only * index) */ if (isset($_GET['mode'])) { $new_mode = NORMAL_MODE; if (htmlentities($_GET['mode']) == 'admin') { $new_mode = ADMIN_MODE; } $this->person->setMode($new_mode); } $this->tpl->assign('title_logo', $this->contentPage->translateMessageTag('l10n_title_logo')); $this->tpl->assign('person', $this->person); $this->tpl->assign('subscriber', $this->person->getSubscriber()); $this->tpl->assign('nren', $this->person->getNREN()); $this->tpl->assign('is_online', Config::get_config('ca_mode') === CA_COMODO); /* If we have a renderError, do not allow the user-page to * render, otherwise, run it, and catch all unhandled exception * * The general idea, is that the process() should be * self-contained wrt to exceptions. * * A NREN admin is supposed to be able to "fix stuff" such as for instance * CGE_CriticalAttributeExceptions and should hence see the pages also if * renderError is set. */ if (!$this->renderError || $this->person->isNRENAdmin()) { try { $this->applyNRENBranding(); $this->contentPage->process($this->person); } catch (KeyNotFoundException $knfe) { $errorTag = PW::create(8); $msg = "[{$errorTag}] " . $this->contentPage->translateMessageTag('fw_keynotfound1'); Logger::logEvent(LOG_NOTICE, "Framework", "start()", "Config-file not properly configured: " . $knfe->getMessage(), __LINE__, $errorTag); $msg .= htmlentities($knfe->getMessage()); $msg .= "<br />" . $this->contentPage->translateMessageTag('fw_keynotfound2'); Framework::error_output($msg); } catch (Exception $e) { Logger::logEvent(LOG_INFO, "Framework", "start()", "Unhandleded exception when running contentPage->process()", __LINE__); Framework::error_output($this->contentPage->translateMessageTag('fw_unhandledexp1') . "<br />\n" . htmlentities($e->getMessage())); } } else { $nren = $this->person->getNREN(); if (isset($nren)) { /* if all else fails, at least give the user some recovery information */ Framework::message_output($this->contentPage->translateMessageTag('fw_unrecoverable_nren') . htmlentities($this->person->getEPPN())); } else { $errorTag = PW::create(); Framework::error_output("[{$errorTag}] " . $this->contentPage->translateMessageTag('fw_unrecoverable_nonren')); Logger::logEvent(LOG_WARNING, "Framework", "start()", "User contacting us from " . $_SERVER['REMOTE_ADDR'] . " tried to login from IdP that appears to have no NREN-mapping!", __LINE__, $errorTag); } } $this->tpl->assign('logoutUrl', 'logout.php'); // see render_menu($this->person) $this->tpl->assign('menu', $this->tpl->fetch('menu.tpl')); $this->tpl->assign('errors', self::$errors); $this->tpl->assign('messages', self::$messages); $this->tpl->assign('successes', self::$successes); $this->tpl->assign('warnings', self::$warnings); if (Config::get_config('debug')) { $db_debug_res = ""; $db_debug_res .= "<address>\n"; $db_debug_res .= "During this session, we had "; $db_debug_res .= MDB2Wrapper::getConnCounter() . " individual DB-connections.<br />\n"; $db_debug_res .= "</address>\n"; $this->tpl->assign('db_debug', $db_debug_res); } $this->tpl->display('site.tpl'); if (!$this->renderError) { $this->contentPage->post_process($this->person); } }
/** * getAdminStatus() get the admin-level from the database * * This function assumes isAuth() has been verified. * * @param void * @return Integer value indication the admin-level */ private function getAdminStatus() { if (isset($this->adminStatus)) { return $this->adminStatus; } $adminRes = NORMAL_USER; if (!$this->isAuth()) { $this->adminStatus = NORMAL_USER; return NORMAL_USER; } /* if the database is riddled with errors, do not run through the * test once more, just bail */ if ($this->adminDBError) { $this->adminStatus = NORMAL_USER; return NORMAL_USER; } require_once 'MDB2Wrapper.php'; $errorCode = PW::create(8); $query = "SELECT * FROM admins WHERE admin=:admin AND nren=:nren_id AND "; $query .= "((admin_level='2' AND (idp_url='' OR ISNULL(idp_url) OR idp_url=:idp_url)) OR "; $query .= "((admin_level='1' OR admin_level='0') AND subscriber=:subscriber_id))"; $params = array(); $params['admin'] = $this->eppn; $params['nren_id'] = $this->nren->getID(); $params['idp_url'] = $this->nren->getIdP(); $params['subscriber_id'] = -1; if (!is_null($this->getSubscriber())) { $params['subscriber_id'] = $this->getSubscriber()->getDBID(); } $res = MDB2Wrapper::execute($query, null, $params); $size = count($res); if ($size == 1) { $adminRes = $res[0]['admin_level']; if ($this->getName(false) != $res[0]['admin_name'] || $this->getEmail(false) != $res[0]['admin_email']) { try { MDB2Wrapper::update("UPDATE admins SET admin_name=?, admin_email=? WHERE admin_id=?", array('text', 'text', 'text'), array($this->getName(false), $this->getEmail(false), $res[0]['admin_id'])); } catch (DBStatementException $dbse) { $msg = "[{$errorCode}] Database not properly set. Missing fields in the admins-table."; Logger::log_event(LOG_ALERT, __FILE__ . ":" . __LINE__ . $msg); Framework::error_output($msg . "<br />Server said: " . $dbse->getMessage()); $this->adminDBError = true; } catch (DBQueryException $dbqe) { Logger::log_event(LOG_INFO, "[{$errorCode}] Could not update data for admin." . $dbqe->getMessage()); Framework::error_output("[{$errorCode}] Could not update data for admin. Problems with keys. Server said: " . $dbqe->getMessage()); $this->adminDBError = true; } catch (Exception $e) { $msg = "Could not update admin-data. Unknown error. Server said: " . $e->getMessage(); Framework::error_output($msg); Logger::Log_event(LOG_INFO, $msg); $this->adminDBError = true; } } } $this->adminStatus = $adminRes; return $adminRes; }
private function updateNRENCSS($nren, $content) { $css_path = Config::get_config('custom_css') . $nren . '/custom.css'; try { /* if the path to the NREN's CSS file does not exist, create the * respective folders * This should have been done by the bootstrap script, though */ File_IO::writeToFile($css_path, $content, TRUE, TRUE); } catch (FileException $fexp) { $error_code = PW::create(8); Logger::log_event(LOG_ERR, "[{$error_code}] could not write custom CSS for NREN {$nren} to file {$css_path}. Propagated error: " . $fexp->getMessage()); Framework::error_output("[{$error_code}] " . $this->translateTag('l10n_fail_updcss', 'stylist')); return; } Logger::log_event(LOG_INFO, "The custom CSS for NREN " . $nren . " was changed. User contacted us from " . $_SERVER['REMOTE_ADDR']); Framework::success_output($this->translateTag('l10n_suc_updcss', 'stylist')); }