Ejemplo n.º 1
0
 public function pre_process($person)
 {
     parent::pre_process($person);
     $res = false;
     if ($this->person->isAuth()) {
         if (isset($_GET['file_cert'])) {
             $authKey = Input::sanitizeCertKey($_GET['file_cert']);
             try {
                 $cert = $this->ca->getCert($authKey);
                 if (isset($cert) && $cert->isValid()) {
                     include 'file_download.php';
                     download_file($cert->getPEMContent(), 'usercert.pem');
                     exit(0);
                 }
             } catch (ConfusaGenException $cge) {
                 Framework::error_output($this->translateMessageTag('downl_err_nodownload') . " " . htmlentities($cge->getMessage()));
             }
         } else {
             if (isset($_GET['cert_status'])) {
                 $this->pollCertStatusAJAX(Input::sanitizeCertKey($_GET['cert_status']));
             } else {
                 if (isset($_GET['certlist_all'])) {
                     $this->showAll = $_GET['certlist_all'] == "true";
                 } else {
                     if (isset($_GET['revoke']) && $_GET['revoke'] == 'revoke_single') {
                         $order_number = Input::sanitizeCertKey($_GET['order_number']);
                         /* sanitized by checking inclusion in the REVOCATION_REASONS
                          * array
                          */
                         if (!array_key_exists('reason', $_GET)) {
                             Framework::error_output($this->translateMessageTag('rev_err_singlenoreason'));
                             return;
                         }
                         $reason = Input::sanitizeText(trim($_GET['reason']));
                         try {
                             if (!isset($order_number) || !isset($reason)) {
                                 Framework::error_output("Revoke Certificate: Errors with parameters, not set properly");
                             } elseif (!$this->checkRevocationPermissions($order_number)) {
                                 Framework::error_output($this->translateMessageTag('rev_err_singlenoperm'));
                             } elseif (!$this->ca->revokeCert($order_number, $reason)) {
                                 Framework::error_output($this->translateMessageTag('rev_err_notyet1') . htmlentities($order_number) . $this->translateMessageTag('rev_err_notyet2') . htmlentities($reason));
                             } else {
                                 Framework::message_output($this->translateMessageTag('rev_suc_single1') . htmlentities($order_number) . $this->translateMessageTag('rev_suc_single2'));
                                 if (Config::get_config('ca_mode') === CA_COMODO && Config::get_config('capi_test') === true) {
                                     Framework::message_output($this->translateTag('l10n_msg_revsim1', 'revocation'));
                                 }
                             }
                         } catch (ConfusaGenException $cge) {
                             Framework::error_output($this->translateMessageTag('rev_err_singleunspec') . " " . htmlentities($cge->getMessage()));
                         }
                     }
                 }
             }
         }
     }
     return false;
 }
Ejemplo n.º 2
0
function confusaErrorHandler($errno, $errstr, $errfile, $errline)
{
    $msg = "";
    $display_errors = ini_get('display_errors') == true || ini_get('display_errors') == "stdout";
    switch ($errno) {
        case E_ERROR:
        case E_USER_ERROR:
            $msg = "PHP Fatal Error: {$errstr} in {$errfile} on line {$errline}";
            if ($display_errors) {
                Framework::error_output($msg);
            }
            break;
        case E_WARNING:
        case E_USER_WARNING:
            $msg = "PHP Warning: {$errstr} in {$errfile} on line {$errline}";
            if ($display_errors) {
                Framework::warning_output($msg);
            }
            break;
        case E_NOTICE:
        case E_USER_NOTICE:
            $msg = "PHP Notice: {$errstr} in {$errfile} on line {$errline}";
            if ($display_errors) {
                Framework::message_output($msg);
            }
            break;
        case E_STRICT:
            $msg = "PHP Strict: {$errstr} in {$errfile} on line {$errline}";
            break;
        default:
            $msg = "PHP Unknown: {$errstr} in {$errfile} on line {$errline}";
            if ($display_errors) {
                Framework::message_output($msg);
            }
            break;
    }
    /* if logging is turned on, log the errors to the respective PHP log */
    if (ini_get('log_errors') && error_reporting() & $errno) {
        error_log($msg);
    }
    return true;
}
Ejemplo n.º 3
0
 public function pre_process($person)
 {
     $res = true;
     $this->setPerson($person);
     $this->account = NRENAccount::get($this->person);
     /* If the caller is not a nren-admin or Confusa is not in online mode, we stop here */
     if (!$this->person->isNRENAdmin() || Config::get_config('ca_mode') != CA_COMODO) {
         return false;
     }
     $login_name = false;
     $password = false;
     $ap_name = false;
     if (isset($_POST['account']) && $_POST['account'] === 'edit') {
         /* We must use POST as we may pass along a password and
          * we do not want to set that statically in the subject-line. */
         if (isset($_POST['login_name'])) {
             $ln = $_POST['login_name'];
             $login_name = Input::sanitizeText(htmlspecialchars($ln));
             if ($ln === $login_name) {
                 $this->account->setLoginName($login_name);
                 $res = false;
             } else {
                 /* FIXME: l10n */
                 Framework::error_output("The new login_name contains illegal characters, dropping new login!");
             }
         }
         /* Do not sanitize password, we should allow special characters and
          * stuff, we should url-encode it. If Comodo does not sanitize
          * their password, it's their business, not ours. */
         if (isset($_POST['password']) && $_POST['password'] !== "") {
             $this->account->setPassword($_POST['password']);
         }
         if (isset($_POST['ap_name'])) {
             $ap = $_POST['ap_name'];
             $ap_name = Input::sanitizeText(htmlspecialchars($ap));
             if ($ap === $ap_name) {
                 $this->account->setAPName($ap_name);
             } else {
                 /* FIXME: l10n */
                 Framework::error_output("Cleaned ap-name and it contains illegal characters, dropping new name!");
                 $res = false;
             }
         }
         /* should we validate? */
         try {
             $validate = false;
             if (isset($_POST['verify_ca_cred']) && $_POST['verify_ca_cred'] === "yes") {
                 $validate = true;
             }
             if ($this->account->save($validate)) {
                 /* FIXME: l10n */
                 Framework::success_output("CA Account details successfully updated!");
             } else {
                 Framework::message_output("No changes to account-details, not updating.");
             }
         } catch (ConfusaGenException $cge) {
             /* FIXME: l10n */
             Framework::error_output("Could not update account-data: " . $cge->getMessage());
         }
     }
     parent::pre_process($person);
     return $res;
 }
Ejemplo n.º 4
0
 /**
  * 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);
 }
Ejemplo n.º 5
0
 /**
  * Retrieve a certificate from a remote endpoint (e.g. Comodo).
  *
  * @params	key	either an order-number that can be used to retrieve a
  *			certificate directly or an auth-key with which we can
  *			retrieve the order-number
  * @param	key	The order-number or an auth_key that can be transformed
  *			to order_number.
  * @access	public
  * @throws ConfusaGenException
  */
 public function getCert($key)
 {
     $key = $this->transformToOrderNumber($key);
     Logger::log_event(LOG_DEBUG, "Trying to retrieve certificate with order number " . $key . " from the Comodo collect API. " . $this->owner_string);
     $collect_endpoint = ConfusaConstants::$CAPI_COLLECT_ENDPOINT . "?loginName=" . $this->account->getLoginName() . "&loginPassword="******"&orderNumber=" . $key . "&queryType=2" . "&responseMimeType=application/x-x509-user-cert";
     $data = CurlWrapper::curlContact($collect_endpoint);
     $STATUS_PEND = "0";
     $STATUS_OK = "2";
     /* Parse the status response from the remote API
      */
     $status = substr($data, 0, 1);
     $cert = false;
     switch ($status) {
         case $STATUS_OK:
             $cert = new Certificate(substr($data, 2));
             break;
         case $STATUS_PEND:
             Framework::message_output("The certificate is being processed and is not yet available");
             return null;
         default:
             /* extract the error status code which is longer than one character */
             $error_parts = explode("\n", $data, 2);
             /* potential error: response does not contain status code */
             if (is_numeric($error_parts[0])) {
                 $msg = $this->capiErrorMessage($error_parts[0], $error_parts[1]);
                 throw new CGE_ComodoAPIException("Received error message {$data} {$msg}\n");
             } else {
                 $msg = "Received an unexpected response from the remote API!n" . "Maybe Confusa is not properly configured?\n";
                 throw new CGE_ComodoAPIException($msg);
             }
     }
     return $cert;
 }
Ejemplo n.º 6
0
 private function resetNRENMailTpl($nren)
 {
     $tpl_file = Config::get_config('custom_mail_tpl') . $nren . '/custom.tpl';
     if (file_exists($tpl_file)) {
         $success = unlink($tpl_file);
         if ($success === false) {
             Framework::error_output("Could not reset the notification mail template!" . "Please contact an IT-administrator.");
         }
     }
     Framework::message_output($this->translateTag('l10n_suc_mailreset', 'stylist'));
 }
Ejemplo n.º 7
0
 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);
     }
 }
Ejemplo n.º 8
0
 /**
  * Revoke a list of certificates possibly belonging to more than one end-entity
  * based on an array of auth_keys stored in the session. Based on the number of
  * certificates that are going to be revoked, this may take some time.
  *
  * @param string $reason The reason for revocation (as in RFC 3280)
  *
  */
 private function revoke_list($reason)
 {
     if (Config::get_config('ca_mode') === CA_COMODO && Config::get_config('capi_test') === true) {
         Framework::message_output($this->translateTag('l10n_msg_revsim1', 'revocation'));
     }
     $auth_keys = CS::getSessionKey('auth_keys');
     CS::deleteSessionKey('auth_keys');
     if (is_null($auth_keys)) {
         Framework::error_output("Lost session! Please log-out of Confusa, " . "log-in again and try again!\n");
         return;
     }
     $num_certs = count($auth_keys);
     $num_certs_revoked = 0;
     Logger::log_event(LOG_INFO, "Trying to revoke {$num_certs} certificates." . "Administrator contacted us from " . $_SERVER['REMOTE_ADDR'] . " in a bulk (list) revocation request.");
     foreach ($auth_keys as $auth_key) {
         try {
             if (!$this->ca->revokeCert($auth_key, $reason)) {
                 Framework::error_output("Could not revoke certificate " . htmlentities($auth_key) . ".");
             } else {
                 $num_certs_revoked = $num_certs_revoked + 1;
             }
         } catch (ConfusaGenException $cge) {
             Framework::error_output($cge->getMessage());
         }
     }
     Logger::log_event(LOG_INFO, "Successfully revoked {$num_certs_revoked} certificates out of {$num_certs}. " . "Administrator contacted us from " . $_SERVER['REMOTE_ADDR'] . " in a bulk (list) revocation request.");
     Framework::message_output($this->translateTag('l10n_suc_revoke1', 'revocation') . " " . $num_certs_revoked . " " . $this->translateTag('l10n_suc_revoke2', 'revocation') . " " . $num_certs);
 }