Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37535220
en ru br
ALT Linux repos
S:0.6-alt22

Group :: Graphical desktop/KDE
RPM: quick-usb-formatter

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: alt-crypto-luks.patch
Download


--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,8 @@ set(KCM_QUF_VERSION "${KCM_QUF_VERSION_M
 find_package(ECM 0.0.11 REQUIRED NO_MODULE)
 set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake/modules)
 
+set(CMAKE_CXX_STANDARD_LIBRARIES -lcryptsetup)
+
 include(KDEInstallDirs)
 include(KDECMakeSettings)
 include(KDECompilerSettings)
--- a/src/helper/helper.cpp
+++ b/src/helper/helper.cpp
@@ -19,26 +19,66 @@
 
 #include "helper.h"
 #include <klocalizedstring.h>
+#include <libcryptsetup.h>
 
 /**
  
  */
 ActionReply Helper::format(QVariantMap args)
 {
-    
+
     ActionReply reply = ActionReply::SuccessReply();
-    
-    
+
     // Is mounted ??
     if( args["mounted"].toBool() ){
         qDebug() << "Umounting device : " << args["device"].toString() ;
-        
+
         if(QProcess::execute("umount", QStringList() << args["device"].toString() ) != 0){
             reply = ActionReply::HelperErrorReply();
             reply.addData("errorDescription", i18n("umount failed"));
             return reply;
         }
     }
+
+    if (args["makecrypt"].toBool()) {
+
+        int retval;
+        QByteArray ba;
+        QString passwd = args["passwd"].toString();
+
+        struct crypt_device *cd;
+        struct crypt_params_luks1 params;
+
+        ba = args["device"].toString().toLocal8Bit();
+
+        retval = crypt_init(&cd, ba.data());
+
+        if (retval < 0)
+            goto cleanup;
+
+        params.hash = "sha1";
+        params.data_alignment = 0;
+        params.data_device = nullptr;
+
+        retval = crypt_format(cd, CRYPT_LUKS1, "aes", "xts-plain64", nullptr, nullptr, 256 / 8, &params);
+
+        if (retval < 0)
+            goto cleanup;
+
+        ba = passwd.toLocal8Bit();
+
+        retval = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, nullptr, 0, ba.data(), ba.size());
+
+        if (retval < 0)
+            goto cleanup;
+
+        return reply;
+
+    cleanup:
+        reply = ActionReply::HelperErrorReply();
+        return reply;
+
+    }
     
     QStringList arguments;
     arguments.append("-c");
@@ -72,7 +112,7 @@ ActionReply Helper::format(QVariantMap a
     }
   
     return reply;
-}    
+}
 
 
 /**
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -34,13 +34,23 @@ Window::Window(DeviceList& dl, QWidget *
   QWidget *w = new QWidget(this);
   ui->setupUi(w);
   setCentralWidget(w);
-  
+
+  QPalette palette = ui->errLabel->palette();
+  palette.setColor(ui->errLabel->foregroundRole(), Qt::red);
+  ui->errLabel->setPalette(palette);
+
+  ui->passwdLabel->setText(i18n("Input password:"));
+
   this->busy = false;
+  ui->passwdEdit->setVisible(false);
+  ui->passwdEdit->setEchoMode(QLineEdit::Password);
+  ui->passwdLabel->setVisible(false);
+  deviseUnlocked = false;
   
   /* Device slot */
   connect(&devList, SIGNAL(refreshDevices(USBDevice, bool)), this, SLOT(refreshListDevices(USBDevice, bool)));
   devList.initOperation();
-  
+
   /* GUI slots */
   connect(ui->cb_devices, SIGNAL(activated(QString)), this, SLOT(newDeviceProperties(QString)));
     
@@ -53,6 +63,10 @@ Window::Window(DeviceList& dl, QWidget *
   ui->cb_filesystem->addItem("f2fs");
   ui->cb_filesystem->addItem("exfat");
 
+  ui->selectCrypt->setText(QString(i18n("Encrypt")));
+
+  connect(ui->selectCrypt, SIGNAL(stateChanged(int)), this, SLOT(selectEncrypt(int)));
+
 //   connect(ui->pushButton, SIGNAL(clicked(bool), this, SLOT());
   Action *formatAction = new Action("org.kde.auth.quf.format");
   formatAction->setHelperId("org.kde.auth.quf");
@@ -90,23 +104,68 @@ QString Window::escapeLabel(const QStrin
  */
 void Window::performAction(KAuth::Action k_action)
 {
+
     KAuth::Action *action = &k_action;
     
       Device actual = getCurrentDevice();
 
+      bool makeCrypt = ui->selectCrypt->isChecked();
+
+      ExecuteJob *reply;
+
       if(!actual.as<Block>()->device().contains(QRegExp("([0-9])$"))){
             qWarning() << "WARNING: It is needed to create a partition";
             QMessageBox::warning(this, i18n("Warning"), i18n("It is needed to create a partition"), QMessageBox::Ok);
             return;
       }
-     
+
+      QString cryptoPass = ui->passwdEdit->text();
+
+      ui->errLabel->clear();
+      ui->passwdEdit->clear();
+
+      disableGUI();
+
      // Obtener argumentos para el formato
      QString command = "";
      QStringList args;
      QString filesystem = ui->cb_filesystem->currentText();
      QString label = ui->label_device->text().trimmed();
      QString dirDev = ui->cb_devices->currentText();
-     
+
+     QVariantMap map;
+
+     if ( (makeCrypt) & (cryptoPass.isEmpty()) ) {
+         ui->errLabel->setText(i18n("Crypto password could not is empty!"));
+         goto cleanup;
+     }
+
+     lockDevice();
+
+     if (makeCrypt) {
+
+         map["makecrypt"] = makeCrypt;
+         map["passwd"] = cryptoPass;
+         map["mounted"] = actual.as<StorageAccess>()->isAccessible();
+         map["device"] = dirDev;
+
+         qDebug() << "Creating crypto LUKS system...";
+
+         action->setArguments(map);
+         reply = startFormat(action, QString(i18n("Device encryption...")));
+
+         if (reply->error())
+             goto cleanup;
+
+         dirDev = unlockDevice(cryptoPass);
+
+         if (!deviseUnlocked) {
+             ui->errLabel->setText(QString(i18n("Unlock device error...")));
+             goto cleanup;
+         }
+
+     }
+
      if(filesystem == QString("ntfs")){
         qDebug() << "**** FORMATTING AS NTFS";
         
@@ -192,49 +251,124 @@ void Window::performAction(KAuth::Action
 
         command = "/sbin/mke2fs";
         
-    }
+     }
 
     else{
         qDebug() << "ERROR: Unsupported filesystem = " << filesystem;
         this->statusBar()->showMessage( i18n("Failed : Unsupported filesystem %1", filesystem) );
-        return;
+        goto cleanup;
     }
-     
+
      qDebug() << "EXEC COMMAND : " << command << ", ARGS: " << args;
-     
-     QVariantMap map;
+
+     map.clear();
+
      map["command"] = command;
      map["args"] = args;
      map["mounted"] = actual.as<StorageAccess>()->isAccessible();
      map["device"] = dirDev;
+
      action->setArguments(map);
-     
-     this->statusBar()->showMessage(i18n("Wait a moment ..."));
-     
-     this->busy = true;
-     this->disableGUI();
-     action->setTimeout(1000*60*2.1);
-     ExecuteJob *reply = action->execute();
-     this->busy = false;
-     this->enableGUI();
-     reply->exec();
-
-     //Syncronous
-     if (reply->error()){
-        //if (reply.type() == ActionReply::KAuthError) {
-            this->statusBar()->showMessage(i18n("%1, %2", reply->error(), reply->errorString()));
-            QMessageBox::warning(this, i18n("Warning"), i18n("Failed: Unable to authenticate/execute the action: %1, %2", reply->error(), reply->errorString()));
-                // There has been an internal KAuth error
-        //} else {
-                // Our helper triggered a custom error
-                // Act accordingly...
-        //   this->statusBar()->showMessage( i18n("Failed : %1", reply.errorDescription()) );
-        //}
-    }
-    else {
+     reply = startFormat(action, QString(i18n("Creating new file system...")));
+
+     setResult(reply);
+
+cleanup:
+
+     if (deviseUnlocked)
+         lockDevice();
+
+     enableGUI();
+
+}
+
+ExecuteJob* Window::startFormat(KAuth::Action *action, QString message)
+{
+    this->statusBar()->showMessage(message);
+    this->busy = true;
+
+    action->setTimeout(1000*60*2.1);
+    ExecuteJob *reply = action->execute();
+
+    this->busy = false;
+
+    reply->exec();
+
+    return reply;
+}
+
+void Window::setResult(ExecuteJob *reply)
+{
+    if (reply->error()) {
+        this->statusBar()->showMessage(i18n("%1, %2", reply->error(), reply->errorString()));
+        QMessageBox::warning(this, i18n("Warning"), i18n("Failed: Unable to authenticate/execute the action: %1, %2", reply->error(), reply->errorString()));
+
+    } else {
         this->statusBar()->showMessage(i18n("Success"));
     }
+}
+
+struct UdisksIface
+{
+    QString dest = "org.freedesktop.UDisks2";
+    QString path = "/org/freedesktop/UDisks2/block_devices/";
+    QString iface = "org.freedesktop.UDisks2.Encrypted";
+    QString meth;
+};
+
+bool Window::createIface()
+{
+    QDBusConnection dbusConn = QDBusConnection::systemBus();
+    if (!dbusConn.isConnected())
+        return false;
+
+    UdisksIface udisks;
+
+    QString dbusPath = udisks.path + ui->cb_devices->currentText().split("/").last();
+
+    dbusIface = new QDBusInterface(udisks.dest, dbusPath, udisks.iface, dbusConn, this);
+    if (!dbusIface->isValid())
+        return false;
+
+    return true;
+}
+
+void Window::lockDevice()
+{
+    if (!createIface())
+        return;
+
+    UdisksIface udisks;
+    udisks.meth = "Lock";
+
+    QList<QVariant> args;
+    args << QMap<QString, QVariant>();
+
+    dbusIface->callWithArgumentList(QDBus::AutoDetect, udisks.meth, args);
+    deviseUnlocked = false;
+}
+
+QString Window::unlockDevice(QString passwd)
+{
+    if (!createIface())
+        return QString("");
+
+    UdisksIface udisks;
+    udisks.meth = "Unlock";
+
+    QList<QVariant> args;
+    args << passwd << QMap<QString, QVariant>();
+
+
+    QDBusMessage msg = dbusIface->callWithArgumentList(QDBus::AutoDetect, udisks.meth, args);
+    if (msg.errorMessage().isEmpty()) {
+        deviseUnlocked = true;
+        return dbusIface->callWithArgumentList(QDBus::AutoDetect, udisks.meth, args).errorMessage().split(" ").last();
+    }
+
+    deviseUnlocked = false;
 
+    return QString("");
 }
 
 /*
@@ -298,15 +432,33 @@ void Window::refreshDeviceProperties()
   newDeviceProperties(str_device);
 }
 
+void Window::selectEncrypt(int encrypt)
+{
+
+    if (encrypt) {
+
+        setLabel();
+
+        ui->passwdEdit->setVisible(true);
+        ui->passwdLabel->setVisible(true);
+
+    } else {
+
+        ui->passwdEdit->setVisible(false);
+        ui->passwdLabel->setVisible(false);
+
+    }
+}
+
 void Window::newDeviceProperties(QString devname)
 {
   USBDevice usb = devList.findDeviceFromPath(devname);
   QString size;
   size.setNum(usb.getCapacity());
-  
+  deviceFilesystem = usb.getFilesystem();
   ui->lb_product->setText( usb.getVendor() );
   ui->lb_size->setText( size.append("MB") );
-  ui->lb_filesystem->setText( usb.getFilesystem());
+  ui->lb_filesystem->setText( deviceFilesystem);
   
   // Icon depending of system
   QLabel *label = ui->label_icon;
@@ -324,6 +476,8 @@ void Window::newDeviceProperties(QString
         }
 
   }
+
+  setLabel();
     
   enableGUI();
 }
@@ -335,6 +489,14 @@ Device Window::getCurrentDevice()
   return ud.getDevice();
 }
 
+void Window::setLabel()
+{
+    if (deviceFilesystem == LUKSFILESYSTEM)
+        ui->passwdLabel->setText(QString(i18n("Input your password:")));
+    else
+        ui->passwdLabel->setText(QString(i18n("Input new password:")));
+}
+
 void Window::disableGUI()
 {
   ui->widget->setDisabled(true);
--- a/src/window.h
+++ b/src/window.h
@@ -24,6 +24,7 @@
 #include <QtGui>
 #include <QStatusBar>
 #include <QPushButton>
+#include <QtDBus/QtDBus>
 
 #include "devices.h"
 #include "usbdevice.h"
@@ -57,6 +58,7 @@ public Q_SLOTS:
     void refreshListDevices(USBDevice, bool);    
     void enableGUI();
     void disableGUI();
+    void selectEncrypt(int encrypt);
     
     /**
      *  Se ejecuta cuando se autoriza una action
@@ -70,7 +72,17 @@ private:
     Device getCurrentDevice();
     QString escapeLabel(const QString label);
     void actionResult(KJob *kjob);
-    bool busy; 
+    bool busy;
+    void lockDevice();
+    QString unlockDevice(QString passwd);
+    bool createIface();
+    QDBusInterface *dbusIface;
+    bool deviseUnlocked;
+    QString deviceFilesystem;
+    const QString LUKSFILESYSTEM = QString("crypto_LUKS");
+    ExecuteJob* startFormat(KAuth::Action *action, QString message);
+    void setResult(ExecuteJob *reply);
+    void setLabel();
     
 };
 
--- a/src/window.ui
+++ b/src/window.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>327</width>
-    <height>272</height>
+    <height>297</height>
    </rect>
   </property>
   <property name="maximumSize">
@@ -101,7 +101,7 @@
            </property>
           </widget>
          </item>
-         <item row="3" column="0">
+         <item row="5" column="0">
           <widget class="QLabel" name="label_6">
            <property name="enabled">
             <bool>true</bool>
@@ -111,7 +111,7 @@
            </property>
           </widget>
          </item>
-         <item row="3" column="1">
+         <item row="5" column="1">
           <widget class="QLineEdit" name="label_device">
            <property name="enabled">
             <bool>true</bool>
@@ -300,10 +300,34 @@
            </layout>
           </widget>
          </item>
+         <item row="4" column="1">
+          <widget class="QLineEdit" name="passwdEdit"/>
+         </item>
+         <item row="4" column="0">
+          <widget class="QLabel" name="passwdLabel">
+           <property name="text">
+            <string>Input password:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QCheckBox" name="selectCrypt">
+           <property name="text">
+            <string>encrypt device</string>
+           </property>
+          </widget>
+         </item>
         </layout>
        </widget>
       </item>
       <item>
+       <widget class="QLabel" name="errLabel">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item>
        <spacer name="verticalSpacer">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin