diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-09-01 19:26:00 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-09-01 19:26:00 -0500 |
commit | f4141d45b69e068fb8ed23d325402790b98a1ca6 (patch) | |
tree | a62eeffc0d463212ab58067f4eebaba3b9776fb2 | |
parent | 1ad8bf94dfd2f4d3a5d7ed89eae309d1f6bc8d06 (diff) | |
download | kcmldapmanager-f4141d45b69e068fb8ed23d325402790b98a1ca6.tar.gz kcmldapmanager-f4141d45b69e068fb8ed23d325402790b98a1ca6.zip |
Add ability to generate user PKI keys and certificates
-rw-r--r-- | src/ldapmgr.h | 2 | ||||
-rw-r--r-- | src/userconfigbase.ui | 121 | ||||
-rw-r--r-- | src/userconfigdlg.cpp | 66 | ||||
-rw-r--r-- | src/userconfigdlg.h | 1 |
4 files changed, 190 insertions, 0 deletions
diff --git a/src/ldapmgr.h b/src/ldapmgr.h index 48fe954..a366f6e 100644 --- a/src/ldapmgr.h +++ b/src/ldapmgr.h @@ -110,6 +110,8 @@ class LDAPConfig: public TDECModule LDAPGroupInfoList m_groupInfoList; LDAPMachineInfoList m_machineInfoList; LDAPServiceInfoList m_serviceInfoList; + + friend class UserConfigDialog; }; #endif diff --git a/src/userconfigbase.ui b/src/userconfigbase.ui index 61e44dc..e435ecf 100644 --- a/src/userconfigbase.ui +++ b/src/userconfigbase.ui @@ -841,6 +841,127 @@ </spacer> </grid> </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>passwordTab</cstring> + </property> + <attribute name="title"> + <string>Certificates and Cards</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0" colspan="1"> + <property name="name"> + <cstring>certificateIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="TQLabel" row="0" column="1" colspan="2"> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="text"> + <string>New PKI Certificate</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0" colspan="2"> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="text"> + <string>Expires:</string> + </property> + </widget> + <widget class="KDateWidget" row="1" column="2" colspan="3"> + <property name="name"> + <cstring>certificateExpirationDate</cstring> + </property> + <property name="enabled"> + <cstring>true</cstring> + </property> + </widget> + <widget class="TQLabel" row="2" column="0" colspan="2"> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="text"> + <string>Private key location:</string> + </property> + </widget> + <widget class="KURLRequester" row="2" column="2" colspan="1"> + <property name="name"> + <cstring>certPrivateKeyFileName</cstring> + </property> + <property name="filter"> + <cstring>*.key</cstring> + </property> + <property name="mode"> + <number>17</number> + </property> + </widget> + <widget class="TQCheckBox" row="2" column="4" colspan="1"> + <property name="name"> + <cstring>certGenPrivateKey</cstring> + </property> + <property name="text"> + <string>Create new private key</string> + </property> + </widget> + <widget class="TQLabel" row="3" column="0" colspan="2"> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="text"> + <string>Public certificate location:</string> + </property> + </widget> + <widget class="KURLRequester" row="3" column="2" colspan="3"> + <property name="name"> + <cstring>certPublicCertFileName</cstring> + </property> + <property name="filter"> + <cstring>*.pem</cstring> + </property> + <property name="mode"> + <number>17</number> + </property> + </widget> + <widget class="KPushButton" row="4" column="0" colspan="5"> + <property name="name"> + <cstring>createCertificate</cstring> + </property> + <property name="text"> + <string>Generate New PKI Certificate</string> + </property> + </widget> + <spacer row="10" column="0"> + <property name="name" stdset="0"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> </widget> </grid> </widget> diff --git a/src/userconfigdlg.cpp b/src/userconfigdlg.cpp index 8f23ed5..55c5d90 100644 --- a/src/userconfigdlg.cpp +++ b/src/userconfigdlg.cpp @@ -22,6 +22,9 @@ #include <klineedit.h> #include <ktextedit.h> #include <knuminput.h> +#include <tdetempfile.h> +#include <kstandarddirs.h> +#include <tdemessagebox.h> #include <tdeactionselector.h> #include <tqlistbox.h> #include <kpushbutton.h> @@ -32,6 +35,7 @@ #include <kcombobox.h> #include <tqradiobutton.h> #include <tqcheckbox.h> +#include <kdatewidget.h> #include <kdatetimewidget.h> #include <kpassdlg.h> #include <kiconloader.h> @@ -60,6 +64,7 @@ UserConfigDialog::UserConfigDialog(LDAPUserInfo user, LDAPConfig* parent, const m_base->userIcon->setPixmap(SmallIcon("personal.png")); m_base->groupsIcon->setPixmap(SmallIcon("tdmconfig.png")); m_base->passwordIcon->setPixmap(SmallIcon("password.png")); + m_base->certificateIcon->setPixmap(SmallIcon("password.png")); connect(m_base->loginName, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); connect(m_base->realName, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); @@ -70,6 +75,10 @@ UserConfigDialog::UserConfigDialog(LDAPUserInfo user, LDAPConfig* parent, const connect(m_base->requirePasswordAging, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); connect(m_base->requirePasswordMinAge, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); connect(m_base->primaryGroup, TQT_SIGNAL(activated(const TQString&)), this, TQT_SLOT(processLockouts())); + connect(m_base->certGenPrivateKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); + connect(m_base->certPrivateKeyFileName, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); + connect(m_base->certPublicCertFileName, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); + connect(m_base->createCertificate, TQT_SIGNAL(clicked()), this, TQT_SLOT(createPKICertificate())); if (m_user.status == KRB5_DISABLED_ACCOUNT) { m_base->userStatusEnabled->setChecked(false); @@ -128,6 +137,10 @@ UserConfigDialog::UserConfigDialog(LDAPUserInfo user, LDAPConfig* parent, const m_base->faxNumber->setText(m_user.faxNumber); m_base->email->setText(m_user.email); + // Certificate generation information + TQDateTime suggestedExpiration = TQDateTime::currentDateTime().addDays(KERBEROS_PKI_KRB_EXPIRY_DAYS); + m_base->certificateExpirationDate->setDate(suggestedExpiration.date()); + processLockouts(); } @@ -252,9 +265,62 @@ void UserConfigDialog::processLockouts() { } enableButton(KDialogBase::Ok, ok_enabled); + if (m_base->certPrivateKeyFileName->url() == "") { + ok_enabled = false; + } + if (m_base->certPublicCertFileName->url() == "") { + ok_enabled = false; + } + if (!m_base->certGenPrivateKey->isChecked()) { + if (!TQFile(m_base->certPrivateKeyFileName->url()).exists()) { + ok_enabled = false; + } + } + m_base->createCertificate->setEnabled(ok_enabled); + m_prevPrimaryGroup = m_base->primaryGroup->currentText(); } +void UserConfigDialog::createPKICertificate() { + TQString errorstring; + LDAPCertConfig certinfo; + LDAPRealmConfigList realms = LDAPManager::fetchAndReadTDERealmList(); + + certinfo.kerberosExpiryDays = TQDate::currentDate().daysTo(m_base->certificateExpirationDate->date()); + + if (m_base->certGenPrivateKey->isChecked()) { + // Generate new private key + if (LDAPManager::generateClientCertificatePrivateKey(m_user, realms[m_ldapconfig->m_ldapmanager->realm()], m_base->certPrivateKeyFileName->url(), &errorstring) != 0) { + KMessageBox::sorry(this, i18n("<qt><b>Unable to generate new private key</b><p>Details: %1</qt>").arg(errorstring), i18n("Unable to Obtain Certificate")); + return; + } + } + + // Get the CA root private key from LDAP + // WARNING + // Anyone with access to this key would be able to create accounts that could access any resource on the realm! + // Secure the key file accordingly... + KTempFile caPrivateKeyTempFile(locateLocal("tmp", "krbcakey"), ".key.pem", 0600); + caPrivateKeyTempFile.setAutoDelete(true); + TQFile* caPrivateKeyFile = caPrivateKeyTempFile.file(); + if (!caPrivateKeyFile) { + KMessageBox::sorry(this, i18n("<qt><b>Unable to obtain root certificate for realm %1!</b><p>Details: %2</qt>").arg(realms[m_ldapconfig->m_ldapmanager->realm()].name.upper()).arg(i18n("Unable to create or open temporary file '%s'").arg(caPrivateKeyTempFile.name())), i18n("Unable to Obtain Certificate")); + return; + } + if (m_ldapconfig->m_ldapmanager->getTDECertificate("privateRootCertificateKey", caPrivateKeyFile, &errorstring) != 0) { + KMessageBox::sorry(this, i18n("<qt><b>Unable to obtain root certificate for realm %1!</b><p>Details: %2</qt>").arg(realms[m_ldapconfig->m_ldapmanager->realm()].name.upper()).arg(errorstring), i18n("Unable to Obtain Certificate")); + return; + } + caPrivateKeyTempFile.sync(); + + if (LDAPManager::generateClientCertificatePublicCertificate(certinfo, m_user, realms[m_ldapconfig->m_ldapmanager->realm()], caPrivateKeyTempFile.name(), m_base->certPrivateKeyFileName->url(), m_base->certPublicCertFileName->url()) != 0) { + KMessageBox::sorry(this, i18n("<qt><b>Unable to generate or sign certificate</b><p>Details: %1</qt>").arg(errorstring), i18n("Unable to Create Certificate")); + } + + // Delete the private key as soon as possible after certificate signing + caPrivateKeyTempFile.unlink(); +} + LDAPUserInfo UserConfigDialog::userProperties() { return m_user; } diff --git a/src/userconfigdlg.h b/src/userconfigdlg.h index de5be1c..cb71b44 100644 --- a/src/userconfigdlg.h +++ b/src/userconfigdlg.h @@ -39,6 +39,7 @@ public: public slots: void slotOk(); void processLockouts(); + void createPKICertificate(); public: LDAPUserConfigBase *m_base; |