/* * * kryptomedia - A KDE cryto media application. * * Copyright (C) 2006-2007 Daniel Gollub * * * This file is part of kryptomedia. * * kbluetooth is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libkbluetooth 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with libkbluetooth; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "kryptomedia.h" #include KryptoMedia *KryptoMedia::_ctx = NULL; KryptoMedia::KryptoMedia(const QString &udi) : mUDI(udi) { _ctx = this; if (!(initDBus() && initHAL())) { kdDebug() << __func__ << "Init of HAL or DBus failed." << endl; return; } QStringList devs; if (udi.isEmpty()) { devs = getDevicesNeedDecrypt(); if (devs.size() < 1) { KMessageBox::information(NULL,i18n("No Device found, which needs to be decrypted.")); exit(0); } } else devs.append(mUDI); initUi(devs); } KryptoMedia::~KryptoMedia() { kdDebug() << __func__ << "()" << endl; if (devices) delete devices; deinitHAL(); } bool KryptoMedia::initDBus() { kdDebug() << __func__ << endl; DBusError error; dbus_error_init(&error); mDBusConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); if (!mDBusConnection) { if (dbus_error_is_set(&error)) { kdDebug() << __func__ << " dbus_bus_get failed: " << error.message << endl; dbus_error_free(&error); } return false; } mDBusQtConnection = new DBusQt::Connection(this); mDBusQtConnection->dbus_connection_setup_with_qt_main(mDBusConnection); return true; } void KryptoMedia::initUi(QStringList &mUDIs) { devices = new QValueVector; for (unsigned int i=0;i < mUDIs.size(); i++) { mUDI = *(mUDIs.at(i)); mUDIparent = getHalPropertyString(mUDI, "info.parent"); mProduct = getHalPropertyString(mUDIparent, "info.product"); mVendor = getHalPropertyString(mUDIparent, "info.vendor"); mDeviceNode = getHalPropertyString(mUDI, "block.device"); mDeviceType = getHalPropertyString(mUDIparent, "storage.drive_type"); KryptoMediaDevice *tmp = new KryptoMediaDevice(mVendor,mProduct,mDeviceNode,mDeviceType,mUDI); devices->push_back(tmp); } dialog = new Dialog(devices); dialog->show(); connect(dialog, SIGNAL (udiChanged(QString&)), SLOT (setNewUDI(QString&))); connect(dialog, SIGNAL (user1Clicked()), this, SLOT (slotSendPassword())); connect(dialog, SIGNAL (cancelClicked()), this, SLOT (slotCancel())); // connect(this, SIGNAL (signalDecrypted()), dialog, SLOT (slotDialogDecrypted())); connect(this, SIGNAL (signalPasswordError(QString, QString)), dialog, SLOT (slotDialogError(QString, QString))); } void KryptoMedia::setNewUDI(QString &udi) { mUDI = udi; } void KryptoMedia::deinitDBus() { kdDebug() << __func__ << endl; mDBusQtConnection->close(); delete mDBusQtConnection; if (mDBusConnection) dbus_connection_unref(mDBusConnection); } bool KryptoMedia::initHAL() { kdDebug() << __func__ << endl; mHALctx = libhal_ctx_new(); libhal_ctx_set_dbus_connection(mHALctx, mDBusConnection); if (!libhal_ctx_init(mHALctx, NULL)) { kdDebug() << __func__ << "(): init of hal ctx failed!" << endl; return false; } return true; } bool KryptoMedia::deinitHAL() { bool ret = true; DBusError error; if (!mHALctx) return true; dbus_error_init(&error); if (!libhal_ctx_shutdown( mHALctx, &error)) { kdDebug() << __func__ << "(): hal ctx shutdown failed." << endl; if (dbus_error_is_set(&error)) { kdDebug() << __func__ << "(): DBus Error Name: " << error.name << " Message: " << error.message << endl; dbus_error_free(&error); } // Go on and try at least to free hal context.... ret = false; } if (!libhal_ctx_free( mHALctx )) { kdDebug() << __func__ << "(): freeing of hal context failed... " << endl; ret = false; } mHALctx = NULL; return ret; } QString KryptoMedia::getHalPropertyString(QString udi, QString prop) { kdDebug() << __func__ << "(" << udi << ", " << prop << ")" << endl; QString value = QString::null; char *_val = libhal_device_get_property_string (mHALctx, udi.ascii(), prop.ascii(), NULL); if (_val != NULL) { value = _val; libhal_free_string (_val); } kdDebug() << __func__ << ": " << value << endl; return value; } QStringList KryptoMedia::getDevicesNeedDecrypt() { // kdDebug() << __func__ << "(" << udi << ", " << prop << ")" << endl; QStringList devList; int num, dm_num; char **dmList = 0; char **blockList = libhal_manager_find_device_string_match(mHALctx, "volume.fstype","crypto_LUKS",&num,NULL); for (int i=0; i < num; i++) { dmList = libhal_manager_find_device_string_match(mHALctx, "volume.crypto_luks.clear.backing_volume",blockList[i],&dm_num,NULL); if (dm_num == 0) devList.append(blockList[i]); } if (blockList != NULL) libhal_free_string_array (blockList); if (dmList != NULL) libhal_free_string_array (dmList); return devList; } /* void KryptoMedia::slotSendPassword() { sendPassword(); } */ void KryptoMedia::slotSendPassword() { kdDebug() << __func__ << "()" << endl; DBusError error; DBusMessage *msg = NULL; const char *password = NULL; DBusPendingCall *pcall = NULL; dbus_error_init(&error); msg = dbus_message_new_method_call("org.freedesktop.Hal", mUDI.ascii(), "org.freedesktop.Hal.Device.Volume.Crypto", "Setup"); if (!msg) { kdDebug() << "Failed to create new dbus message. UDI: " << mUDI << endl; goto error; } password = dialog->getPassword().ascii(); if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &password, DBUS_TYPE_INVALID)) { kdDebug() << __func__ << "(): Failed to setup a encrypt message." << endl; goto error; } if (!dbus_connection_send_with_reply(mDBusConnection, msg, &pcall, -1)) { kdDebug() << __func__ << "(): No Memory for sending message with reply..." << endl; goto error; } if (!pcall) { kdDebug() << __func__ << "(): PendingCall is NULL! Connection is disconnected!" << endl; goto error; } // Last two parameters only needed for dbus user data ( and freeing it ). if (!dbus_pending_call_set_notify(pcall, KryptoMedia::encryptCallback, NULL, NULL)) { kdDebug() << __func__ << "(): Got some trouble while setting callback function..." << endl; goto error; } dbus_message_unref(msg); return; error: if (msg) dbus_message_unref(msg); return; } void KryptoMedia::encryptCallback(DBusPendingCall* pcall, void* /*data*/) { kdDebug() << __func__ << "()" << endl; DBusMessage *reply = NULL; DBusError error; QString errorName = QString::null; QString errorMsg = QString::null; reply = dbus_pending_call_steal_reply(pcall); if (!reply) { kdDebug() << __func__ << "(): stolen reply is empty!" << endl; goto error; } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { dbus_error_init(&error); dbus_set_error_from_message(&error, reply); kdDebug() << __func__ << "(): Recieved error: " << error.name << ": " << error.message << endl; errorName = QString(error.name); errorMsg = QString(error.message); dbus_error_free(&error); goto error_and_unref; } dbus_message_unref(reply); dbus_pending_call_unref(pcall); // _ctx->signalDecrypted(); exit(0); return; error_and_unref: dbus_message_unref(reply); error: dbus_pending_call_unref(pcall); _ctx->signalPasswordError(errorName, errorMsg); return; } void KryptoMedia::slotCancel() { exit(0); } #include "kryptomedia.moc"