function getAccessTokenTimeout($idp_url) { $query = "SELECT reauth_timeout FROM nrens n, idp_map m " . "WHERE m.nren_id = n.nren_id AND m.idp_url = ?"; try { $res = MDB2Wrapper::execute($query, array('text'), array($idp_url)); } catch (ConfusaGenException $cge) { throw new CGE_AuthException("No NREN connected to IdP {$idp_url}!"); } if (count($res) == 1) { return $res[0]['reauth_timeout']; } else { return ConfusaConstants::$DEFAULT_REAUTH_TIMEOUT; } }
public function getCriticalErrors() { $query = "SELECT error_date, log_msg FROM critical_errors WHERE " . "is_resolved = false"; try { $res = MDB2Wrapper::execute($query, null, null); } catch (ConfusaGenException $e) { $this->tpl->assign('generalErrors', true); $this->tpl->assign('errorMessage', $e->getMessage()); return false; } foreach ($res as $row) { $this->logErrors[] = $row['error_date'] . " " . $row['log_msg']; } return true; }
/** * delSubscriber - remove the subscriber from the NREN and Confusa. * * This will remove the subscriber *permanently* along with all it's * affiliated subscriber admins (this is handled by the database-schema * with the 'ON DELETE CASCADE'. * * @param id String|integer the ID of the institution/subscriber in the database. * */ private function delSubscriber($id) { if (!isset($id) || $id === "") { Framework::error_output("Cannot delete subscriber with unknown id!"); } $nren = $this->person->getNREN(); /* * Make sure that we are deleting a subscriber from the current NREN. */ try { $query = "SELECT nren_id, subscriber FROM nren_subscriber_view "; $query .= "WHERE nren=? AND subscriber_id=?"; $res = MDB2Wrapper::execute($query, array('text', 'text'), array($this->person->getNREN(), $id)); } catch (DBQueryException $dbqe) { $errorTag = PW::create(); $msg = "Could not delete subscriber with ID {$id} from DB."; Logger::logEvent(LOG_NOTICE, "NRENAdmin", "delSubscriber()", $msg, __LINE__, $errorTag); Framework::message_output($msg . "<br />[{$errorTag}] Server said: " . htmlentities($dbqe->getMessage())); return false; } catch (DBStatementException $dbse) { $errorTag = PW::create(); $msg = "Could not delete subsriber with ID {$id} from DB, due to problems with the " . "statement. Probably this is a configuration error. Server said: " . $dbse->getMessage(); Logger::logEvent(LOG_NOTICE, "NRENAdmin", "delSubscriber()", $msg, __LINE__, $errorTag); Framework::message_output("[{$errorTag}]" . htmlentities($msg)); return false; } if (count($res) != 1) { Framework::error_output("Could not find a unique NREN/subscriber pair for subscriber with id " . htmlentities($id)); return false; } $nren_id = $res[0]['nren_id']; $subscriberName = $res[0]['subscriber']; if (!isset($nren_id) || $nren_id == "") { Framework::error_output("Could not get the NREN-ID for subscriber " . htmlentities($id) . "Will not delete subscriber (" . htmlentites($id) . ")."); return false; } /* * Revoke all certificates for subscriber */ $ca = CAHandler::getCA($this->person); $list = $ca->getCertListForPersons("", $subscriberName); $count = 0; foreach ($list as $key => $value) { try { if (isset($value['auth_key'])) { echo "<pre>\n"; print_r($value); echo "</pre>\n"; if ($ca->revokeCert($value['auth_key'], "privilegeWithdrawn")) { $count = $count + 1; } } } catch (CGE_KeyRevokeException $kre) { echo $kre->getMessage() . "<br />\n"; } Logger::logEvent(LOG_INFO, "NRENAdmin", "delSubscriber()", "Deleting subscriber, revoked {$count} issued certificates " . "for subscriber {$subscriberName}."); } MDB2Wrapper::update("DELETE FROM subscribers WHERE subscriber_id = ? AND nren_id = ?", array('text', 'text'), array($id, $nren_id)); Logger::logEvent(LOG_INFO, "NRENAdmin", "delSubscriber()", "Deleted subscriber with ID {$id}.\n"); $msg = $this->translateTag('l10n_suc_deletesubs1', 'nrenadmin') . htmlentities($subscriberName) . $this->translateTag('l10n_suc_deletesubs2', 'nrenadmin') . " " . htmlentities($id) . ". " . $this->translateTag('l10n_suc_deletesubs3', 'nrenadmin') . " " . $count . " " . $this->translateTag('l10n_suc_deletesubs4', 'nrenadmin'); Framework::success_output($msg); }
private function getRobotCert($serial) { $query = "SELECT * FROM robot_certs where subscriber_id=? AND serial=?"; $params = array('text', 'text'); $data = array($this->person->getSubscriber()->getDBID(), $serial); try { $res = MDB2Wrapper::execute($query, $params, $data); if (count($res) != 1) { return null; } return $res[0]; } catch (Exception $e) { Framework::error_output("Could not find cert. Server said: " . htmlentities($e->getMessage())); return null; } return null; }
static function sanitizeText($input) { if (!isset($input) || empty($input)) { return null; } if (is_array($input)) { foreach ($input as $var => $val) { $output[$var] = Input::sanitizeText($val); } } $input = stripslashes($input); /* in text is feasible to want newlines, to format the appearance of the * text. Since it is undesired to directly insert newlines into the DB * convert them to <br /> tags. Direct HTML insertion has been dealt * with using htmlentities*/ /* allow <br /> tags with strip_tags, otherwise the <br />'s you insert * here will be stripped the next time the text is sanitized! */ $input = strtr(strip_tags($input, '<br>'), array("\n" => '<br />', "\r\n" => '<br />')); /* The following is a *HACK* * However, since we want to use the mysql_real_escape_string, * we have to make sure that the database has been * contacted. *sigh* * * Note that this *may* throw an exception from the database. */ if (!Input::$bootstrapped) { MDB2Wrapper::execute("SELECT current_timestamp()", null, null); Input::$bootstrapped = true; } /* Escape the string */ $output = mysql_real_escape_string($input); return $output; }
/** * Check if key $auth_key is an order-number or an authvar. * If it is an authvar, retrieve the associated order-number from the DB. * * @throws ConfusaGenException */ private function transformToOrderNumber($auth_key) { /* first check if it is an order number already */ if (is_numeric($auth_key)) { /* if it is numeric, chances are quite high that we have an order number. * at the same time this is the only formal restriction we have for an order number. */ return $auth_key; } else { if (strlen($auth_key) == ConfusaConstants::$AUTH_KEY_LENGTH) { $res = MDB2Wrapper::execute("SELECT order_number FROM order_store WHERE auth_key=? AND owner=?", array('text', 'text'), array($auth_key, $this->person->getEPPN())); if (count($res) < 1) { throw new DBQueryException("Could not find order number for {$auth_key} " . "and " . $this->person->getEPPN() . " in order_store"); } return $res[0]['order_number']; } else { throw new ConfusaGenException("Auth_var format not recognized!"); } } }
/** * Get the list of IdPs stored in the DB for this NREN. * * @param void * @return array|null an array with all IdP URLs or null if not found * @access public */ public function getIdPList() { $query = "SELECT m.idp_url FROM idp_map m " . "WHERE m.nren_id = ?"; try { $res = MDB2Wrapper::execute($query, array('text'), array($this->getID())); } catch (ConfusaGenException $cge) { Logger::log_event(LOG_NOTICE, __FILE__ . " " . __LINE__ . ": Could not " . "get the IdP list for NREN with ID " . $this->getID() . ". All IdP scoping will fail!"); } if (count($res) > 0) { $idpList = array(); foreach ($res as $row) { $idpList[] = $row['idp_url']; } } else { return null; } return $idpList; }
/** * getFromQuery() run the query and create a new NREN * * @param String $query the query * @param Array $params * @param Array $data * @access private */ private function getFromQuery($query, $params, $data) { try { $res = MDB2Wrapper::execute($query, $params, $data); if (count($res) == 0) { return false; } /* loop through the resultset and return an NREN for * the first entry with idp_url. * * If we get multiple hits, there's no way we can adapt * to this, so we default to _the_first_valid_entry_ */ foreach ($res as $key => $r) { if (array_key_exists('idp_url', $r)) { return new NREN($r['idp_url']); } } } catch (DBStatementException $dbse) { Logger::log_event(LOG_ALERT, __FILE__ . ":" . __LINE__ . " problem with db-statement when finding NREN. " . $dbse->getMessage()); } catch (DBQueryException $dbqe) { Logger::log_event(LOG_ALERT, __FILE__ . ":" . __LINE__ . " Query-error when finding NREN. " . $dbqe->getMessage()); } return false; }
/** * Get the owner DN and the organization name for the certificate associated * with key $key. * * @param $key mixed The key for which the certificate is to be retrieved * @return array containing owner DN and organization name * * @throws DBQueryException If something went wrong with the query * @throws DBStatementException If the SQL configuration is wrong */ public function getCertInformation($key) { $query = "SELECT cert_owner, organization FROM cert_cache WHERE auth_key=?"; $res = MDB2Wrapper::execute($query, array('text'), array($key)); if (count($res) == 1) { return $res[0]; } }
/** * getCertFromDB() take the registred Certificate and find a match in * the DB * * Robot_Certificates are used for authenticating remote * clients. Therefore, we will *always* start the object with a * certificate. * * The authN-mechanism lies in whether or not the certicate is also * present in the database. * * @param Boolean $db_authoriative the values in the database is * authorative (overwrite local values if * present). * @return Boolean flag indicating if the certificate was found and * it matches the current @access private */ private function getCertFromDB($db_authorative = false) { $fp = $this->getFingerprint(); if (!$fp) { return false; } try { $query = "SELECT * FROM robot_certs WHERE fingerprint=?"; $res = MDB2Wrapper::execute($query, array('text'), array($fp)); if (count($res) == 1) { if ($res[0]['cert'] == $this->getPEMContent()) { if ($db_authorative) { $this->db_id = Input::sanitize($res[0]['id']); $this->owner = Input::sanitize($res[0]['uploaded_by']); $this->subscriber = Input::sanitize($res[0]['subscriber_id']); $this->lwsent = Input::sanitize($res[0]['last_warning_sent']); $this->uploaded_date = Input::sanitize($res[0]['uploaded_date']); } return true; } } return false; } catch (DBStatementException $dbse) { Logger::log_event(LOG_NOTICE, "Corrupted statement in query (" . __FILE__ . ":" . __LINE__ . " " . $dbse->getMessage()); } catch (DBQueryException $dbqe) { Logger::log_event(LOG_NOTICE, "Corrupted content in query (" . __FILE__ . ":" . __LINE__ . " " . $dbqe->getMessage()); } return false; }
private function getNRENTexts($nren) { $sample_text = "h4. A heading\n\nMake a *strong* point on something\n\n"; $sample_text .= "_Emphasize_ a point, -invalidate it-, +insert replacement+\n\n"; $sample_text .= "* Enumerate\n"; $sample_text .= "* all the\n"; $sample_text .= "* advantages\n"; $sample_text .= "# list-items\n"; $sample_text .= "## and even subadvantages\n\n\n"; $sample_text .= "|ung|äldre|äldst|\n"; $sample_text .= "|barn|mor|mormor|\n"; $sample_text .= "|tables|are|nice|\n\n"; $sample_text .= "Appear smart, use footnotes[1]\n\n"; $sample_text .= "\"Present a link\":http://beta.confusa.org\n\n"; $sample_text .= "fn1. Roddenberry, G.: Where no man has gone before\n"; $query = "SELECT help, about, privacy_notice FROM nrens WHERE name=?"; $res = NULL; try { $res = MDB2Wrapper::execute($query, array('text'), array($nren)); } catch (DBStatementException $dbse) { Framework::error_output("Problem looking up the NREN about-, help- and " . "privacy-notice-texts in the DB. " . "Looks like a server problem, contact an administrator. " . "Server said " . htmlentities($dbse->getMessage())); return NULL; } catch (DBQueryException $dbqe) { Framework::error_output("Problem looking up the NREN about-, help- and " . "privacy-notice-texts in the DB. " . "Looks like a problem with the supplied data. " . "Server said " . htmlentities($dbqe->getMessage())); return NULL; } if (count($res) === 1) { $result = array(); if (is_null($res[0]['help'])) { $result[0] = $sample_text; } else { $result[0] = Input::br2nl(stripslashes($res[0]['help'])); } if (is_null($res[0]['about']) || empty($res[0]['about'])) { $result[1] = $sample_text; } else { $result[1] = Input::br2nl(stripslashes($res[0]['about'])); } if (is_null($res[0]['privacy_notice']) || empty($res[0]['privacy_notice'])) { $result[2] = $sample_text; } else { $result[2] = Input::br2nl(stripslashes($res[0]['privacy_notice'])); } return $result; } else { if (count($res) > 1) { /* conflict!! */ Framework::error_output("More than one pair of about and help texts in the DB." . "Please contact an administrator to resolve this!"); return NULL; } } }
/** * MDB2Wrapper::testColumn() * * Test if a column is part of the schema. * In some settings, this is a useful feature, especially when the schema * changes over time. * * @param String $table name of table * @param String $column column to look for * @return Boolean * @access public */ public static function testColumn($table = null, $column = null) { if (is_null($table) || is_null($column)) { return False; } $query = "SHOW COLUMNS FROM {$table} LIKE '{$column}'"; try { $res = MDB2Wrapper::execute($query, NULL, NULL); return count($res) > 0; } catch (DBQueryException $dqe) { Logger::log_event(LOG_INFO, "Error when looking for {$column} in table {$table}\n"); } catch (DBStatementException $dse) { Logger::log_event(LOG_INFO, "Error when looking for {$column} in table {$table}\n"); } return false; }
function getAccountsForNREN($nren_id) { $q = "SELECT * FROM account_map WHERE nren_id=?"; return MDB2Wrapper::execute($q, array('integer'), array($nren_id)); }
/** * try to grap the account_map_id from the old schema. */ private function readDeprecatedSchema($nren_id) { /* test if nren_id is in table */ if (MDB2Wrapper::testColumn('account_map', 'nren_id') === true) { try { $res = MDB2Wrapper::execute("SELECT count(*) as count FROM account_map WHERE nren_id = ?", array('integer'), array($nren_id)); } catch (Exception $e) { /* doesn't really matter, this is best-effort only */ Logger::log_event(LOG_NOTICE, "Could not get nren_id from account_map, error: " . $e->getMessage()); return false; } $num = $res[0]['count'] . "\n"; try { $res = MDB2Wrapper::execute("SELECT * FROM account_map WHERE nren_id = ?", array('integer'), array($nren_id)); } catch (Exception $e) { /* doesn't really matter, this is best-effort only */ Logger::log_event(LOG_NOTICE, "Could not get accounts from account_map, error: " . $e->getMessage()); return false; } return $this->parseAccountData($res, 0); } }
/** * Guess the "best" language for a user. This should be called whenever a * decorated person object is availabe. * The "best" language is determined by the following order of steps: * * 1.) If there is already a language set (this->language) take that one. * Thus the language settings can be functionaly overriden, e.g. in * the framework. * 2.) The language stored in the cookie of the user dominates over everything else * Thus, manually changing the language only means setting a cookie. * 3.) Try to take the language set by the subscriber, if the user is logged in * 4.) If the subscriber-language is NULL, take the language set by the NREN, * if the user is logged in * 5.) If the user is not logged in and no session variable is set, take the * first available language from the user's language accept-headers * 6.) If none of the languages in the user's accept header is available, * take the default language of the Confusa instance (usually but not necessarily English) * * @param $person Person-oject (Decorated) Person, from the subscriber or * NREN of which translator can deduce the * best language * @return void */ public function guessBestLanguage($person) { if ($this->languageOverridden) { return; } if (isset($_COOKIE['language'])) { $cookielang = Input::sanitizeLangCode($_COOKIE['language']); $this->language = $cookielang; return; } if ($person->isAuth()) { if (!is_null($person->getSubscriber())) { try { $query = "SELECT lang FROM subscribers WHERE name=?"; $res = MDB2Wrapper::execute($query, array('text'), array($person->getSubscriber()->getIdPName())); if (isset($res[0]['lang'])) { setCookie('language', $res[0]['lang']); $this->language = $res[0]['lang']; return; } $query = "SELECT lang FROM nrens WHERE name=?"; $res = MDB2Wrapper::execute($query, array('text'), array($person->getNREN())); if (isset($res[0]['lang'])) { setCookie('language', $res[0]['lang']); $this->language = $res[0]['lang']; return; } } catch (DBQueryException $dbqe) { Logger::log_event(LOG_WARNING, "Could not query subscriber/NREN default language. " . "Falling back to system language default! " . $dbqe->getMessage()); } catch (DBStatementException $dbse) { Logger::log_event(LOG_WARNING, "Could not query subscriber/NREN default language. " . "Falling back to system default! " . $dbse->getMessage()); } } } $sspdir = Config::get_config('simplesaml_path'); /* turn off warnings to keep the page header tidy */ $level = error_reporting(E_ERROR); /* poll the accept languages only, if we can load simplesamlphp * simplesamlphp *should* always be enabled (otherwise no authN :)), * But there can be configurations in bypass auth-mode without a working * simplesamlphp instance */ if (file_exists($sspdir . "/lib/_autoload.php")) { require_once $sspdir . '/lib/_autoload.php'; $accept_languages = SimpleSAML_Utilities::getAcceptLanguage(); $available_languages = Config::get_config('language.available'); if (empty($accept_languages)) { Logger::log_event(LOG_DEBUG, "Simplesamlphp instance seems to be not " . "configured, or not configured properly. Translator " . "will not use the browser's accept-header to determine " . "language settings."); } foreach ($accept_languages as $key => $value) { if (array_search($key, $available_languages) === FALSE) { continue; } else { $this->language = $key; return; } } } /* turn on warnings again */ error_reporting($level); $this->language = $this->defaultLanguage; return; }
function get_csr_from_db_raw($eppn, $auth_key) { $csr_res = MDB2Wrapper::execute("SELECT * FROM csr_cache WHERE auth_key=? AND common_name=?", array('text', 'text'), array($auth_key, $eppn)); $size = count($csr_res); switch ($size) { case 0: throw new CSRNotFoundException("CSR with token {$auth_key} not found for {$eppn}"); case 1: return $csr_res[0]; } throw new ConfusaGenException("Too many CSRs found in the database with token {$auth_token}"); }
/** * Return if this person may request a new certificate. This is dependant * on a few conditions: * - person is fully decorated * - 'confusa' entitlement is set * - subscriber of the person is in state 'subscribed' * * @return permission object containing * permissionGranted true/false based on whether the permission was granted * reasons array with reasons for granting/rejecting the permissions */ public function mayRequestCertificate() { $permission = new Permission(); $permission->setPermission(true); $translator = new Translator(); $translator->guessBestLanguage($this); if (empty($this->eppn)) { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_reas_malfeppn', 'reasons')); } if (empty($this->given_name)) { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_reas_nogivenname', 'reasons')); } if (empty($this->email)) { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_reas_noemailaddr', 'reasons')); } if (is_null($this->getNREN()->getCountry()) || $this->getNREN()->getCountry() == "") { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_reas_nocountryname', 'reasons')); } $subscriberOrgName = $this->subscriber->getOrgName(); if (empty($subscriberOrgName)) { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_reas_malfsubsname', 'reasons')); } if (Config::get_config('capi_test') && Config::get_config('ca_mode') === CA_COMODO && $subscriberOrgName == ConfusaConstants::$CAPI_TEST_O_PREFIX) { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_reas_malfsubsname', 'reasons')); } if (empty($this->entitlement) || !$this->testEntitlementAttribute(Config::get_config('entitlement_user'))) { $permission->setPermission(false); $permission->addReason(Config::get_config('entitlement_user') . " " . $translator->getTextForTag('l10n_reas_noentitlement', 'reasons')); } $query = "SELECT org_state FROM subscribers WHERE name=?"; /* Bubble up exceptions */ $res = MDB2Wrapper::execute($query, array('text'), array($this->subscriber->getIdPName())); if (count($res) == 0) { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_instunkn1', 'reasons') . " " . $this->subscriber->getIdPName() . " " . $translator->getTextForTag('l10n_instunkn2', 'reasons')); return $permission; } else { if (count($res) > 1) { throw new CGE_AuthException("More than one DB-entry with same subscriberOrgName " . $this->subscriber->getOrgName()); } } if ($res[0]['org_state'] !== 'subscribed') { $permission->setPermission(false); $permission->addReason($translator->getTextForTag('l10n_instnsubscr1', 'reasons') . " " . $this->subscriber->getIdPName() . " " . $translator->getTextForTag('l10n_instnsubscr2', 'reasons')); } return $permission; }
/** * getSubscriberByIO() find a subscriber in the database and decoraate a * Subscriber-object * * @param int $id the db-id for the subscriber * @param NREN $nren * @return Subscriber|null * @access public */ static function getSubscriberByID($id, $nren) { if (is_null($nren)) { return null; } if (is_null($id)) { return null; } try { $res = MDB2Wrapper::execute("SELECT name FROM subscribers WHERE subscriber_id=?", array('text'), array(Input::sanitizeText($id))); } catch (ConfusaGenException $cge) { echo $cge->getMessage(); return null; } if (count($res) != 1) { echo "wrong count"; return null; } return new Subscriber($res[0]['name'], $nren); }
private function deleteAdmin($admin, $level) { /* does the current user have the rights? */ try { $query = "SELECT a.* FROM admins a LEFT JOIN nrens n on n.nren_id = a.nren"; $query .= " WHERE (a.admin=? OR a.admin=?) AND n.name=?"; $res = MDB2Wrapper::execute($query, array('text', 'text', 'text'), array($admin, $this->person->getEPPN(), $this->person->getNREN())); switch (count($res)) { case 0: Framework::error_output("Did not find neither the admin to delete or the current admin in the database. Cannot continue."); return; case 1: if ($res[0]['admin'] != $admin) { Framework::error_output("Cannot find the admin to delete in the admins-table. Cannot continue."); return; } break; case 2: $id = 0; if ($res[1]['admin'] == $admin) { $id = 1; } $nrenID = $res[$id]['nren']; $subscriberID = $res[$id]['subscriber']; break; default: Framework::error_output("Too many hits in the database. Cannot decide where to go from here."); return; } } catch (DBStatementException $dbse) { $msg = "Cannot find id-values in the database due to server problems. Server said: " . htmlentities($dbse->getMessage()); Framework::error_output($msg); return; } catch (DBQueryException $dbqe) { $msg = "Cannot find id-values due to data inconsistency. Server said: " . htmlentities($dbqe->getMessage()); Framework::error_output($msg); return; } /* Find the admin-level of both admins and make sure that the * enforcer (the admin performing the deletion) has the rights * to do so. */ if ($res[0]['admin'] == $admin) { $targetLevel = (int) $res[0]['admin_level']; $enforcerLevel = (int) $res[1]['admin_level']; } else { $targetLevel = (int) $res[1]['admin_level']; $enforcerLevel = (int) $res[0]['admin_level']; } if ($enforcerLevel < $targetLevel) { Framework::error_output("Cannot delete admin with higher admin-level."); return; } if ($targetLevel == NREN_ADMIN) { $query = "DELETE FROM admins WHERE admin=? AND nren=?"; $params = array('text', 'text'); $data = array($admin, $nrenID); } else { $query = "DELETE FROM admins WHERE admin=? AND nren=? AND subscriber=?"; $params = array('text', 'text', 'text'); $data = array($admin, $nrenID, $subscriberID); } try { MDB2Wrapper::update($query, $params, $data); Logger::log_event(LOG_INFO, "Successfully deleted admin {$admin} with level {$targetLevel}"); } catch (DBStatementException $dbse) { Framework::error_output("Could not delete the admin because the statement was bad " . "Please contact an administrator. Server said " . htmlentities($dbse->getMessage())); Logger::log_event(LOG_NOTICE, __FILE__ . ":" . __LINE__ . ": Problem occured when trying to delete " . "admin {$admin} with level {$level}: " . $dbse->getMessage()); } catch (DBQueryException $dbqe) { Framework::error_output("Could not delete the admin because of problems with the " . "received data. Server said " . htmlentities($dbqe->getMessage())); Logger::log_event(LOG_INFO, __FILE__ . ":" . __LINE__ . ": Problem occured when tyring to delete " . "admin {$admin} with level {$level}: " . $dbqe->getMessage()); } Framework::success_output($this->translateTag('l10n_suc_deleteadm1', 'admin') . " " . htmlentities($admin)); }
/** getCountriesIdP() return all countries and IdP present in the database * * @params void * @return array list of available countries with corresponding IdP(s) * @access private */ private function getCountriesIdP() { if (isset($this->cidp)) { return $this->cidp; } try { $res = MDB2Wrapper::execute("SELECT idp_url, country, name FROM nrens n " . "LEFT JOIN idp_map im ON n.nren_id = im.nren_id", NULL, NULL); } catch (ConfusaGenException $cge) { Logger::log_event(LOG_WARNING, "Could not get IdP-URLs from the database, " . "make sure DB-connection is properly configured\n"); Framework::error_output($this->translateTag('l10n_err_db_select', 'disco')); return array(); } $this->cidp = array(); foreach ($res as $key => $value) { if (!isset($this->cidp[$value['country']])) { $this->cidp[$value['country']] = array(); } $this->cidp[$value['country']][] = $value['idp_url']; } return $res; }
/** * createAdminPerson() Create a person-object based on the certificate * credentials passed via the client certificate. * * Ideally, this should be done via Confusa_Auth, however, since we do not have * a live Feide-session, but are basing the authetnication on an X.509 * certificate, the case is a corner, thus we do it here. * * @return Person|NULL the decorated person or NULL if the creation failed. */ function createAdminPerson() { global $log_error_code; /* * Try to find the certificate in the robot_certs-table. If we have a * match, we have a legit user and create a proxy-admin. * * If the query fails for some reason, we jumb out, returning null */ $fingerprint = openssl_x509_fingerprint($_SERVER['SSL_CLIENT_CERT'], true); if (is_null($fingerprint)) { return null; } try { $cert_res = MDB2Wrapper::execute("SELECT * FROM robot_certs WHERE fingerprint = ?", array('text'), array(trim($fingerprint))); } catch (DBStatementException $dbse) { Logger::log_event(LOG_NOTICE, "[RI] ({$log_error_code}) (line: " . __LINE__ . ")Error with syntax for robot_certs-query.(" . $dbse->getMessage() . ")"); return null; } catch (DBQueryException $dbqe) { Logger::log_event(LOG_NOTICE, "[RI] ({$log_error_code}) Error with params (line (" . __LINE__ . ") in robot_certs-query.(" . $dbqe->getMessage() . ")"); return null; } switch (count($cert_res)) { case 0: Logger::log_event(LOG_NOTICE, "[RI] ({$log_error_code}): Unauthenticated client connected. Refusing to establish connection. " . $_SERVER['SSL_CLIENT_I_DN']); echo "[{$log_error_code}] You are not authorized to use this API. This incident has been logged.\n"; return null; case 1: /* * We have to do the compare in a rather awkward way to ensure * that differences in spaces, newlines, tabs and whatnot are * removed. */ openssl_x509_export(openssl_x509_read($_SERVER['SSL_CLIENT_CERT']), $stored_admin_dump); openssl_x509_export(openssl_x509_read($cert_res[0]['cert']), $stored_client_dump); if ($stored_admin_dump != $stored_client_dump) { Logger::log_event(LOG_NOTICE, "[RI] ({$log_error_code}) Got matching fingerprint ({$fingerprint}) " . "but actual certificates differ! Aborting"); echo "[{$code}] There were issues with your certificate. Cannot continue using this cert.\n"; echo "Please use another certificate for the time being.\n"; echo "This event has been logged.\n"; return null; } break; default: Logger::log_event(LOG_ALERT, "[RI] ({$log_error_code}) Several certs (" . count($cert_res) . ") in DB matching fingerprint ({$fingerprint}), cannot auth client."); return null; } /* * Get the details for the owner of the certificate, use this as a * basis for authenticating the person. * * It does not really matter which IdP-map we use, as long as we get one * that points to the correct NREN. This is probably not the 'correct' * way of using the idp_map, but atm, this is the only 'correct' way of * decorating the NREN-object. */ try { /* get admin */ $ares = MDB2Wrapper::execute("SELECT * FROM admins WHERE admin_id=?", array('text'), array($cert_res[0]['uploaded_by'])); if (count($ares) != 1) { /* no admin found. This should not be possible, but be * safe and test nevertheless */ return null; } /* get Subscriber */ $sres = MDB2Wrapper::execute("SELECT * FROM subscribers WHERE subscriber_id=?", array('text'), array($cert_res[0]['subscriber_id'])); if (count($sres) != 1) { /* No subscriber found */ return null; } /* get NREN */ $nres = MDB2Wrapper::execute("SELECT n.*,im.idp_url FROM nrens n LEFT JOIN idp_map im ON im.nren_id = n.nren_id WHERE n.nren_id=?", array('text'), array($sres[0]['nren_id'])); if (count($nres) < 1) { /* No nrens found at all, which means that the * subscriber is bogus. Since this is a foreign-key * constraint, we've run into a corrupt db. Let's hope * this'll never happen :-) */ Logger::log_event(LOG_EMERG, "Found subscriber (" . $sres[0]['subscriber_id'] . ":" . $sres[0]['name'] . ") without a corresponding NREN (" . $sres[0]['nren_id'] . "), you have a corrupt database"); } } catch (DBStatementException $dbse) { $msg = "[{$log_error_code}] Problem executing query. Is the database-schema outdated?. "; Logger::log_event(LOG_INFO, $msg . " Server said: " . $dbse->getMessage()); echo $msg . "<br />\nServer said: " . htmlentities($dbse->getMessage()) . "<br />\n"; return null; } catch (DBQueryException $dbqe) { /* FIXME */ $msg = "Could not find owner-details for certificate, probably issues with supplied data. "; $msg .= "Admin_id: " . htmlentities($cert_res[0]['uploaded_by']); Logger::log_event(LOG_INFO, $msg . " Server said: " . $dbqe->getMessage()); echo $msg . "<br />\nServer said: " . htmlentities($dbqe->getMessage()) . "<br />\n"; return null; } /* * Decorate person. */ $person = new Person(); if (isset($ares[0]['admin_name']) && $ares[0]['admin_name'] != "") { $person->setName($ares[0]['admin_name']); } else { $person->setName($ares[0]['admin']); } try { $person->setEPPN($ares[0]['admin']); } catch (CGE_CriticalAttributeException $cae) { echo "[{$log_error_code}] Problems with setting the unique identifier for robot-admin.<br />\n"; echo "Check the data in admins (admin_id: " . htmlentities($cert_res[0]['uploaded_by']) . ")<br />\n"; Logger::log_event(LOG_NOTICE, "[RI] ({$log_error_code}) Internal error? Suddenly provided admin-uid is not available."); return null; } $person->setAuth(true); $person->setNREN(new NREN($nres[0]['idp_url'])); $person->setSubscriber(new Subscriber($sres[0]['name'], $person->getNREN())); $person->setName($ares[0]['admin_name']); $person->setEmail($ares[0]['admin_email']); /* Robot authenticated, we can return the person and live happily ever * after */ Logger::log_event(LOG_NOTICE, "[RI]: Authenticated robot-client via cert {$fingerprint} belonging to " . $person->getEPPN()); return $person; }
/** * listPErsonCSRs() get a list of a person's CSRs * * This will *not* return the CSRs, but the data stored around the * CSRs. From this, it is trivial to retrieve the data from the * database. * * Data stored in the array: * * - csr_id The ID in the database. * - uploaded_date when the CSR was uploaded * - common_name Owner of the CSR * - auth_key Hash of the pubkey, used to retrieve a specific CSR * - from_ip The IP that sent the CSR. * * @param String the x509Name stored as common-name in csr_cache * @return Array of CSR entries. * @access public * @static */ static function listPersonCSRs($x509Name) { $query = "SELECT csr_id, uploaded_date, common_name, auth_key, from_ip" . " FROM csr_cache WHERE common_name=:cn ORDER BY uploaded_date"; try { $res = MDB2Wrapper::execute($query, null, array('cn' => $x509Name)); } catch (DBStatementException $dbse) { Logger::log_event(LOG_WARNING, __FILE__ . ":" . __LINE__ . "cannot retrieve CSR from DB. Server said: " . $dbse->getMessage()); return false; } catch (DBQueryException $dbqe) { Logger::log_event(LOG_WARNING, __FILE__ . ":" . __LINE__ . "cannot retrieve CSR from DB. Server said: " . $dbse->getMessage()); return false; } return $res; }