From 9556cd9e6908d6906717a89fff12b046beaeb7fd Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 6 Sep 2015 19:15:49 -0500 Subject: Add LUKS key management to tdehwmanager --- kcontrol/hwmanager/CMakeLists.txt | 3 +- kcontrol/hwmanager/cryptpassworddlg.cpp | 115 +++++++++++++++++++++++++ kcontrol/hwmanager/cryptpassworddlg.h | 61 +++++++++++++ kcontrol/hwmanager/cryptpassworddlgbase.ui | 132 +++++++++++++++++++++++++++++ kcontrol/hwmanager/devicepropsdlg.cpp | 115 +++++++++++++++++++++++++ kcontrol/hwmanager/devicepropsdlg.h | 6 ++ kcontrol/hwmanager/devicepropsdlgbase.ui | 93 +++++++++++++++++++- 7 files changed, 522 insertions(+), 3 deletions(-) create mode 100644 kcontrol/hwmanager/cryptpassworddlg.cpp create mode 100644 kcontrol/hwmanager/cryptpassworddlg.h create mode 100644 kcontrol/hwmanager/cryptpassworddlgbase.ui (limited to 'kcontrol') diff --git a/kcontrol/hwmanager/CMakeLists.txt b/kcontrol/hwmanager/CMakeLists.txt index 584eba7bc..8b46dd98e 100644 --- a/kcontrol/hwmanager/CMakeLists.txt +++ b/kcontrol/hwmanager/CMakeLists.txt @@ -33,7 +33,8 @@ set_source_files_properties( hwmanager.cpp PROPERTIES COMPILE_FLAGS -DKDE_CONFDI tde_add_kpart( kcm_hwmanager AUTOMOC SOURCES - hwmanager.cpp deviceiconview.cpp devicepropsdlg.cpp devicepropsdlgbase.ui hwmanagerbase.ui hwmanager.skel + hwmanager.cpp deviceiconview.cpp devicepropsdlg.cpp devicepropsdlgbase.ui hwmanagerbase.ui + cryptpassworddlg.cpp cryptpassworddlgbase.ui hwmanager.skel LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/kcontrol/hwmanager/cryptpassworddlg.cpp b/kcontrol/hwmanager/cryptpassworddlg.cpp new file mode 100644 index 000000000..43d714e12 --- /dev/null +++ b/kcontrol/hwmanager/cryptpassworddlg.cpp @@ -0,0 +1,115 @@ +/* This file is part of TDE + Copyright (C) 2015 Timothy Pearson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef Unsorted // Required for --enable-final (tqdir.h) +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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) +{ + m_base = new CryptPasswordDialogBase(plainPage()); + + TQGridLayout *mainGrid = new TQGridLayout(plainPage(), 1, 1, 0, spacingHint()); + mainGrid->setRowStretch(1, 1); + mainGrid->addWidget(m_base, 0, 0); + + m_base->passwordPrompt->setText(passwordPrompt); + m_base->passwordIcon->setPixmap(SmallIcon("password.png")); + + 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->textPasswordEntry, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); + connect(m_base->filePasswordURL, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); + + m_base->textPasswordEntry->setFocus(); + + processLockouts(); +} + +CryptPasswordDialog::~CryptPasswordDialog() +{ +} + +TQByteArray CryptPasswordDialog::password() { + if (m_base->textPasswordButton->isOn() == true) { + m_password.duplicate(m_base->textPasswordEntry->password(), strlen(m_base->textPasswordEntry->password())); + } + else { + m_password = TQFile(m_base->filePasswordURL->url()).readAll(); + } + + return m_password; +} + +void CryptPasswordDialog::processLockouts() { + if (m_base->textPasswordButton->isOn() == true) { + m_base->textPasswordEntry->setEnabled(true); + m_base->filePasswordURL->setEnabled(false); + if (strlen(m_base->textPasswordEntry->password()) > 0) { + enableButtonOK(true); + } + else { + enableButtonOK(false); + } + } + else { + m_base->textPasswordEntry->setEnabled(false); + m_base->filePasswordURL->setEnabled(true); + if (TQFile(m_base->filePasswordURL->url()).exists()) { + enableButtonOK(true); + } + else { + enableButtonOK(false); + } + } +} + +void CryptPasswordDialog::virtual_hook( int id, void* data ) +{ KDialogBase::virtual_hook( id, data ); } + +#include "cryptpassworddlg.moc" diff --git a/kcontrol/hwmanager/cryptpassworddlg.h b/kcontrol/hwmanager/cryptpassworddlg.h new file mode 100644 index 000000000..8cec6e55b --- /dev/null +++ b/kcontrol/hwmanager/cryptpassworddlg.h @@ -0,0 +1,61 @@ +/* This file is part of TDE + Copyright (C) 2015 Timothy Pearson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef __cryptpassworddlg_h__ +#define __cryptpassworddlg_h__ + +#include + +#include "cryptpassworddlgbase.h" + +/** + * + * Dialog to enter LUKS passwords or password files + * + * @version 0.1 + * @author Timothy Pearson + */ + +class TDEUI_EXPORT CryptPasswordDialog : public KDialogBase +{ + Q_OBJECT +public: + /** + * 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); + virtual ~CryptPasswordDialog(); + + TQByteArray password(); + +protected: + virtual void virtual_hook( int id, void* data ); + +private slots: + void processLockouts(); + +private: + CryptPasswordDialogBase* m_base; + TQByteArray m_password; + + class CryptPasswordDialogPrivate; + CryptPasswordDialogPrivate* d; +}; + +#endif diff --git a/kcontrol/hwmanager/cryptpassworddlgbase.ui b/kcontrol/hwmanager/cryptpassworddlgbase.ui new file mode 100644 index 000000000..7c61187ae --- /dev/null +++ b/kcontrol/hwmanager/cryptpassworddlgbase.ui @@ -0,0 +1,132 @@ + + CryptPasswordDialogBase + + + CryptPasswordDialogBase + + + + unnamed + + + + passwordIcon + + + + 4 + 5 + 0 + 0 + + + + + + passwordPrompt + + + + + + + + passwordProps + + + Password Source + + + + unnamed + + + + enabledBox + + + + 5 + 5 + 0 + 0 + + + + NoFrame + + + Plain + + + + + + true + + + true + + + 0 + + + + unnamed + + + 0 + + + + textPasswordButton + + + Text: + + + true + + + + + textPasswordEntry + + + + + filePasswordButton + + + File: + + + + + filePasswordURL + + + * + + + 17 + + + + + + + + + + CryptPasswordDialogBase.ui.h + + + enableSupport_toggled(bool) + + + kdialog.h + + + + diff --git a/kcontrol/hwmanager/devicepropsdlg.cpp b/kcontrol/hwmanager/devicepropsdlg.cpp index b14177ca3..7ce36f1b3 100644 --- a/kcontrol/hwmanager/devicepropsdlg.cpp +++ b/kcontrol/hwmanager/devicepropsdlg.cpp @@ -32,14 +32,18 @@ #undef Unsorted // Required for --enable-final (tqdir.h) #include +#include #include #include #include #include #include +#include #include #include +#include "cryptpassworddlg.h" + #include "devicepropsdlg.h" SensorDisplayLabelsWidget::SensorDisplayLabelsWidget(TQWidget *parent) @@ -255,6 +259,7 @@ DevicePropertiesDialog::DevicePropertiesDialog(TDEGenericDevice* device, TQWidge // Remove all non-applicable tabs if (m_device->type() != TDEGenericDeviceType::Disk) { base->tabBarWidget->removePage(base->tabDisk); + base->tabBarWidget->removePage(base->tabDiskCrypt); } if (m_device->type() != TDEGenericDeviceType::CPU) { base->tabBarWidget->removePage(base->tabCPU); @@ -291,8 +296,21 @@ DevicePropertiesDialog::DevicePropertiesDialog(TDEGenericDevice* device, TQWidge connect(base->comboCPUGovernor, TQT_SIGNAL(activated(const TQString &)), this, TQT_SLOT(setCPUGovernor(const TQString &))); } if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast(m_device); connect(base->buttonDiskMount, TQT_SIGNAL(clicked()), this, TQT_SLOT(mountDisk())); connect(base->buttonDiskUnmount, TQT_SIGNAL(clicked()), this, TQT_SLOT(unmountDisk())); + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { + connect(base->cryptLUKSAddKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(cryptLUKSAddKey())); + connect(base->cryptLUKSDelKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(cryptLUKSDelKey())); + connect(base->cryptLUKSKeySlotList, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(processLockouts())); + base->cryptLUKSKeySlotList->setAllColumnsShowFocus(true); + base->cryptLUKSKeySlotList->setFullWidth(true); + cryptLUKSPopulateList(); + processLockouts(); + } + else { + base->tabBarWidget->removePage(base->tabDiskCrypt); + } } if ((m_device->type() == TDEGenericDeviceType::OtherSensor) || (m_device->type() == TDEGenericDeviceType::ThermalSensor)) { @@ -860,6 +878,103 @@ void DevicePropertiesDialog::unmountDisk() { populateDeviceInformation(); } +void DevicePropertiesDialog::cryptLUKSAddKey() { + if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast(m_device); + + TQListViewItem* lvi = base->cryptLUKSKeySlotList->selectedItem(); + if (lvi) { + TQByteArray new_password; + CryptPasswordDialog* passDlg = new CryptPasswordDialog(this, i18n("Enter the new LUKS password for key slot %1").arg(lvi->text(0))); + if (passDlg->exec() == TQDialog::Accepted) { + new_password = passDlg->password(); + delete passDlg; + if (!sdevice->cryptOperationsUnlockPasswordSet()) { + TQCString password; + passDlg = new CryptPasswordDialog(this, i18n("Enter the LUKS device unlock password")); + if (passDlg->exec() == TQDialog::Accepted) { + sdevice->cryptSetOperationsUnlockPassword(passDlg->password()); + } + delete passDlg; + } + if (sdevice->cryptOperationsUnlockPasswordSet()) { + if ((lvi->text(1) == sdevice->cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::Inactive)) || (KMessageBox::warningYesNo(this, i18n("You are about to overwrite the key in key slot %1
This action cannot be undone

Are you sure you want to proceed?").arg(lvi->text(0)), i18n("Confirmation Required")) == KMessageBox::Yes)) { + if (sdevice->cryptAddKey(lvi->text(0).toUInt(), new_password) != TDELUKSResult::Success) { + sdevice->cryptClearOperationsUnlockPassword(); + KMessageBox::error(this, i18n("Key write failed
Please check the LUKS password and try again
"), i18n("Key write failure")); + } + } + } + } + else { + delete passDlg; + } + } + } + + cryptLUKSPopulateList(); +} + +void DevicePropertiesDialog::cryptLUKSDelKey() { + if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast(m_device); + + TQListViewItem* lvi = base->cryptLUKSKeySlotList->selectedItem(); + if (lvi) { + if (KMessageBox::warningYesNo(this, i18n("You are about to purge the key in key slot %1
This action cannot be undone

Are you sure you want to proceed?").arg(lvi->text(0)), i18n("Confirmation Required")) == KMessageBox::Yes) { + if (sdevice->cryptKeySlotStatus()[lvi->text(0).toUInt()] & TDELUKSKeySlotStatus::Last) { + if (KMessageBox::warningYesNo(this, i18n("You are about to purge the last active key from the device!

This action will render the contents of the encrypted device permanently inaccessable and cannot be undone

Are you sure you want to proceed?"), i18n("Confirmation Required")) != KMessageBox::Yes) { + cryptLUKSPopulateList(); + return; + } + } + if (sdevice->cryptDelKey(lvi->text(0).toUInt()) != TDELUKSResult::Success) { + sdevice->cryptClearOperationsUnlockPassword(); + KMessageBox::error(this, i18n("Key purge failed
The key in key slot %1 is still active
").arg(lvi->text(0)), i18n("Key purge failure")); + } + } + } + } + + cryptLUKSPopulateList(); +} + +void DevicePropertiesDialog::cryptLUKSPopulateList() { + unsigned int i; + TDEStorageDevice* sdevice = static_cast(m_device); + + base->cryptLUKSKeySlotList->clear(); + unsigned int count = sdevice->cryptKeySlotCount(); + TDELUKSKeySlotStatusList status = sdevice->cryptKeySlotStatus(); + for (i = 0; i < count; i++) { + new TQListViewItem(base->cryptLUKSKeySlotList, TQString("%1").arg(i), sdevice->cryptKeySlotFriendlyName(status[i])); + } + + processLockouts(); +} + +void DevicePropertiesDialog::processLockouts() { + if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast(m_device); + + TQListViewItem* lvi = base->cryptLUKSKeySlotList->selectedItem(); + if (lvi) { + if (lvi->text(1) == sdevice->cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::Active)) { + base->cryptLUKSAddKey->setEnabled(true); + base->cryptLUKSDelKey->setEnabled(true); + } + else { + base->cryptLUKSAddKey->setEnabled(true); + base->cryptLUKSDelKey->setEnabled(false); + } + } + else { + base->cryptLUKSAddKey->setEnabled(false); + base->cryptLUKSDelKey->setEnabled(false); + } + } +} + void DevicePropertiesDialog::virtual_hook( int id, void* data ) { KDialogBase::virtual_hook( id, data ); } diff --git a/kcontrol/hwmanager/devicepropsdlg.h b/kcontrol/hwmanager/devicepropsdlg.h index 0b8553c96..e958d39ba 100644 --- a/kcontrol/hwmanager/devicepropsdlg.h +++ b/kcontrol/hwmanager/devicepropsdlg.h @@ -191,10 +191,16 @@ private slots: void mountDisk(); void unmountDisk(); + void cryptLUKSAddKey(); + void cryptLUKSDelKey(); + void cryptLUKSPopulateList(); + void cryptographicCardInserted(); void cryptographicCardRemoved(); void updateCryptographicCardStatusDisplay(); + void processLockouts(); + private: TDEGenericDevice* m_device; DevicePropertiesDialogBase* base; diff --git a/kcontrol/hwmanager/devicepropsdlgbase.ui b/kcontrol/hwmanager/devicepropsdlgbase.ui index 1be078c43..de77d5f91 100644 --- a/kcontrol/hwmanager/devicepropsdlgbase.ui +++ b/kcontrol/hwmanager/devicepropsdlgbase.ui @@ -326,7 +326,7 @@ unnamed - + buttonDiskMount @@ -334,7 +334,7 @@ Mount - + buttonDiskUnmount @@ -363,6 +363,95 @@ + + + tabDiskCrypt + + + LUKS + + + + unnamed + + + + groupLUKSProps + + + LUKS Information + + + + unnamed + + + + + Slot Number + + + true + + + true + + + + + Status + + + true + + + true + + + + cryptLUKSKeySlotList + + + false + + + + + cryptLUKSAddKey + + + Install new password into keyslot + + + + + cryptLUKSDelKey + + + Delete existing password from keyslot + + + + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + tabCPU -- cgit v1.2.3