allow to specify SSL CA certificates in LAM main configuration
This commit is contained in:
parent
442c3f5cc6
commit
90e01cbcaa
|
@ -1,4 +1,5 @@
|
||||||
September 2013 4.3
|
September 2013 4.3
|
||||||
|
- Custom SSL CA certificates can be setup in LAM main configuration
|
||||||
- LAM Pro:
|
- LAM Pro:
|
||||||
-> PPolicy: check password history for password reuse
|
-> PPolicy: check password history for password reuse
|
||||||
-> Custom fields: read-only fields for admin interface and file upload for binary data
|
-> Custom fields: read-only fields for admin interface and file upload for binary data
|
||||||
|
|
|
@ -80,6 +80,8 @@ $helpArray = array (
|
||||||
_("Example").
|
_("Example").
|
||||||
":</b><br><br>".
|
":</b><br><br>".
|
||||||
_("dc=yourcompany,dc=com")),
|
_("dc=yourcompany,dc=com")),
|
||||||
|
"204" => array ("Headline" => _("SSL certificate"),
|
||||||
|
"Text" => _("This is only needed for TLS/SSL connections. By default, LAM will use the certificate authorities installed on your system. If you have a private CA in your company you can upload your CA certificates here and override the system certificates.")),
|
||||||
"206" => array ("Headline" => _("List attributes"),
|
"206" => array ("Headline" => _("List attributes"),
|
||||||
"Text" => _("This is the list of attributes to show in the account list. The entries can either be predefined values, \"#attribute\", or individual ones, \"attribute:description\". Several entries are separated by semicolons.") .
|
"Text" => _("This is the list of attributes to show in the account list. The entries can either be predefined values, \"#attribute\", or individual ones, \"attribute:description\". Several entries are separated by semicolons.") .
|
||||||
"<br><br><br><big><b>" .
|
"<br><br><br><big><b>" .
|
||||||
|
|
|
@ -1077,4 +1077,39 @@ function getRandomNumber() {
|
||||||
return mt_rand();
|
return mt_rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the LDAP server and extracts the certificates.
|
||||||
|
*
|
||||||
|
* @param String $server server name
|
||||||
|
* @param String $port server port
|
||||||
|
* @return mixed false on error and certificate if extracted successfully
|
||||||
|
*/
|
||||||
|
function getLDAPSSLCertificate($server, $port) {
|
||||||
|
$stream = @stream_context_create(array("ssl" => array("capture_peer_cert_chain" => true)));
|
||||||
|
if (!$stream) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$client = @stream_socket_client('ssl://' . $server . ':' . $port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream);
|
||||||
|
if (!$client) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$context = stream_context_get_params($client);
|
||||||
|
if (!isset($context['options']['ssl']['peer_certificate_chain'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$finalPEM = '';
|
||||||
|
for ($i = 0; $i < sizeof($context['options']['ssl']['peer_certificate_chain']); $i++) {
|
||||||
|
$cert = $context['options']['ssl']['peer_certificate_chain'][$i];
|
||||||
|
$pemData = null;
|
||||||
|
$pemResult = @openssl_x509_export($cert, $pemData);
|
||||||
|
if ($pemResult) {
|
||||||
|
$finalPEM .= $pemData;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $finalPEM;
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -70,6 +70,10 @@ if (! function_exists('ldap_search')) {
|
||||||
if (! function_exists('gettext') || !function_exists('_')) {
|
if (! function_exists('gettext') || !function_exists('_')) {
|
||||||
$criticalErrors[] = array("ERROR", "Your PHP has no gettext support!", "Please install gettext for PHP.");
|
$criticalErrors[] = array("ERROR", "Your PHP has no gettext support!", "Please install gettext for PHP.");
|
||||||
}
|
}
|
||||||
|
// check if PHP has openssl support
|
||||||
|
if (! function_exists('openssl_x509_parse')) {
|
||||||
|
$criticalErrors[] = array("ERROR", "Your PHP has no openssl support!", "Please install openssl for PHP.");
|
||||||
|
}
|
||||||
// check if PHP has XML support
|
// check if PHP has XML support
|
||||||
if (! function_exists('utf8_decode')) {
|
if (! function_exists('utf8_decode')) {
|
||||||
$criticalErrors[] = array("ERROR", "Your PHP has no XML support!", "Please install the XML extension for PHP.");
|
$criticalErrors[] = array("ERROR", "Your PHP has no XML support!", "Please install the XML extension for PHP.");
|
||||||
|
|
|
@ -37,6 +37,20 @@ include_once("modules.inc");
|
||||||
/** Used to get type information. */
|
/** Used to get type information. */
|
||||||
include_once("types.inc");
|
include_once("types.inc");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the environment variables for custom SSL CA certificates.
|
||||||
|
*/
|
||||||
|
function setSSLCaCert() {
|
||||||
|
// set SSL certificate if set
|
||||||
|
if (isset($_SESSION['cfgMain'])) {
|
||||||
|
$sslCaPath = $_SESSION['cfgMain']->getSSLCaCertPath();
|
||||||
|
if ($sslCaPath != null) {
|
||||||
|
putenv('LDAPTLS_CACERT=' . $sslCaPath);
|
||||||
|
putenv('TLS_CACERT=' . $sslCaPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets language settings for automatic translation
|
* Sets language settings for automatic translation
|
||||||
*/
|
*/
|
||||||
|
@ -545,15 +559,16 @@ class LAMConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$file = @fopen($conffile, "w");
|
$file = @fopen($conffile, "w");
|
||||||
|
$saveResult = LAMConfig::SAVE_OK;
|
||||||
if ($file) {
|
if ($file) {
|
||||||
for ($i = 0; $i < sizeof($file_array); $i++) fputs($file, $file_array[$i]);
|
for ($i = 0; $i < sizeof($file_array); $i++) fputs($file, $file_array[$i]);
|
||||||
fclose($file);
|
fclose($file);
|
||||||
@chmod ($conffile, 0600);
|
@chmod($conffile, 0600);
|
||||||
return LAMConfig::SAVE_OK;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return LAMConfig::SAVE_FAIL;
|
$saveResult = LAMConfig::SAVE_FAIL;
|
||||||
}
|
}
|
||||||
|
return $saveResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1376,6 +1391,12 @@ class LAMCfgMain {
|
||||||
/** path to config file */
|
/** path to config file */
|
||||||
private $conffile;
|
private $conffile;
|
||||||
|
|
||||||
|
/** uploaded SSL certificate that is stored to disk on save() */
|
||||||
|
private $uploadedSSLCaCert = null;
|
||||||
|
|
||||||
|
/** SSL certificate should be deleted on save() */
|
||||||
|
private $delSSLCaCert = false;
|
||||||
|
|
||||||
/** list of data fields to save in config file */
|
/** list of data fields to save in config file */
|
||||||
private $settings = array("password", "default", "sessionTimeout",
|
private $settings = array("password", "default", "sessionTimeout",
|
||||||
"logLevel", "logDestination", "allowedHosts", "passwordMinLength",
|
"logLevel", "logDestination", "allowedHosts", "passwordMinLength",
|
||||||
|
@ -1473,6 +1494,27 @@ class LAMCfgMain {
|
||||||
else {
|
else {
|
||||||
StatusMessage("ERROR", "", _("Cannot open config file!") . " (" . $this->conffile . ")");
|
StatusMessage("ERROR", "", _("Cannot open config file!") . " (" . $this->conffile . ")");
|
||||||
}
|
}
|
||||||
|
// store SSL certificate
|
||||||
|
if ($this->uploadedSSLCaCert != null) {
|
||||||
|
$sslPath = $this->getInternalSSLCaCertFileName();
|
||||||
|
$file = @fopen($sslPath, "w");
|
||||||
|
if ($file) {
|
||||||
|
fputs($file, $this->uploadedSSLCaCert);
|
||||||
|
fclose($file);
|
||||||
|
@chmod($sslPath, 0600);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
StatusMessage("ERROR", _("Cannot write certificate file. Please check the permissions of config/serverCerts.pem."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// delete SSL certificate
|
||||||
|
if ($this->delSSLCaCert === true) {
|
||||||
|
$sslPath = $this->getInternalSSLCaCertFileName();
|
||||||
|
$result = @unlink($sslPath);
|
||||||
|
if (!$result) {
|
||||||
|
StatusMessage("ERROR", _("Cannot write certificate file. Please check the permissions of config/serverCerts.pem."));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1537,6 +1579,187 @@ class LAMCfgMain {
|
||||||
return file_exists($this->conffile);
|
return file_exists($this->conffile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path to the SSL CA certificate file that overrides the system certificates.
|
||||||
|
*
|
||||||
|
* @return String path to certificate file or null if certificate is not overridden
|
||||||
|
*/
|
||||||
|
public function getSSLCaCertPath() {
|
||||||
|
$path = $this->getInternalSSLCaCertFileName();
|
||||||
|
if (file_exists($path)) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the file name that will be used internally to store the CA file.
|
||||||
|
*
|
||||||
|
* @return String file name
|
||||||
|
*/
|
||||||
|
private function getInternalSSLCaCertFileName() {
|
||||||
|
return dirname(__FILE__) . '/../config/serverCerts.pem';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads a new SSL CA cert.
|
||||||
|
*
|
||||||
|
* @param String $cert file content in DER/PEM format
|
||||||
|
* @return mixed TRUE if format is correct, error message if file is not accepted
|
||||||
|
*/
|
||||||
|
public function uploadSSLCaCert($cert) {
|
||||||
|
if (strpos($cert, '-----BEGIN CERTIFICATE-----') !== 0) {
|
||||||
|
$pem = @chunk_split(@base64_encode($cert), 64, "\n");
|
||||||
|
$cert = "-----BEGIN CERTIFICATE-----\n" . $pem . "-----END CERTIFICATE-----\n";
|
||||||
|
}
|
||||||
|
$pemData = @openssl_x509_parse($cert);
|
||||||
|
if ($pemData === false) {
|
||||||
|
return _('Please provide a file in DER or PEM format.');
|
||||||
|
}
|
||||||
|
$existingCerts = $this->getSSLCaCertificateContent();
|
||||||
|
if (!empty($existingCerts)) {
|
||||||
|
// merge with existing certificates
|
||||||
|
$existingList = $this->splitSSLCaCertificateContent($existingCerts);
|
||||||
|
$newList = $this->splitSSLCaCertificateContent($cert);
|
||||||
|
$this->uploadedSSLCaCert = implode("\n", array_unique(array_merge($existingList, $newList)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->uploadedSSLCaCert = $cert;
|
||||||
|
}
|
||||||
|
$this->delSSLCaCert = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of a temporary file in tmp that contains the SSL certificate.
|
||||||
|
* The file contains either the stored data in serverCerts or the uploaded data.
|
||||||
|
*
|
||||||
|
* @return String file name or null if no certificate was set
|
||||||
|
*/
|
||||||
|
public function getSSLCaCertTempFileName() {
|
||||||
|
if ($this->delSSLCaCert) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// get certificate data
|
||||||
|
$content = $this->getSSLCaCertificateContent();
|
||||||
|
if ($content == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// write to temp file
|
||||||
|
$fileName = time() . getRandomNumber() . '.pem';
|
||||||
|
$path = dirname(__FILE__) . '/../tmp/' . $fileName;
|
||||||
|
$handle = @fopen($path, "wb");
|
||||||
|
@chmod($path, 0600);
|
||||||
|
if ($handle) {
|
||||||
|
$content = fputs($handle, $content);
|
||||||
|
fclose($handle);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a single or all SSL CA certificate files for deletion.
|
||||||
|
* The changes take effect on save().
|
||||||
|
*
|
||||||
|
* @param int $index certificate index, null deletes all certificates (default: null)
|
||||||
|
*/
|
||||||
|
public function deleteSSLCaCert($index = null) {
|
||||||
|
if ($index == null) {
|
||||||
|
// delete all
|
||||||
|
$this->delSSLCaCert = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$content = $this->getSSLCaCertificateContent();
|
||||||
|
$list = $this->splitSSLCaCertificateContent($content);
|
||||||
|
unset($list[$index]);
|
||||||
|
if (sizeof($list) < 1) {
|
||||||
|
$this->delSSLCaCert = true;
|
||||||
|
$this->uploadedSSLCaCert = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->uploadedSSLCaCert = implode("\n", $list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all CA certificates.
|
||||||
|
*
|
||||||
|
* @return array list of certificates as output of openssl_x509_parse()
|
||||||
|
*/
|
||||||
|
public function getSSLCaCertificates() {
|
||||||
|
if ($this->delSSLCaCert) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$content = $this->getSSLCaCertificateContent();
|
||||||
|
if (empty($content)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$list = $this->splitSSLCaCertificateContent($content);
|
||||||
|
for ($i = 0; $i < sizeof($list); $i++) {
|
||||||
|
$list[$i] = @openssl_x509_parse($list[$i]);
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content of the certificate file or uploaded data.
|
||||||
|
*
|
||||||
|
* @return String null or certificate content
|
||||||
|
*/
|
||||||
|
private function getSSLCaCertificateContent() {
|
||||||
|
$content = null;
|
||||||
|
if ($this->delSSLCaCert) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($this->uploadedSSLCaCert != null) {
|
||||||
|
$content = $this->uploadedSSLCaCert;
|
||||||
|
}
|
||||||
|
elseif ($this->getSSLCaCertPath() != null) {
|
||||||
|
$path = $this->getSSLCaCertPath();
|
||||||
|
$handle = @fopen($path, "r");
|
||||||
|
if ($handle) {
|
||||||
|
$content = fread($handle, 10000000);
|
||||||
|
fclose($handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits the certificate content into single PEM data chunks.
|
||||||
|
*
|
||||||
|
* @param String $content PEM file content
|
||||||
|
* @return array one element for each certificate chunk
|
||||||
|
*/
|
||||||
|
private function splitSSLCaCertificateContent($content) {
|
||||||
|
if (empty($content)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$content = str_replace("\n\n", "\n", $content);
|
||||||
|
if (empty($content)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
if (!(strpos($content, '-----BEGIN CERTIFICATE-----') === 0)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$lines = explode("\n", $content);
|
||||||
|
$list = array();
|
||||||
|
$pos = -1;
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
if (strpos($line, '-----BEGIN CERTIFICATE-----') === 0) {
|
||||||
|
$pos++;
|
||||||
|
}
|
||||||
|
if (!isset($list[$pos])) {
|
||||||
|
$list[$pos] = '';
|
||||||
|
}
|
||||||
|
$list[$pos] .= $line . "\n";
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -2261,7 +2261,9 @@ class inetOrgPerson extends baseModule implements passwordService {
|
||||||
$table->colspan = 10;
|
$table->colspan = 10;
|
||||||
for ($i = 0; $i < sizeof($this->attributes['userCertificate;binary']); $i++) {
|
for ($i = 0; $i < sizeof($this->attributes['userCertificate;binary']); $i++) {
|
||||||
$filename = 'userCertificate' . getRandomNumber() . '.der';
|
$filename = 'userCertificate' . getRandomNumber() . '.der';
|
||||||
$out = @fopen(dirname(__FILE__) . '/../../tmp/' . $filename, "wb");
|
$pathOut = dirname(__FILE__) . '/../../tmp/' . $filename;
|
||||||
|
$out = @fopen($pathOut, "wb");
|
||||||
|
@chmod($pathOut, 0600);
|
||||||
fwrite($out, $this->attributes['userCertificate;binary'][$i]);
|
fwrite($out, $this->attributes['userCertificate;binary'][$i]);
|
||||||
fclose ($out);
|
fclose ($out);
|
||||||
$path = '../../tmp/' . $filename;
|
$path = '../../tmp/' . $filename;
|
||||||
|
|
|
@ -87,6 +87,7 @@ function startSecureSession($redirectToLogin = true, $initSecureData = false) {
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
setSSLCaCert();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ if (sizeof($errorsToDisplay) > 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// display formular
|
// display formular
|
||||||
echo ("<form action=\"confmain.php\" method=\"post\" autocomplete=\"off\">\n");
|
echo ("<form enctype=\"multipart/form-data\" action=\"confmain.php\" method=\"post\" autocomplete=\"off\">\n");
|
||||||
|
|
||||||
// hidden submit buttons which are clicked by tabs
|
// hidden submit buttons which are clicked by tabs
|
||||||
echo "<div style=\"display: none;\">\n";
|
echo "<div style=\"display: none;\">\n";
|
||||||
|
@ -264,6 +264,7 @@ if (isLAMProVersion()) {
|
||||||
$accessSelect->setHasDescriptiveElements(true);
|
$accessSelect->setHasDescriptiveElements(true);
|
||||||
$serverSettingsContent->addElement($accessSelect, true);
|
$serverSettingsContent->addElement($accessSelect, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$serverSettings = new htmlFieldset($serverSettingsContent, _("Server settings"), '../../graphics/profiles.png');
|
$serverSettings = new htmlFieldset($serverSettingsContent, _("Server settings"), '../../graphics/profiles.png');
|
||||||
$container->addElement($serverSettings, true);
|
$container->addElement($serverSettings, true);
|
||||||
$container->addElement(new htmlSpacer(null, '10px'), true);
|
$container->addElement(new htmlSpacer(null, '10px'), true);
|
||||||
|
|
|
@ -46,7 +46,9 @@ setlanguage();
|
||||||
|
|
||||||
// remove settings from session
|
// remove settings from session
|
||||||
if (isset($_SESSION["mainconf_password"])) unset($_SESSION["mainconf_password"]);
|
if (isset($_SESSION["mainconf_password"])) unset($_SESSION["mainconf_password"]);
|
||||||
|
if (isset($_SESSION['cfgMain'])) {
|
||||||
|
unset($_SESSION['cfgMain']);
|
||||||
|
}
|
||||||
$cfgMain = new LAMCfgMain();
|
$cfgMain = new LAMCfgMain();
|
||||||
// check if user entered a password
|
// check if user entered a password
|
||||||
if (isset($_POST['passwd'])) {
|
if (isset($_POST['passwd'])) {
|
||||||
|
|
|
@ -43,7 +43,11 @@ if (strtolower(session_module_name()) == 'files') {
|
||||||
|
|
||||||
setlanguage();
|
setlanguage();
|
||||||
|
|
||||||
$cfg = new LAMCfgMain();
|
if (!isset($_SESSION['cfgMain'])) {
|
||||||
|
$cfg = new LAMCfgMain();
|
||||||
|
$_SESSION['cfgMain'] = $cfg;
|
||||||
|
}
|
||||||
|
$cfg = &$_SESSION['cfgMain'];
|
||||||
|
|
||||||
// check if user is logged in
|
// check if user is logged in
|
||||||
if (!isset($_SESSION["mainconf_password"]) || (!$cfg->checkPassword($_SESSION["mainconf_password"]))) {
|
if (!isset($_SESSION["mainconf_password"]) || (!$cfg->checkPassword($_SESSION["mainconf_password"]))) {
|
||||||
|
@ -58,8 +62,9 @@ if (isset($_POST['cancel'])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
$messages = array();
|
||||||
// check if submit button was pressed
|
// check if submit button was pressed
|
||||||
if (isset($_POST['submit'])) {
|
if (isset($_POST['submitFormData'])) {
|
||||||
// remove double slashes if magic quotes are on
|
// remove double slashes if magic quotes are on
|
||||||
if (get_magic_quotes_gpc() == 1) {
|
if (get_magic_quotes_gpc() == 1) {
|
||||||
$postKeys = array_keys($_POST);
|
$postKeys = array_keys($_POST);
|
||||||
|
@ -117,12 +122,62 @@ if (isset($_POST['submit'])) {
|
||||||
$cfg->passwordMinNumeric = $_POST['passwordMinNumeric'];
|
$cfg->passwordMinNumeric = $_POST['passwordMinNumeric'];
|
||||||
$cfg->passwordMinSymbol = $_POST['passwordMinSymbol'];
|
$cfg->passwordMinSymbol = $_POST['passwordMinSymbol'];
|
||||||
$cfg->passwordMinClasses = $_POST['passwordMinClasses'];
|
$cfg->passwordMinClasses = $_POST['passwordMinClasses'];
|
||||||
|
if (isset($_POST['sslCaCertUpload'])) {
|
||||||
|
if (!isset($_FILES['sslCaCert']) || ($_FILES['sslCaCert']['size'] == 0)) {
|
||||||
|
$errors[] = _('No file selected.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$handle = fopen($_FILES['sslCaCert']['tmp_name'], "r");
|
||||||
|
$data = fread($handle, 10000000);
|
||||||
|
fclose($handle);
|
||||||
|
$sslReturn = $cfg->uploadSSLCaCert($data);
|
||||||
|
if ($sslReturn !== true) {
|
||||||
|
$errors[] = $sslReturn;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$messages[] = _('You might need to restart your webserver for changes to take effect.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($_POST['sslCaCertDelete'])) {
|
||||||
|
$cfg->deleteSSLCaCert();
|
||||||
|
$messages[] = _('You might need to restart your webserver for changes to take effect.');
|
||||||
|
}
|
||||||
|
if (isset($_POST['sslCaCertImport'])) {
|
||||||
|
$matches = array();
|
||||||
|
if (preg_match('/^([a-zA-Z0-9_\\.-]+)(:([0-9]+))?$/', $_POST['serverurl'], $matches)) {
|
||||||
|
$port = '636';
|
||||||
|
if (isset($matches[3]) && !empty($matches[3])) {
|
||||||
|
$port = $matches[3];
|
||||||
|
}
|
||||||
|
$pemResult = getLDAPSSLCertificate($matches[1], $port);
|
||||||
|
if ($pemResult !== false) {
|
||||||
|
$messages[] = _('Imported certificate from server.');
|
||||||
|
$messages[] = _('You might need to restart your webserver for changes to take effect.');
|
||||||
|
$cfg->uploadSSLCaCert($pemResult);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$errors[] = _('Unable to import server certificate. Please use the upload function.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$errors[] = _('Invalid server name. Please enter "server" or "server:port".');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($_POST as $key => $value) {
|
||||||
|
if (strpos($key, 'deleteCert_') === 0) {
|
||||||
|
$index = substr($key, strlen('deleteCert_'));
|
||||||
|
$cfg->deleteSSLCaCert($index);
|
||||||
|
}
|
||||||
|
}
|
||||||
// save settings
|
// save settings
|
||||||
|
if (isset($_POST['submit'])) {
|
||||||
$cfg->save();
|
$cfg->save();
|
||||||
if (sizeof($errors) == 0) {
|
if (sizeof($errors) == 0) {
|
||||||
metaRefresh('../login.php?confMainSavedOk=1');
|
metaRefresh('../login.php?confMainSavedOk=1');
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $_SESSION['header'];
|
echo $_SESSION['header'];
|
||||||
|
@ -166,7 +221,7 @@ echo $_SESSION['header'];
|
||||||
</table>
|
</table>
|
||||||
<br>
|
<br>
|
||||||
<!-- form for adding/renaming/deleting profiles -->
|
<!-- form for adding/renaming/deleting profiles -->
|
||||||
<form action="mainmanage.php" method="post">
|
<form enctype="multipart/form-data" action="mainmanage.php" method="post">
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// include all JavaScript files
|
// include all JavaScript files
|
||||||
|
@ -188,23 +243,97 @@ $container = new htmlTable();
|
||||||
for ($i = 0; $i < sizeof($errors); $i++) {
|
for ($i = 0; $i < sizeof($errors); $i++) {
|
||||||
$container->addElement(new htmlStatusMessage("ERROR", $errors[$i]), true);
|
$container->addElement(new htmlStatusMessage("ERROR", $errors[$i]), true);
|
||||||
}
|
}
|
||||||
|
for ($i = 0; $i < sizeof($messages); $i++) {
|
||||||
|
$container->addElement(new htmlStatusMessage("INFO", $messages[$i]), true);
|
||||||
|
}
|
||||||
|
|
||||||
// check if config file is writable
|
// check if config file is writable
|
||||||
if (!$cfg->isWritable()) {
|
if (!$cfg->isWritable()) {
|
||||||
$container->addElement(new htmlStatusMessage('WARN', 'The config file is not writable.', 'Your changes cannot be saved until you make the file writable for the webserver user.'), true);
|
$container->addElement(new htmlStatusMessage('WARN', 'The config file is not writable.', 'Your changes cannot be saved until you make the file writable for the webserver user.'), true);
|
||||||
}
|
}
|
||||||
$container->addElement(new htmlSpacer(null, '20px'), true);
|
|
||||||
|
|
||||||
// security settings
|
// security settings
|
||||||
|
$container->addElement(new htmlSubTitle(_("Security settings")), true);
|
||||||
$securityTable = new htmlTable();
|
$securityTable = new htmlTable();
|
||||||
$options = array(5, 10, 20, 30, 60, 90, 120, 240);
|
$options = array(5, 10, 20, 30, 60, 90, 120, 240);
|
||||||
$securityTable->addElement(new htmlTableExtendedSelect('sessionTimeout', $options, array($cfg->sessionTimeout), _("Session timeout"), '238'), true);
|
$securityTable->addElement(new htmlTableExtendedSelect('sessionTimeout', $options, array($cfg->sessionTimeout), _("Session timeout"), '238'), true);
|
||||||
$securityTable->addElement(new htmlTableExtendedInputTextarea('allowedHosts', implode("\n", explode(",", $cfg->allowedHosts)), '30', '7', _("Allowed hosts"), '241'), true);
|
$securityTable->addElement(new htmlTableExtendedInputTextarea('allowedHosts', implode("\n", explode(",", $cfg->allowedHosts)), '30', '7', _("Allowed hosts"), '241'), true);
|
||||||
$securityField = new htmlFieldset($securityTable, _("Security settings"));
|
// SSL certificate
|
||||||
$container->addElement($securityField, true);
|
$securityTable->addElement(new htmlOutputText(_('SSL certificates')));
|
||||||
|
$sslMethod = _('use system certificates');
|
||||||
|
$sslFileName = $cfg->getSSLCaCertTempFileName();
|
||||||
|
if ($sslFileName != null) {
|
||||||
|
$sslMethod = _('use custom CA certificate');
|
||||||
|
}
|
||||||
|
$sslDelSaveGroup = new htmlGroup();
|
||||||
|
$sslDelSaveGroup->addElement(new htmlOutputText($sslMethod));
|
||||||
|
$sslDelSaveGroup->addElement(new htmlSpacer('5px', null));
|
||||||
|
// delete+download button
|
||||||
|
if ($sslFileName != null) {
|
||||||
|
$sslDownloadBtn = new htmlLink('', '../../tmp/' . $sslFileName, '../../graphics/save.png');
|
||||||
|
$sslDownloadBtn->setTargetWindow('_blank');
|
||||||
|
$sslDownloadBtn->setTitle(_('Download CA certificates'));
|
||||||
|
$sslDelSaveGroup->addElement($sslDownloadBtn);
|
||||||
|
$sslDeleteBtn = new htmlButton('sslCaCertDelete', 'delete.png', true);
|
||||||
|
$sslDeleteBtn->setTitle(_('Delete all CA certificates'));
|
||||||
|
$sslDelSaveGroup->addElement($sslDeleteBtn);
|
||||||
|
}
|
||||||
|
$securityTable->addElement($sslDelSaveGroup);
|
||||||
|
$securityTable->addElement(new htmlHelpLink('204'));
|
||||||
|
$securityTable->addElement(new htmlSpacer('250px', null), true);
|
||||||
|
$securityTable->addElement(new htmlOutputText(''));
|
||||||
|
$sslButtonTable = new htmlTable();
|
||||||
|
$sslButtonTable->colspan = 3;
|
||||||
|
$sslButtonTable->addElement(new htmlInputFileUpload('sslCaCert'));
|
||||||
|
$sslUploadBtn = new htmlButton('sslCaCertUpload', _('Upload'));
|
||||||
|
$sslUploadBtn->setIconClass('upButton');
|
||||||
|
$sslUploadBtn->setTitle(_('Upload CA certificate'));
|
||||||
|
$sslButtonTable->addElement($sslUploadBtn, true);
|
||||||
|
if (function_exists('stream_socket_client')) {
|
||||||
|
$sslImportGroup = new htmlGroup();
|
||||||
|
$sslImportGroup->addElement(new htmlOutputText('ldaps://'));
|
||||||
|
$sslImportServerUrl = !empty($_POST['serverurl']) ? $_POST['serverurl'] : '';
|
||||||
|
$sslImportGroup->addElement(new htmlInputField('serverurl'));
|
||||||
|
$sslButtonTable->addElement($sslImportGroup);
|
||||||
|
$sslImportBtn = new htmlButton('sslCaCertImport', _('Import from server'));
|
||||||
|
$sslImportBtn->setIconClass('downButton');
|
||||||
|
$sslImportBtn->setTitle(_('Imports the certificate directly from your LDAP server.'));
|
||||||
|
$sslImportBtn->setCSSClasses(array('nowrap'));
|
||||||
|
$sslButtonTable->addElement($sslImportBtn);
|
||||||
|
$sslButtonTable->addElement(new htmlEqualWidth(array('btn_sslCaCertUpload', 'btn_sslCaCertImport')));
|
||||||
|
}
|
||||||
|
$securityTable->addElement($sslButtonTable, true);
|
||||||
|
$sslCerts = $cfg->getSSLCaCertificates();
|
||||||
|
if (sizeof($sslCerts) > 0) {
|
||||||
|
$certTable = new htmlTable();
|
||||||
|
$certTable->colspan = 3;
|
||||||
|
$certSpace = new htmlSpacer('5px', null);
|
||||||
|
$certTable->addElement(new htmlOutputText(''));
|
||||||
|
$certTable->addElement(new htmlOutputText(_('Serial number')));
|
||||||
|
$certTable->addElement($certSpace);
|
||||||
|
$certTable->addElement(new htmlOutputText(_('Valid to')));
|
||||||
|
$certTable->addElement($certSpace);
|
||||||
|
$certTable->addElement(new htmlOutputText(_('Common name')), true);
|
||||||
|
for ($i = 0; $i < sizeof($sslCerts); $i++) {
|
||||||
|
$serial = isset($sslCerts[$i]['serialNumber']) ? $sslCerts[$i]['serialNumber'] : '';
|
||||||
|
$validTo = isset($sslCerts[$i]['validTo_time_t']) ? $sslCerts[$i]['validTo_time_t'] : '';
|
||||||
|
$cn = isset($sslCerts[$i]['subject']['CN']) ? $sslCerts[$i]['subject']['CN'] : '';
|
||||||
|
$certTable->addElement(new htmlButton('deleteCert_' . $i, 'delete.png', true));
|
||||||
|
$certTable->addElement(new htmlOutputText($serial));
|
||||||
|
$certTable->addElement($certSpace);
|
||||||
|
$certTable->addElement(new htmlOutputText(formatSSLTimestamp($validTo)));
|
||||||
|
$certTable->addElement($certSpace);
|
||||||
|
$certTable->addElement(new htmlOutputText($cn), true);
|
||||||
|
}
|
||||||
|
$securityTable->addElement(new htmlOutputText(''));
|
||||||
|
$securityTable->addElement($certTable, true);
|
||||||
|
}
|
||||||
|
$container->addElement($securityTable, true);
|
||||||
|
|
||||||
$container->addElement(new htmlSpacer(null, '10px'), true);
|
$container->addElement(new htmlSpacer(null, '10px'), true);
|
||||||
|
|
||||||
// password policy
|
// password policy
|
||||||
|
$container->addElement(new htmlSubTitle(_("Password policy")), true);
|
||||||
$policyTable = new htmlTable();
|
$policyTable = new htmlTable();
|
||||||
$options20 = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
|
$options20 = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
|
||||||
$options4 = array(0, 1, 2, 3, 4);
|
$options4 = array(0, 1, 2, 3, 4);
|
||||||
|
@ -214,11 +343,11 @@ $policyTable->addElement(new htmlTableExtendedSelect('passwordMinUpper', $option
|
||||||
$policyTable->addElement(new htmlTableExtendedSelect('passwordMinNumeric', $options20, array($cfg->passwordMinNumeric), _('Minimum numeric characters'), '242'), true);
|
$policyTable->addElement(new htmlTableExtendedSelect('passwordMinNumeric', $options20, array($cfg->passwordMinNumeric), _('Minimum numeric characters'), '242'), true);
|
||||||
$policyTable->addElement(new htmlTableExtendedSelect('passwordMinSymbol', $options20, array($cfg->passwordMinSymbol), _('Minimum symbolic characters'), '242'), true);
|
$policyTable->addElement(new htmlTableExtendedSelect('passwordMinSymbol', $options20, array($cfg->passwordMinSymbol), _('Minimum symbolic characters'), '242'), true);
|
||||||
$policyTable->addElement(new htmlTableExtendedSelect('passwordMinClasses', $options4, array($cfg->passwordMinClasses), _('Minimum character classes'), '242'), true);
|
$policyTable->addElement(new htmlTableExtendedSelect('passwordMinClasses', $options4, array($cfg->passwordMinClasses), _('Minimum character classes'), '242'), true);
|
||||||
$policyField = new htmlFieldset($policyTable, _("Password policy"));
|
$container->addElement($policyTable, true);
|
||||||
$container->addElement($policyField, true);
|
|
||||||
$container->addElement(new htmlSpacer(null, '10px'), true);
|
$container->addElement(new htmlSpacer(null, '10px'), true);
|
||||||
|
|
||||||
// logging
|
// logging
|
||||||
|
$container->addElement(new htmlSubTitle(_("Logging")), true);
|
||||||
$loggingTable = new htmlTable();
|
$loggingTable = new htmlTable();
|
||||||
$levelOptions = array(_("Debug") => LOG_DEBUG, _("Notice") => LOG_NOTICE, _("Warning") => LOG_WARNING, _("Error") => LOG_ERR);
|
$levelOptions = array(_("Debug") => LOG_DEBUG, _("Notice") => LOG_NOTICE, _("Warning") => LOG_WARNING, _("Error") => LOG_ERR);
|
||||||
$levelSelect = new htmlTableExtendedSelect('logLevel', $levelOptions, array($cfg->logLevel), _("Log level"), '239');
|
$levelSelect = new htmlTableExtendedSelect('logLevel', $levelOptions, array($cfg->logLevel), _("Log level"), '239');
|
||||||
|
@ -238,11 +367,11 @@ elseif ($cfg->logDestination == 'SYSLOG') {
|
||||||
$loggingTable->addElement(new htmlTableExtendedRadio(_("Log destination"), 'logDestination', $destinationOptions, $destinationSelected, '240'), true);
|
$loggingTable->addElement(new htmlTableExtendedRadio(_("Log destination"), 'logDestination', $destinationOptions, $destinationSelected, '240'), true);
|
||||||
$loggingTable->addElement(new htmlOutputText(''));
|
$loggingTable->addElement(new htmlOutputText(''));
|
||||||
$loggingTable->addElement(new htmlInputField('logFile', $destinationPath), true);
|
$loggingTable->addElement(new htmlInputField('logFile', $destinationPath), true);
|
||||||
$loggingField = new htmlFieldset($loggingTable, _("Logging"));
|
$container->addElement($loggingTable, true);
|
||||||
$container->addElement($loggingField, true);
|
|
||||||
$container->addElement(new htmlSpacer(null, '10px'), true);
|
$container->addElement(new htmlSpacer(null, '10px'), true);
|
||||||
|
|
||||||
// change master password
|
// change master password
|
||||||
|
$container->addElement(new htmlSubTitle(_("Change master password")), true);
|
||||||
$passwordTable = new htmlTable();
|
$passwordTable = new htmlTable();
|
||||||
$pwd1 = new htmlTableExtendedInputField(_("New master password"), 'masterpassword', '', '235');
|
$pwd1 = new htmlTableExtendedInputField(_("New master password"), 'masterpassword', '', '235');
|
||||||
$pwd1->setIsPassword(true);
|
$pwd1->setIsPassword(true);
|
||||||
|
@ -250,8 +379,7 @@ $passwordTable->addElement($pwd1, true);
|
||||||
$pwd2 = new htmlTableExtendedInputField(_("Reenter password"), 'masterpassword2', '');
|
$pwd2 = new htmlTableExtendedInputField(_("Reenter password"), 'masterpassword2', '');
|
||||||
$pwd2->setIsPassword(true);
|
$pwd2->setIsPassword(true);
|
||||||
$passwordTable->addElement($pwd2, true);
|
$passwordTable->addElement($pwd2, true);
|
||||||
$passwordField = new htmlFieldset($passwordTable, _("Change master password"));
|
$container->addElement($passwordTable, true);
|
||||||
$container->addElement($passwordField, true);
|
|
||||||
$container->addElement(new htmlSpacer(null, '20px'), true);
|
$container->addElement(new htmlSpacer(null, '20px'), true);
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
|
@ -259,11 +387,31 @@ if ($cfg->isWritable()) {
|
||||||
$buttonTable = new htmlTable();
|
$buttonTable = new htmlTable();
|
||||||
$buttonTable->addElement(new htmlButton('submit', _("Ok")));
|
$buttonTable->addElement(new htmlButton('submit', _("Ok")));
|
||||||
$buttonTable->addElement(new htmlButton('cancel', _("Cancel")));
|
$buttonTable->addElement(new htmlButton('cancel', _("Cancel")));
|
||||||
$container->addElement($buttonTable);
|
$container->addElement($buttonTable, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$container->addElement(new htmlHiddenInput('submitFormData', '1'), true);
|
||||||
|
|
||||||
$tabindex = 1;
|
$tabindex = 1;
|
||||||
parseHtml(null, $container, array(), false, $tabindex, 'user');
|
$globalFieldset = new htmlFieldset($container, _('General settings'));
|
||||||
|
parseHtml(null, $globalFieldset, array(), false, $tabindex, 'user');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats an LDAP time string (e.g. from createTimestamp).
|
||||||
|
*
|
||||||
|
* @param String $time LDAP time value
|
||||||
|
* @return String formated time
|
||||||
|
*/
|
||||||
|
function formatSSLTimestamp($time) {
|
||||||
|
$matches = array();
|
||||||
|
if (!empty($time)) {
|
||||||
|
return date('d.m.Y', $time);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -523,6 +523,7 @@ if(!empty($_POST['checklogin'])) {
|
||||||
include_once("../lib/ldap.inc"); // Include ldap.php which provides Ldap class
|
include_once("../lib/ldap.inc"); // Include ldap.php which provides Ldap class
|
||||||
|
|
||||||
$_SESSION['ldap'] = new Ldap($_SESSION['config']); // Create new Ldap object
|
$_SESSION['ldap'] = new Ldap($_SESSION['config']); // Create new Ldap object
|
||||||
|
setSSLCaCert();
|
||||||
|
|
||||||
$clientSource = $_SERVER['REMOTE_ADDR'];
|
$clientSource = $_SERVER['REMOTE_ADDR'];
|
||||||
if (isset($_SERVER['REMOTE_HOST'])) {
|
if (isset($_SERVER['REMOTE_HOST'])) {
|
||||||
|
|
Loading…
Reference in New Issue