From fe0c30b53f1b30a1475f044ec1c141efafacae74 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Mon, 28 Jan 2013 21:15:55 +0000 Subject: [PATCH] user certificates --- lam/HISTORY | 1 + lam/docs/manual-sources/howto.xml | 17 ++- .../manual-sources/images/mod_personal2.png | Bin 0 -> 42516 bytes lam/lib/modules/inetOrgPerson.inc | 131 +++++++++++++++++- 4 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 lam/docs/manual-sources/images/mod_personal2.png diff --git a/lam/HISTORY b/lam/HISTORY index ee01cf89..4dcbb324 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -1,5 +1,6 @@ March 2013 4.1 - updated EDU person module (RFE 3599128) + - Personal: allow management of user certificates (RFE 1753030) - fixed bugs: -> changed user and group size limits (3601649) diff --git a/lam/docs/manual-sources/howto.xml b/lam/docs/manual-sources/howto.xml index 120c1096..2aea7a6d 100644 --- a/lam/docs/manual-sources/howto.xml +++ b/lam/docs/manual-sources/howto.xml @@ -1605,7 +1605,16 @@ Have fun! - + User certificates can be uploaded and downloaded. LAM will + automatically convert PEM to DER format. + + + + + + + + LDAP attribute mappings @@ -1788,6 +1797,12 @@ Have fun! Job title + + userCertificate + + User certificates + + uid/userid diff --git a/lam/docs/manual-sources/images/mod_personal2.png b/lam/docs/manual-sources/images/mod_personal2.png new file mode 100644 index 0000000000000000000000000000000000000000..e3aaf4b9540f35fcae0f2ab7294f7a84bee1b9a3 GIT binary patch literal 42516 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

JBl{rfY618r;Tfv>4!L7eewChbkm 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 Gp8XdT-_3&n literal 0 HcmV?d00001 diff --git a/lam/lib/modules/inetOrgPerson.inc b/lam/lib/modules/inetOrgPerson.inc index 7ef4d977..d267d99e 100644 --- a/lam/lib/modules/inetOrgPerson.inc +++ b/lam/lib/modules/inetOrgPerson.inc @@ -78,7 +78,7 @@ class inetOrgPerson extends baseModule implements passwordService { $this->messages['uid'][1] = array('ERROR', _('Account %s:') . ' inetOrgPerson_userName', _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); $this->messages['uid'][3] = array('ERROR', _('Account %s:') . ' inetOrgPerson_userName', _('User name already exists!')); $this->messages['manager'][0] = array('ERROR', _('Account %s:') . ' inetOrgPerson_manager', _('This is not a valid DN!')); - $this->messages['photo'][0] = array('ERROR', _('No file selected.')); + $this->messages['file'][0] = array('ERROR', _('No file selected.')); $this->messages['businessCategory'][0] = array('ERROR', _('Business category'), _('Please enter a valid business category!')); $this->messages['businessCategory'][1] = array('ERROR', _('Account %s:') . ' inetOrgPerson_businessCategory', _('Please enter a valid business category!')); $this->messages['userPassword'][0] = array('ERROR', _('Account %s:') . ' posixAccount_password', _('Password contains invalid characters. Valid characters are:') . ' a-z, A-Z, 0-9 and #*,.;:_-+!%&/|?{[()]}=@$ §°!'); @@ -117,7 +117,7 @@ class inetOrgPerson extends baseModule implements passwordService { $return['attributes'] = array('uid', 'cn', 'employeeType', 'givenName', 'jpegPhoto', 'mail', 'manager', 'mobile', 'title', 'telephoneNumber', 'facsimileTelephoneNumber', 'street', 'postOfficeBox', 'postalCode', 'postalAddress', 'sn', 'userPassword', 'description', 'homePhone', 'roomNumber', 'businessCategory', 'l', 'st', 'physicalDeliveryOfficeName', - 'carLicense', 'departmentNumber', 'o', 'employeeNumber', 'initials', 'registeredAddress', 'labeledURI', 'ou'); + 'carLicense', 'departmentNumber', 'o', 'employeeNumber', 'initials', 'registeredAddress', 'labeledURI', 'ou', 'userCertificate;binary'); // self service search attributes $return['selfServiceSearchAttributes'] = array('uid', 'mail', 'cn', 'surname', 'givenName', 'employeeNumber'); // self service field settings @@ -127,11 +127,12 @@ class inetOrgPerson extends baseModule implements passwordService { 'postalCode' => _('Postal code'), 'postOfficeBox' => _('Post office box'), 'jpegPhoto' => _('Photo'), 'homePhone' => _('Home telephone number'), 'roomNumber' => _('Room number'), 'carLicense' => _('Car license'), 'location' => _('Location'), 'state' => _('State'), 'officeName' => _('Office name'), 'businessCategory' => _('Business category'), - 'departmentNumber' => _('Department'), 'initials' => _('Initials'), 'title' => _('Job title'), 'labeledURI' => _('Web site')); + 'departmentNumber' => _('Department'), 'initials' => _('Initials'), 'title' => _('Job title'), 'labeledURI' => _('Web site'), + 'userCertificate' => _('User certificates')); // possible self service read-only fields $return['selfServiceReadOnlyFields'] = array('firstName', 'lastName', 'mail', 'telephoneNumber', 'mobile', 'faxNumber', 'street', 'postalAddress', 'registeredAddress', 'postalCode', 'postOfficeBox', 'jpegPhoto', 'homePhone', 'roomNumber', 'carLicense', - 'location', 'state', 'officeName', 'businessCategory', 'departmentNumber', 'initials', 'title', 'labeledURI'); + 'location', 'state', 'officeName', 'businessCategory', 'departmentNumber', 'initials', 'title', 'labeledURI', 'userCertificate'); // profile elements $profileElements = array(); if (!$this->isBooleanConfigOptionSet('inetOrgPerson_hideInitials')) { @@ -313,6 +314,8 @@ class inetOrgPerson extends baseModule implements passwordService { $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('inetOrgPerson_hideInitials', false, _('Initials'), null, false)); $configContainerOptions->addNewLine(); $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('inetOrgPerson_hideLabeledURI', false, _('Web site'), null, false)); + $configContainerOptions->addElement(new htmlOutputText(' ')); + $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('inetOrgPerson_hideuserCertificate', false, _('User certificates'), null, false)); $configContainer->addElement($configContainerOptions, true); if (isset($_SESSION['conf_config'])) { // add password hash type if posixAccount is inactive @@ -842,6 +845,10 @@ class inetOrgPerson extends baseModule implements passwordService { "Headline" => _("Password"), "Text" => _("Please enter the password which you want to set for this account.") ), + 'userCertificate' => array( + "Headline" => _('User certificates'), + "Text" => _('These are the user\'s certificates.') + ), ); return $return; } @@ -1743,7 +1750,8 @@ class inetOrgPerson extends baseModule implements passwordService { if (!$this->isBooleanConfigOptionSet('inetOrgPerson_hideJobTitle') || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideCarLicense') || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideEmployeeType') || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideBusinessCategory') - || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideDepartments') || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideManager')) { + || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideDepartments') || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideManager') + || !$this->isBooleanConfigOptionSet('inetOrgPerson_hideuserCertificate')) { $fieldContainer->addElement(new htmlSubTitle(_('Work details')), true); } @@ -1852,6 +1860,20 @@ class inetOrgPerson extends baseModule implements passwordService { $oHelp->alignment = htmlElement::ALIGN_TOP; $fieldContainer->addElement($oHelp, true); } + // user certificates + if (!$this->isBooleanConfigOptionSet('inetOrgPerson_hideuserCertificate')) { + $fieldContainer->addElement(new htmlOutputText(_('User certificates'))); + $userCertificateGroup = new htmlGroup(); + $userCertificateCount = 0; + if (isset($this->attributes['userCertificate;binary'])) { + $userCertificateCount = sizeof($this->attributes['userCertificate;binary']); + } + $userCertificateGroup->addElement(new htmlOutputText($userCertificateCount)); + $userCertificateGroup->addElement(new htmlSpacer('10px', null)); + $userCertificateGroup->addElement(new htmlAccountPageButton(get_class($this), 'userCertificate', 'manage', _('Manage'))); + $fieldContainer->addElement($userCertificateGroup); + $fieldContainer->addElement(new htmlHelpLink('userCertificate'), true); + } // manager if (!$this->isBooleanConfigOptionSet('inetOrgPerson_hideManager')) { $fieldContainer->addElement(new htmlOutputText(_('Manager'))); @@ -1922,7 +1944,7 @@ class inetOrgPerson extends baseModule implements passwordService { $this->attributes['jpegPhoto'][0] = $data; } else { - $messages[] = $this->messages['photo'][0]; + $messages[] = $this->messages['file'][0]; } return $messages; } @@ -2044,6 +2066,103 @@ class inetOrgPerson extends baseModule implements passwordService { return $return; } + /** + * Displays the certificate upload page. + * + * @return array meta HTML code + */ + function display_html_userCertificate() { + $container = new htmlTable(); + if (isset($this->attributes['userCertificate;binary'])) { + $table = new htmlTable(); + $table->colspan = 10; + for ($i = 0; $i < sizeof($this->attributes['userCertificate;binary']); $i++) { + $filename = 'userCertificate' . $_SESSION['ldap']->new_rand() . '.der'; + $out = @fopen(dirname(__FILE__) . '/../../tmp/' . $filename, "wb"); + fwrite($out, $this->attributes['userCertificate;binary'][$i]); + fclose ($out); + $path = '../../tmp/' . $filename; + $link = new htmlLink('', $path, '../../graphics/save.png'); + $link->setTargetWindow('_blank'); + $table->addElement($link); + $deleteButton = new htmlAccountPageButton(get_class($this), 'userCertificate', 'delete_' . $i, 'delete.png', true); + $deleteButton->setIconClass('deleteButton'); + $table->addElement($deleteButton); + if (function_exists('openssl_x509_parse')) { + $pem = @chunk_split(@base64_encode($this->attributes['userCertificate;binary'][$i]), 64, "\n"); + if (!empty($pem)) { + $pem = "-----BEGIN CERTIFICATE-----\n" . $pem . "-----END CERTIFICATE-----\n"; + $pemData = @openssl_x509_parse($pem); + $data = array(); + if (isset($pemData['serialNumber'])) { + $data[] = $pemData['serialNumber']; + } + if (isset($pemData['name'])) { + $data[] = $pemData['name']; + } + if (sizeof($data) > 0) { + $table->addElement(new htmlOutputText(implode(': ', $data))); + } + } + } + $table->addNewLine(); + } + $container->addElement($table, true); + $container->addElement(new htmlSpacer(null, '20px'), true); + } + $newGroup = new htmlGroup(); + $newGroup->addElement(new htmlOutputText(_('New user certificate'))); + $newGroup->addElement(new htmlSpacer('1px', null)); + $newGroup->addElement(new htmlInputFileUpload('userCertificateUpload')); + $newGroup->addElement(new htmlSpacer('1px', null)); + $uploadButton = new htmlAccountPageButton(get_class($this), 'userCertificate', 'submit', _('Upload')); + $uploadButton->setIconClass('upButton'); + $newGroup->addElement($uploadButton); + $container->addElement($newGroup, true); + $container->addElement(new htmlSpacer(null, '10px'), true); + $container->addElement(new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back'))); + return $container; + } + + /** + * Sets a new certificate or deletes old ones. + */ + function process_userCertificate() { + $messages = array(); + if (isset($_POST['form_subpage_' . get_class($this) . '_userCertificate_submit'])) { + if ($_FILES['userCertificateUpload'] && ($_FILES['userCertificateUpload']['size'] > 0)) { + $handle = fopen($_FILES['userCertificateUpload']['tmp_name'], "r"); + $data = fread($handle, 10000000); + fclose($handle); + if (strpos($data, '-----BEGIN CERTIFICATE-----') === 0) { + $pemData = str_replace("\r", '', $data); + $pemData = explode("\n", $pemData); + array_shift($pemData); + $last = array_pop($pemData); + while (($last != '-----END CERTIFICATE-----') && sizeof($pemData) > 2) { + $last = array_pop($pemData); + } + $pemData = implode('', $pemData); + $data = base64_decode($pemData); + } + $this->attributes['userCertificate;binary'][] = $data; + } + else { + $messages[] = $this->messages['file'][0]; + } + } + elseif (isset($this->attributes['userCertificate;binary'])) { + for ($i = 0; $i < sizeof($this->attributes['userCertificate;binary']); $i++) { + if (isset($_POST['form_subpage_' . get_class($this) . '_userCertificate_delete_' . $i])) { + unset($this->attributes['userCertificate;binary'][$i]); + $this->attributes['userCertificate;binary'] = array_values($this->attributes['userCertificate;binary']); + break; + } + } + } + return $messages; + } + /** * Returns the PDF entries for this module. *