Branch: master

6095bc10 2015-09-14 20:46:15 Timothy Pearson
Add cryptographic card support to LUKS configuration
M kcontrol/hwmanager/cryptpassworddlg.cpp
M kcontrol/hwmanager/cryptpassworddlg.h
M kcontrol/hwmanager/cryptpassworddlgbase.ui
M kcontrol/hwmanager/devicepropsdlg.cpp
M kcontrol/hwmanager/devicepropsdlgbase.ui
M kcontrol/hwmanager/hwmanager.cpp
M kcontrol/hwmanager/hwmanager.h
diff --git a/kcontrol/hwmanager/cryptpassworddlg.cpp b/kcontrol/hwmanager/cryptpassworddlg.cpp
index 43d714e..1d66d89 100644
--- a/kcontrol/hwmanager/cryptpassworddlg.cpp
+++ b/kcontrol/hwmanager/cryptpassworddlg.cpp
@@ -46,11 +46,13 @@
 #include <kpushbutton.h>
 #include <kstdguiitem.h>
 #include <tdemessagebox.h>
+#include <ksslcertificate.h>
 
 #include "cryptpassworddlg.h"
 
-CryptPasswordDialog::CryptPasswordDialog(TQWidget *parent, TQString passwordPrompt, TQString caption)
-	: KDialogBase(Plain, ((caption == "")?i18n("Enter Password"):caption), Ok|Cancel, Ok, parent, 0L, true, true)
+CryptPasswordDialog::CryptPasswordDialog(TQWidget *parent, TQString passwordPrompt, TQString caption, bool allow_card, KSSLCertificate* card_cert, bool* use_card)
+	: KDialogBase(Plain, ((caption == "")?i18n("Enter Password"):caption), Ok|Cancel, Ok, parent, 0L, true, true),
+	m_useCard(use_card)
 {
 	m_base = new CryptPasswordDialogBase(plainPage());
 
@@ -61,8 +63,19 @@
 	m_base->passwordPrompt->setText(passwordPrompt);
 	m_base->passwordIcon->setPixmap(SmallIcon("password.png"));
 
+	if (!allow_card) {
+		m_base->cardKeyButton->hide();
+		m_base->cardKeyInfo->hide();
+	}
+	else {
+		if (card_cert) {
+			m_base->cardKeyInfo->setText(card_cert->getSubject());
+		}
+	}
+
 	connect(m_base->textPasswordButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts()));
 	connect(m_base->filePasswordButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts()));
+	connect(m_base->cardKeyButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts()));
 	connect(m_base->textPasswordEntry, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts()));
 	connect(m_base->filePasswordURL, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts()));
 
@@ -78,9 +91,14 @@
 TQByteArray CryptPasswordDialog::password() {
 	if (m_base->textPasswordButton->isOn() == true) {
 		m_password.duplicate(m_base->textPasswordEntry->password(), strlen(m_base->textPasswordEntry->password()));
+		if (m_useCard) *m_useCard = false;
+	}
+	else if (m_base->filePasswordButton->isOn() == true) {
+		m_password = TQFile(m_base->filePasswordURL->url()).readAll();
+		if (m_useCard) *m_useCard = false;
 	}
 	else {
-		m_password = TQFile(m_base->filePasswordURL->url()).readAll();
+		if (m_useCard) *m_useCard = true;
 	}
 
 	return m_password;
@@ -90,7 +108,19 @@
 	if (m_base->textPasswordButton->isOn() == true) {
 		m_base->textPasswordEntry->setEnabled(true);
 		m_base->filePasswordURL->setEnabled(false);
+		m_base->textPasswordEntry->setFocus();
 		if (strlen(m_base->textPasswordEntry->password()) > 0) {
+			enableButtonOK(true);
+		}
+		else {
+			enableButtonOK(false);
+		}
+	}
+	else if (m_base->filePasswordButton->isOn() == true) {
+		m_base->textPasswordEntry->setEnabled(false);
+		m_base->filePasswordURL->setEnabled(true);
+		m_base->filePasswordURL->setFocus();
+		if (TQFile(m_base->filePasswordURL->url()).exists()) {
 			enableButtonOK(true);
 		}
 		else {
@@ -99,13 +129,8 @@
 	}
 	else {
 		m_base->textPasswordEntry->setEnabled(false);
-		m_base->filePasswordURL->setEnabled(true);
-		if (TQFile(m_base->filePasswordURL->url()).exists()) {
-			enableButtonOK(true);
-		}
-		else {
-			enableButtonOK(false);
-		}
+		m_base->filePasswordURL->setEnabled(false);
+		enableButtonOK(true);
 	}
 }
 
diff --git a/kcontrol/hwmanager/cryptpassworddlg.h b/kcontrol/hwmanager/cryptpassworddlg.h
index 8cec6e5..d595c4a 100644
--- a/kcontrol/hwmanager/cryptpassworddlg.h
+++ b/kcontrol/hwmanager/cryptpassworddlg.h
@@ -23,6 +23,8 @@
 
 #include "cryptpassworddlgbase.h"
 
+class KSSLCertificate;
+
 /**
  *
  * Dialog to enter LUKS passwords or password files
@@ -39,7 +41,7 @@
 	* Create a dialog that allows a user to enter LUKS passwords or password files
 	* @param parent     Parent widget
 	*/
-	CryptPasswordDialog(TQWidget *parent, TQString passwordPrompt, TQString caption=TQString::null);
+	CryptPasswordDialog(TQWidget *parent, TQString passwordPrompt, TQString caption=TQString::null, bool allow_card=false, KSSLCertificate* card_cert=NULL, bool* use_card=NULL);
 	virtual ~CryptPasswordDialog();
 
 	TQByteArray password();
@@ -53,6 +55,7 @@
 private:
 	CryptPasswordDialogBase* m_base;
 	TQByteArray m_password;
+	bool* m_useCard;
 
 	class CryptPasswordDialogPrivate;
 	CryptPasswordDialogPrivate* d;
diff --git a/kcontrol/hwmanager/cryptpassworddlgbase.ui b/kcontrol/hwmanager/cryptpassworddlgbase.ui
index 7c61187..549a591 100644
--- a/kcontrol/hwmanager/cryptpassworddlgbase.ui
+++ b/kcontrol/hwmanager/cryptpassworddlgbase.ui
@@ -112,6 +112,22 @@
 									<number>17</number>
 								</property>
 							</widget>
+							<widget class="TQRadioButton" row="2" column="0" colspan="1">
+								<property name="name">
+									<cstring>cardKeyButton</cstring>
+								</property>
+								<property name="text">
+									<string>Cryptographic Card</string>
+								</property>
+							</widget>
+							<widget class="TQLabel" row="2" column="1" colspan="1">
+								<property name="name">
+									<cstring>cardKeyInfo</cstring>
+								</property>
+								<property name="text">
+									<string></string>
+								</property>
+							</widget>
 						</grid>
 					</widget>
 				</grid>
diff --git a/kcontrol/hwmanager/devicepropsdlg.cpp b/kcontrol/hwmanager/devicepropsdlg.cpp
index 7ce36f1..a1ef81c 100644
--- a/kcontrol/hwmanager/devicepropsdlg.cpp
+++ b/kcontrol/hwmanager/devicepropsdlg.cpp
@@ -41,6 +41,7 @@
 #include <kpushbutton.h>
 #include <kstdguiitem.h>
 #include <tdemessagebox.h>
+#include <ksslcertificate.h>
 
 #include "cryptpassworddlg.h"
 
@@ -800,12 +801,47 @@
 	int status = cdevice->cardPresent();
 	if ((status < 0) ||(status > 1)) {
 		base->labelCardStatus->setText(i18n("Unknown"));
+		base->labelCardCertificates->setText("");
+		base->groupCardCerts->hide();
 	}
 	else if (status == 0) {
 		base->labelCardStatus->setText(i18n("Empty"));
+		base->labelCardCertificates->setText("");
+		base->groupCardCerts->hide();
 	}
 	else if (status == 1) {
 		base->labelCardStatus->setText(i18n("Inserted") + TQString("<br>") + i18n("ATR: %1").arg(cdevice->cardATR()));
+
+		X509CertificatePtrList certList = cdevice->cardX509Certificates();
+
+		if (certList.count() > 0) {
+			// Assemble list of certificates on card
+			unsigned int certificate_number = 1;
+			TQString certInfo = "<qt>";
+			X509CertificatePtrList::iterator it;
+			for (it = certList.begin(); it != certList.end(); ++it) {
+				KSSLCertificate* tdeCert = KSSLCertificate::fromX509(*it);
+				KSSLCertificate::KSSLValidation validationStatus = tdeCert->validate();
+				certInfo += i18n("Certificate #%1").arg(certificate_number) + ":<br>";
+				certInfo += i18n("Subject") + ": " + tdeCert->getSubject() + "<br>";
+				certInfo += i18n("Issuer") + ": " + tdeCert->getIssuer() + "<br>";
+				certInfo += i18n("Status") + ": " + KSSLCertificate::verifyText(validationStatus) + "<br>";
+				certInfo += i18n("Valid From") + ": " + tdeCert->getNotBefore() + "<br>";
+				certInfo += i18n("Valid Until") + ": " + tdeCert->getNotAfter() + "<br>";
+				certInfo += i18n("Serial Number") + ": " + tdeCert->getSerialNumber() + "<br>";
+				certInfo += i18n("MD5 Digest") + ": " + tdeCert->getMD5DigestText() + "<br>";
+				certInfo += "<p>";
+				delete tdeCert;
+				certificate_number++;
+			}
+			certInfo += "</qt>";
+			base->labelCardCertificates->setText(certInfo);
+			base->groupCardCerts->show();
+		}
+		else {
+			base->labelCardCertificates->setText("");
+			base->groupCardCerts->hide();
+		}
 	}
 }
 
@@ -879,27 +915,169 @@
 }
 
 void DevicePropertiesDialog::cryptLUKSAddKey() {
+	int retcode;
+
 	if (m_device->type() == TDEGenericDeviceType::Disk) {
 		TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(m_device);
 
 		TQListViewItem* lvi = base->cryptLUKSKeySlotList->selectedItem();
 		if (lvi) {
+			TDECryptographicCardDevice* cdevice = NULL;
+			unsigned int key_slot = lvi->text(0).toUInt();
+			bool allow_card = false;
+			bool use_card = false;
+			KSSLCertificate* card_cert = NULL;
+			X509* card_cert_x509;
+			TQString disk_uuid = sdevice->diskUUID();
+			TDEGenericDevice *hwdevice;
+			TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+			TDEGenericHardwareList cardReaderList = hwdevices->listByDeviceClass(TDEGenericDeviceType::CryptographicCard);
+			for (hwdevice = cardReaderList.first(); hwdevice; hwdevice = cardReaderList.next()) {
+				cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice);
+				X509CertificatePtrList certList = cdevice->cardX509Certificates();
+				if (certList.count() > 0) {
+					allow_card = true;
+					card_cert_x509 = certList[0];
+					card_cert = KSSLCertificate::fromX509(certList[0]);
+				}
+			}
 			TQByteArray new_password;
-			CryptPasswordDialog* passDlg = new CryptPasswordDialog(this, i18n("Enter the new LUKS password for key slot %1").arg(lvi->text(0)));
+			CryptPasswordDialog* passDlg = new CryptPasswordDialog(this, i18n("Enter the new LUKS password for key slot %1").arg(key_slot), TQString::null, allow_card, card_cert, &use_card);
 			if (passDlg->exec() == TQDialog::Accepted) {
 				new_password = passDlg->password();
+				if (allow_card && use_card) {
+					// Create new private key for disk device
+					if (!TQDir("/etc/trinity/luks").exists()) {
+						TQDir directory;
+						if (!directory.mkdir("/etc/trinity/luks", true)) {
+							KMessageBox::error(this, i18n("<qt><b>Key creation failed</b><br>Please check that you have write access to /etc/trinity and try again</qt>"), i18n("Key creation failure"));
 ** Diff limit reached (max: 250 lines) **