From 90e01cbcaabc0b3b92b1f4e1998726fddf11b9fc Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sat, 10 Aug 2013 12:43:01 +0000 Subject: [PATCH] allow to specify SSL CA certificates in LAM main configuration --- lam/HISTORY | 1 + lam/help/help.inc | 2 + lam/lib/account.inc | 35 +++++ lam/lib/checkEnvironment.inc | 4 + lam/lib/config.inc | 235 +++++++++++++++++++++++++++- lam/lib/modules/inetOrgPerson.inc | 4 +- lam/lib/security.inc | 1 + lam/templates/config/confmain.php | 3 +- lam/templates/config/mainlogin.php | 4 +- lam/templates/config/mainmanage.php | 184 +++++++++++++++++++--- lam/templates/login.php | 3 +- 11 files changed, 448 insertions(+), 28 deletions(-) diff --git a/lam/HISTORY b/lam/HISTORY index 0c26fa6e..6af2f2f1 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -1,4 +1,5 @@ September 2013 4.3 + - Custom SSL CA certificates can be setup in LAM main configuration - LAM Pro: -> PPolicy: check password history for password reuse -> Custom fields: read-only fields for admin interface and file upload for binary data diff --git a/lam/help/help.inc b/lam/help/help.inc index 9c40f27b..863e8787 100644 --- a/lam/help/help.inc +++ b/lam/help/help.inc @@ -80,6 +80,8 @@ $helpArray = array ( _("Example"). ":

". _("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"), "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.") . "


" . diff --git a/lam/lib/account.inc b/lam/lib/account.inc index f1204c35..356e563b 100644 --- a/lam/lib/account.inc +++ b/lam/lib/account.inc @@ -1077,4 +1077,39 @@ function getRandomNumber() { 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; +} + ?> diff --git a/lam/lib/checkEnvironment.inc b/lam/lib/checkEnvironment.inc index 98105187..1186ac93 100644 --- a/lam/lib/checkEnvironment.inc +++ b/lam/lib/checkEnvironment.inc @@ -70,6 +70,10 @@ if (! function_exists('ldap_search')) { if (! function_exists('gettext') || !function_exists('_')) { $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 if (! function_exists('utf8_decode')) { $criticalErrors[] = array("ERROR", "Your PHP has no XML support!", "Please install the XML extension for PHP."); diff --git a/lam/lib/config.inc b/lam/lib/config.inc index b17c0b7a..cba2e190 100644 --- a/lam/lib/config.inc +++ b/lam/lib/config.inc @@ -37,6 +37,20 @@ include_once("modules.inc"); /** Used to get type information. */ 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 */ @@ -233,13 +247,13 @@ class LAMConfig { /** line separator */ const LINE_SEPARATOR = '+::+'; - + /** Server address (e.g. ldap://127.0.0.1:389) */ private $ServerURL; /** enables/disables TLS encryption */ private $useTLS; - + /** Array of string: users with admin rights */ private $Admins; @@ -545,15 +559,16 @@ class LAMConfig { } } $file = @fopen($conffile, "w"); + $saveResult = LAMConfig::SAVE_OK; if ($file) { for ($i = 0; $i < sizeof($file_array); $i++) fputs($file, $file_array[$i]); fclose($file); - @chmod ($conffile, 0600); - return LAMConfig::SAVE_OK; + @chmod($conffile, 0600); } else { - return LAMConfig::SAVE_FAIL; + $saveResult = LAMConfig::SAVE_FAIL; } + return $saveResult; } } @@ -1326,7 +1341,7 @@ class LAMConfig { public function setLamProMailText($lamProMailText) { $this->lamProMailText = implode(LAMConfig::LINE_SEPARATOR, explode("\r\n", $lamProMailText)); } - + } @@ -1376,6 +1391,12 @@ class LAMCfgMain { /** path to config file */ 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 */ private $settings = array("password", "default", "sessionTimeout", "logLevel", "logDestination", "allowedHosts", "passwordMinLength", @@ -1473,6 +1494,27 @@ class LAMCfgMain { else { 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); } + /** + * 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; + } + } ?> diff --git a/lam/lib/modules/inetOrgPerson.inc b/lam/lib/modules/inetOrgPerson.inc index d9a8945e..fd5bbe02 100644 --- a/lam/lib/modules/inetOrgPerson.inc +++ b/lam/lib/modules/inetOrgPerson.inc @@ -2261,7 +2261,9 @@ class inetOrgPerson extends baseModule implements passwordService { $table->colspan = 10; for ($i = 0; $i < sizeof($this->attributes['userCertificate;binary']); $i++) { $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]); fclose ($out); $path = '../../tmp/' . $filename; diff --git a/lam/lib/security.inc b/lam/lib/security.inc index c7d91385..f1f597ab 100644 --- a/lam/lib/security.inc +++ b/lam/lib/security.inc @@ -87,6 +87,7 @@ function startSecureSession($redirectToLogin = true, $initSecureData = false) { else { return false; } + setSSLCaCert(); return true; } diff --git a/lam/templates/config/confmain.php b/lam/templates/config/confmain.php index 24834590..72a19c14 100644 --- a/lam/templates/config/confmain.php +++ b/lam/templates/config/confmain.php @@ -186,7 +186,7 @@ if (sizeof($errorsToDisplay) > 0) { } // display formular -echo ("
\n"); +echo ("\n"); // hidden submit buttons which are clicked by tabs echo "
\n"; @@ -264,6 +264,7 @@ if (isLAMProVersion()) { $accessSelect->setHasDescriptiveElements(true); $serverSettingsContent->addElement($accessSelect, true); } + $serverSettings = new htmlFieldset($serverSettingsContent, _("Server settings"), '../../graphics/profiles.png'); $container->addElement($serverSettings, true); $container->addElement(new htmlSpacer(null, '10px'), true); diff --git a/lam/templates/config/mainlogin.php b/lam/templates/config/mainlogin.php index d319b49c..e00660fd 100644 --- a/lam/templates/config/mainlogin.php +++ b/lam/templates/config/mainlogin.php @@ -46,7 +46,9 @@ setlanguage(); // remove settings from session if (isset($_SESSION["mainconf_password"])) unset($_SESSION["mainconf_password"]); - +if (isset($_SESSION['cfgMain'])) { + unset($_SESSION['cfgMain']); +} $cfgMain = new LAMCfgMain(); // check if user entered a password if (isset($_POST['passwd'])) { diff --git a/lam/templates/config/mainmanage.php b/lam/templates/config/mainmanage.php index bf6b1703..12ce9ce5 100644 --- a/lam/templates/config/mainmanage.php +++ b/lam/templates/config/mainmanage.php @@ -43,7 +43,11 @@ if (strtolower(session_module_name()) == 'files') { setlanguage(); -$cfg = new LAMCfgMain(); +if (!isset($_SESSION['cfgMain'])) { + $cfg = new LAMCfgMain(); + $_SESSION['cfgMain'] = $cfg; +} +$cfg = &$_SESSION['cfgMain']; // check if user is logged in if (!isset($_SESSION["mainconf_password"]) || (!$cfg->checkPassword($_SESSION["mainconf_password"]))) { @@ -58,8 +62,9 @@ if (isset($_POST['cancel'])) { } $errors = array(); +$messages = array(); // check if submit button was pressed -if (isset($_POST['submit'])) { +if (isset($_POST['submitFormData'])) { // remove double slashes if magic quotes are on if (get_magic_quotes_gpc() == 1) { $postKeys = array_keys($_POST); @@ -117,11 +122,61 @@ if (isset($_POST['submit'])) { $cfg->passwordMinNumeric = $_POST['passwordMinNumeric']; $cfg->passwordMinSymbol = $_POST['passwordMinSymbol']; $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 - $cfg->save(); - if (sizeof($errors) == 0) { - metaRefresh('../login.php?confMainSavedOk=1'); - exit(); + if (isset($_POST['submit'])) { + $cfg->save(); + if (sizeof($errors) == 0) { + metaRefresh('../login.php?confMainSavedOk=1'); + exit(); + } } } @@ -166,7 +221,7 @@ echo $_SESSION['header'];
- + 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 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 htmlSpacer(null, '20px'), true); // security settings +$container->addElement(new htmlSubTitle(_("Security settings")), true); $securityTable = new htmlTable(); $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 htmlTableExtendedInputTextarea('allowedHosts', implode("\n", explode(",", $cfg->allowedHosts)), '30', '7', _("Allowed hosts"), '241'), true); -$securityField = new htmlFieldset($securityTable, _("Security settings")); -$container->addElement($securityField, true); +// SSL certificate +$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); // password policy +$container->addElement(new htmlSubTitle(_("Password policy")), true); $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); $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('passwordMinSymbol', $options20, array($cfg->passwordMinSymbol), _('Minimum symbolic characters'), '242'), true); $policyTable->addElement(new htmlTableExtendedSelect('passwordMinClasses', $options4, array($cfg->passwordMinClasses), _('Minimum character classes'), '242'), true); -$policyField = new htmlFieldset($policyTable, _("Password policy")); -$container->addElement($policyField, true); +$container->addElement($policyTable, true); $container->addElement(new htmlSpacer(null, '10px'), true); // logging +$container->addElement(new htmlSubTitle(_("Logging")), true); $loggingTable = new htmlTable(); $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'); @@ -238,11 +367,11 @@ elseif ($cfg->logDestination == 'SYSLOG') { $loggingTable->addElement(new htmlTableExtendedRadio(_("Log destination"), 'logDestination', $destinationOptions, $destinationSelected, '240'), true); $loggingTable->addElement(new htmlOutputText('')); $loggingTable->addElement(new htmlInputField('logFile', $destinationPath), true); -$loggingField = new htmlFieldset($loggingTable, _("Logging")); -$container->addElement($loggingField, true); +$container->addElement($loggingTable, true); $container->addElement(new htmlSpacer(null, '10px'), true); // change master password +$container->addElement(new htmlSubTitle(_("Change master password")), true); $passwordTable = new htmlTable(); $pwd1 = new htmlTableExtendedInputField(_("New master password"), 'masterpassword', '', '235'); $pwd1->setIsPassword(true); @@ -250,8 +379,7 @@ $passwordTable->addElement($pwd1, true); $pwd2 = new htmlTableExtendedInputField(_("Reenter password"), 'masterpassword2', ''); $pwd2->setIsPassword(true); $passwordTable->addElement($pwd2, true); -$passwordField = new htmlFieldset($passwordTable, _("Change master password")); -$container->addElement($passwordField, true); +$container->addElement($passwordTable, true); $container->addElement(new htmlSpacer(null, '20px'), true); // buttons @@ -259,11 +387,31 @@ if ($cfg->isWritable()) { $buttonTable = new htmlTable(); $buttonTable->addElement(new htmlButton('submit', _("Ok"))); $buttonTable->addElement(new htmlButton('cancel', _("Cancel"))); - $container->addElement($buttonTable); + $container->addElement($buttonTable, true); } +$container->addElement(new htmlHiddenInput('submitFormData', '1'), true); + $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 ''; +} + + + ?> diff --git a/lam/templates/login.php b/lam/templates/login.php index bbd0e98c..d03a4a6e 100644 --- a/lam/templates/login.php +++ b/lam/templates/login.php @@ -523,7 +523,8 @@ if(!empty($_POST['checklogin'])) { include_once("../lib/ldap.inc"); // Include ldap.php which provides Ldap class $_SESSION['ldap'] = new Ldap($_SESSION['config']); // Create new Ldap object - + setSSLCaCert(); + $clientSource = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['REMOTE_HOST'])) { $clientSource .= '/' . $_SERVER['REMOTE_HOST'];