From 25db5c0f40379dadd4224cfbd87aad92a49d90ae Mon Sep 17 00:00:00 2001 From: nils Date: Sat, 29 Oct 2011 22:29:36 +0000 Subject: refactored gpgwin -> mainwindow and context -> gpgcontext git-svn-id: http://cpunk.de/svn/src/gpg4usb/trunk@588 34ebc366-c3a9-4b3c-9f84-69acf7962910 --- TODO | 8 +- context.cpp | 671 --------------------------------------- context.h | 127 -------- fileencryptiondialog.cpp | 2 +- fileencryptiondialog.h | 6 +- gpg4usb.pro | 8 +- gpgcontext.cpp | 671 +++++++++++++++++++++++++++++++++++++++ gpgcontext.h | 127 ++++++++ gpgwin.cpp | 782 ---------------------------------------------- gpgwin.h | 294 ----------------- keydetailsdialog.cpp | 2 +- keydetailsdialog.h | 6 +- keygenthread.cpp | 2 +- keygenthread.h | 6 +- keylist.cpp | 2 +- keylist.h | 6 +- keymgmt.cpp | 2 +- keymgmt.h | 4 +- keyserverimportdialog.cpp | 2 +- keyserverimportdialog.h | 6 +- main.cpp | 4 +- mainwindow.cpp | 782 ++++++++++++++++++++++++++++++++++++++++++++++ mainwindow.h | 294 +++++++++++++++++ verifydetailsdialog.cpp | 2 +- verifydetailsdialog.h | 4 +- verifykeydetailbox.cpp | 2 +- verifykeydetailbox.h | 4 +- verifynotification.cpp | 2 +- verifynotification.h | 4 +- 29 files changed, 1916 insertions(+), 1916 deletions(-) delete mode 100644 context.cpp delete mode 100644 context.h create mode 100644 gpgcontext.cpp create mode 100644 gpgcontext.h delete mode 100644 gpgwin.cpp delete mode 100644 gpgwin.h create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h diff --git a/TODO b/TODO index 72d71d9..f5caba4 100644 --- a/TODO +++ b/TODO @@ -24,7 +24,7 @@ Release 0.3.1 - cross out expired keys and add warning in key properties [DONE] - stealth mode for windows (http://www.portablefreeware.com/forums/viewtopic.php?f=4&t=3713) [DONE] - keyid should be searchable in import from keyserver [DONE] -- beautify icons for verify and sign +- beautify icons for verify and sign [DONE] Release 0.3.2 - set gpgme error language to chosen language (context.cpp:49) @@ -34,9 +34,9 @@ Release 0.3.2 - understandable message if no matching private key found for decryption - investigate in adding a offline help system - investigate in embedding a steganography tool -- refactoring and cleanup: - - gpgwin.cpp -> mainwindow.cpp - - context.cpp -> gpgcontext.cpp +- refactoring and cleanup: [DONE] + - gpgwin.cpp -> mainwindow.cpp [DONE] + - context.cpp -> gpgcontext.cpp [DONE] - optionally open new tab after encryption/decrytion diff --git a/context.cpp b/context.cpp deleted file mode 100644 index 654b928..0000000 --- a/context.cpp +++ /dev/null @@ -1,671 +0,0 @@ -/* - * context.cpp - * - * Copyright 2008 gpg4usb-team - * - * This file is part of gpg4usb. - * - * Gpg4usb 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 3 of the License, or - * (at your option) any later version. - * - * Gpg4usb 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 gpg4usb. If not, see - */ - -#include "context.h" - -#ifdef _WIN32 -#include -#include /* contains read/write */ -#endif - - -namespace GpgME -{ - -/** Constructor - * Set up gpgme-context, set paths to app-run path - */ -Context::Context() -{ - - /** get application path */ - QString appPath = qApp->applicationDirPath(); - - /** The function `gpgme_check_version' must be called before any other - * function in the library, because it initializes the thread support - * subsystem in GPGME. (from the info page) */ - gpgme_check_version(NULL); - - // TODO: Set gpgme_language to config - // http://lavica.fesb.hr/cgi-bin/info2html?%28gpgme%29Locale - setlocale(LC_ALL, ""); - /** set locale, because tests do also */ - gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); - //qDebug() << "Locale set to" << LC_CTYPE << " - " << setlocale(LC_CTYPE, NULL); -#ifndef _WIN32 - gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); -#endif - - err = gpgme_new(&mCtx); - checkErr(err); - /** here come the settings, instead of /usr/bin/gpg - * a executable in the same path as app is used. - * also lin/win must be checked, for calling gpg.exe if needed - */ -#ifdef _WIN32 - QString gpgBin = appPath + "/bin/gpg.exe"; -#else - QString gpgBin = appPath + "/bin/gpg"; -#endif - QString gpgKeys = appPath + "/keydb"; - /* err = gpgme_ctx_set_engine_info(mCtx, GPGME_PROTOCOL_OpenPGP, - gpgBin.toUtf8().constData(), - gpgKeys.toUtf8().constData());*/ - err = gpgme_ctx_set_engine_info(mCtx, GPGME_PROTOCOL_OpenPGP, - gpgBin.toLocal8Bit().constData(), - gpgKeys.toLocal8Bit().constData()); - checkErr(err); - - - /** Setting the output type must be done at the beginning */ - /** think this means ascii-armor --> ? */ - gpgme_set_armor(mCtx, 1); - /** passphrase-callback */ - gpgme_set_passphrase_cb(mCtx, passphraseCb, this); - - /** check if app is called with -d from command line */ - if (qApp->arguments().contains("-d")) { - qDebug() << "gpgme_data_t debug on"; - debug = true; - } else { - debug = false; - } - -} - -/** Destructor - * Release gpgme-context - */ -Context::~Context() -{ - if (mCtx) gpgme_release(mCtx); - mCtx = 0; -} - -/** Import Key from QByteArray - * - */ -void Context::importKey(QByteArray inBuffer) -{ - err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); - checkErr(err); - err = gpgme_op_import(mCtx, in); - checkErr(err); - gpgme_data_release(in); - emit keyDBChanged(); -} - -/** Generate New Key with values params - * - */ -void Context::generateKey(QString *params) -{ - err = gpgme_op_genkey(mCtx, params->toAscii().data(), NULL, NULL); - checkErr(err); - emit keyDBChanged(); -} - -/** Export Key to QByteArray - * - */ -bool Context::exportKeys(QStringList *uidList, QByteArray *outBuffer) -{ - size_t read_bytes; - gpgme_data_t out = 0; - outBuffer->resize(0); - - if (uidList->count() == 0) { - QMessageBox::critical(0, "Export Keys Error", "No Keys Selected"); - return false; - } - - for (int i = 0; i < uidList->count(); i++) { - err = gpgme_data_new(&out); - checkErr(err); - - err = gpgme_op_export(mCtx, uidList->at(i).toAscii().constData(), 0, out); - checkErr(err); - - read_bytes = gpgme_data_seek(out, 0, SEEK_END); - - err = readToBuffer(out, outBuffer); - checkErr(err); - gpgme_data_release(out); - } - return true; -} - -gpgme_key_t Context::getKeyDetails(QString uid) -{ - gpgme_key_t key; - - // try secret - gpgme_get_key(mCtx, uid.toAscii().constData(), &key, 1); - // ok, its a public key - if (!key) { - gpgme_get_key(mCtx, uid.toAscii().constData(), &key, 0); - } - return key; -} - -/** List all availabe Keys (VERY much like kgpgme) - */ -GpgKeyList Context::listKeys() -{ - gpgme_error_t err; - gpgme_key_t key; - - GpgKeyList keys; - //TODO dont run the loop more often than necessary - // list all keys ( the 0 is for all ) - err = gpgme_op_keylist_start(mCtx, NULL, 0); - checkErr(err); - while (!(err = gpgme_op_keylist_next(mCtx, &key))) { - GpgKey gpgkey; - - if (!key->subkeys) - continue; - - gpgkey.id = key->subkeys->keyid; - gpgkey.fpr = key->subkeys->fpr; - gpgkey.expired = (key->expired != 0); - - if (key->uids) { - gpgkey.name = key->uids->name; - gpgkey.email = key->uids->email; - } - keys.append(gpgkey); - gpgme_key_unref(key); - } - gpgme_op_keylist_end(mCtx); - - // list only private keys ( the 1 does ) - gpgme_op_keylist_start(mCtx, NULL, 1); - while (!(err = gpgme_op_keylist_next(mCtx, &key))) { - if (!key->subkeys) - continue; - // iterate keys, mark privates - GpgKeyList::iterator it = keys.begin(); - while (it != keys.end()) { - if (key->subkeys->keyid == it->id.toStdString()) - it->privkey = true; - it++; - } - - gpgme_key_unref(key); - } - gpgme_op_keylist_end(mCtx); - - return keys; -} - -/** Delete keys - */ - -void Context::deleteKeys(QStringList *uidList) -{ - QString tmp; - gpgme_key_t key; - - foreach(tmp, *uidList) { - gpgme_op_keylist_start(mCtx, tmp.toAscii().constData(), 0); - gpgme_op_keylist_next(mCtx, &key); - gpgme_op_keylist_end(mCtx); - gpgme_op_delete(mCtx, key, 1); - } - emit keyDBChanged(); -} - -/** Encrypt inBuffer for reciepients-uids, write - * result to outBuffer - */ -bool Context::encrypt(QStringList *uidList, const QByteArray &inBuffer, QByteArray *outBuffer) -{ - - gpgme_data_t in = 0, out = 0; - outBuffer->resize(0); - - if (uidList->count() == 0) { - QMessageBox::critical(0, tr("No Key Selected"), tr("No Key Selected")); - return false; - } - - //gpgme_encrypt_result_t e_result; - gpgme_key_t recipients[uidList->count()+1]; - - /* get key for user */ - for (int i = 0; i < uidList->count(); i++) { - // the last 0 is for public keys, 1 would return private keys - gpgme_op_keylist_start(mCtx, uidList->at(i).toAscii().constData(), 0); - gpgme_op_keylist_next(mCtx, &recipients[i]); - gpgme_op_keylist_end(mCtx); - } - //Last entry in array has to be NULL - recipients[uidList->count()] = NULL; - - //If the last parameter isnt 0, a private copy of data is made - if (mCtx) { - err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); - checkErr(err); - if (!err) { - err = gpgme_data_new(&out); - checkErr(err); - if (!err) { - err = gpgme_op_encrypt(mCtx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); - checkErr(err); - if (!err) { - err = readToBuffer(out, outBuffer); - checkErr(err); - } - } - } - } - /* unref all keys */ - for (int i = 0; i <= uidList->count(); i++) { - gpgme_key_unref(recipients[i]); - } - if (in) { - gpgme_data_release(in); - } - if (out) { - gpgme_data_release(out); - } - return (err == GPG_ERR_NO_ERROR); -} - -/** Decrypt QByteAarray, return QByteArray - * mainly from http://basket.kde.org/ (kgpgme.cpp) - */ -bool Context::decrypt(const QByteArray &inBuffer, QByteArray *outBuffer) -{ - gpgme_data_t in = 0, out = 0; - gpgme_decrypt_result_t result = 0; - - outBuffer->resize(0); - if (mCtx) { - err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); - checkErr(err); - if (!err) { - err = gpgme_data_new(&out); - checkErr(err); - if (!err) { - err = gpgme_op_decrypt(mCtx, in, out); - checkErr(err); - if (!err) { - result = gpgme_op_decrypt_result(mCtx); - if (result->unsupported_algorithm) { - QMessageBox::critical(0, tr("Unsupported algorithm"), result->unsupported_algorithm); - } else { - err = readToBuffer(out, outBuffer); - checkErr(err); - } - } - } - } - } - if (err != GPG_ERR_NO_ERROR && err != GPG_ERR_CANCELED) { - QMessageBox::critical(0, tr("Error decrypting:"), gpgme_strerror(err)); - return false; - } - - if (! settings.value("general/rememberPassword").toBool()) { - clearPasswordCache(); - } - - if (in) { - gpgme_data_release(in); - } - if (out) { - gpgme_data_release(out); - } - return (err == GPG_ERR_NO_ERROR); -} - -/** Read gpgme-Data to QByteArray - * mainly from http://basket.kde.org/ (kgpgme.cpp) - */ -#define BUF_SIZE (32 * 1024) -gpgme_error_t Context::readToBuffer(gpgme_data_t in, QByteArray *outBuffer) -{ - int ret; - gpgme_error_t err = GPG_ERR_NO_ERROR; - - ret = gpgme_data_seek(in, 0, SEEK_SET); - if (ret) { - err = gpgme_err_code_from_errno(errno); - checkErr(err, "failed dataseek in readToBuffer"); - } else { - char *buf = new char[BUF_SIZE + 2]; - - if (buf) { - while ((ret = gpgme_data_read(in, buf, BUF_SIZE)) > 0) { - uint size = outBuffer->size(); - outBuffer->resize(size + ret); - memcpy(outBuffer->data() + size, buf, ret); - } - if (ret < 0) { - err = gpgme_err_code_from_errno(errno); - checkErr(err, "failed data_read in readToBuffer"); - } - delete[] buf; - } - } - return err; -} - -/** The Passphrase window, if not provided by env-Var GPG_AGENT_INFO - * originally copied from http://basket.kde.org/ (kgpgme.cpp), but modified - */ -gpgme_error_t Context::passphraseCb(void *hook, const char *uid_hint, - const char *passphrase_info, - int last_was_bad, int fd) -{ - Context *gpg = static_cast(hook); - return gpg->passphrase(uid_hint, passphrase_info, last_was_bad, fd); -} - -gpgme_error_t Context::passphrase(const char *uid_hint, - const char * /*passphrase_info*/, - int last_was_bad, int fd) -{ - gpgme_error_t returnValue = GPG_ERR_CANCELED; - QString passwordDialogMessage; - QString gpgHint = uid_hint; - bool result; - - if (last_was_bad) { - passwordDialogMessage += ""+tr("Wrong password")+".

\n\n"; - clearPasswordCache(); - } - - /** if uid provided */ - if (!gpgHint.isEmpty()) { - // remove UID, leave only username & email - gpgHint.remove(0, gpgHint.indexOf(" ")); - passwordDialogMessage += "Enter Password for
\n" + gpgHint + "\n"; - } - - if (mPasswordCache.isEmpty()) { - QString password = QInputDialog::getText(0, tr("Enter Password"), - passwordDialogMessage, QLineEdit::Password, - "", &result, Qt::Window); - - if (result) mPasswordCache = password.toAscii(); - } else { - result = true; - } - - if (result) { - -#ifndef _WIN32 - if (write(fd, mPasswordCache.data(), mPasswordCache.length()) == -1) { - qDebug() << "something is terribly broken"; - } -#else - DWORD written; - WriteFile((HANDLE) fd, mPasswordCache.data(), mPasswordCache.length(), &written, 0); -#endif - - returnValue = 0; - } - -#ifndef _WIN32 - if (write(fd, "\n", 1) == -1) { - qDebug() << "something is terribly broken"; - } -#else - DWORD written; - WriteFile((HANDLE) fd, "\n", 1, &written, 0); -#endif - - return returnValue; -} - -/** also from kgpgme.cpp, seems to clear password from mem */ -void Context::clearPasswordCache() -{ - if (mPasswordCache.size() > 0) { - mPasswordCache.fill('\0'); - mPasswordCache.truncate(0); - } -} - -// error-handling -int Context::checkErr(gpgme_error_t err, QString comment) const -{ - //if (err != GPG_ERR_NO_ERROR && err != GPG_ERR_CANCELED) { - if (err != GPG_ERR_NO_ERROR) { - qDebug() << "[Error " << comment << "] Source: " << gpgme_strsource(err) << " String: " << gpgme_strerror(err); - } - return err; -} - -int Context::checkErr(gpgme_error_t err) const -{ - //if (err != GPG_ERR_NO_ERROR && err != GPG_ERR_CANCELED) { - if (err != GPG_ERR_NO_ERROR) { - qDebug() << "[Error] Source: " << gpgme_strsource(err) << " String: " << gpgme_strerror(err); - } - return err; -} - - -/** export private key, TODO errohandling, e.g. like in seahorse (seahorse-gpg-op.c) **/ - -void Context::exportSecretKey(QString uid, QByteArray *outBuffer) -{ - // export private key to outBuffer - QStringList arguments; - arguments << "--armor" << "--export-secret-key" << uid; - QByteArray *err = new QByteArray(); - executeGpgCommand(arguments, outBuffer, err); - - // append public key to outBuffer - QByteArray *pubKey = new QByteArray(); - QStringList keyList; - keyList.append(uid); - exportKeys(&keyList,pubKey); - outBuffer->append(*pubKey); -} - -/** return type should be gpgme_error_t*/ -void Context::executeGpgCommand(QStringList arguments, QByteArray *stdOut, QByteArray *stdErr) -{ - gpgme_engine_info_t engine = gpgme_ctx_get_engine_info(mCtx); - - QStringList args; - args << "--homedir" << engine->home_dir << "--batch" << arguments; - - QProcess gpg; - gpg.start(engine->file_name, args); - gpg.waitForFinished(); - - *stdOut = gpg.readAllStandardOutput(); - *stdErr = gpg.readAllStandardError(); -} - -/*** - * TODO: return type should contain: - * -> list of sigs - * -> valid - * -> errors - */ -gpgme_signature_t Context::verify(QByteArray inBuffer) { - - int error=0; - gpgme_data_t in; - gpgme_error_t err; - gpgme_signature_t sign; - gpgme_verify_result_t result; - - err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); - checkErr(err); - - err = gpgme_op_verify (mCtx, in, NULL, in); - error = checkErr(err); - - if (error != 0) { - return NULL; - } - - result = gpgme_op_verify_result (mCtx); - sign = result->signatures; - return sign; -} - -/*** - * return type should contain: - * -> list of sigs - * -> valid - * -> decrypted message - */ -//void Context::decryptVerify(QByteArray in) { - -/* gpgme_error_t err; - gpgme_data_t in, out; - - gpgme_decrypt_result_t decrypt_result; - gpgme_verify_result_t verify_result; - - err = gpgme_op_decrypt_verify (mCtx, in, out); - decrypt_result = gpgme_op_decrypt_result (mCtx); - - verify_result = gpgme_op_verify_result (mCtx); - */ -//} - -bool Context::sign(QStringList *uidList, const QByteArray &inBuffer, QByteArray *outBuffer ) { - - gpgme_error_t err; - gpgme_data_t in, out; - gpgme_sign_result_t result; - - if (uidList->count() == 0) { - QMessageBox::critical(0, tr("Key Selection"), tr("No Private Key Selected")); - return false; - } - - // at start or end? - gpgme_signers_clear(mCtx); - - //gpgme_encrypt_result_t e_result; - gpgme_key_t signers[uidList->count()+1]; - - - // TODO: do we really need array? adding one key in loop should be ok - for (int i = 0; i < uidList->count(); i++) { - // the last 0 is for public keys, 1 would return private keys - gpgme_op_keylist_start(mCtx, uidList->at(i).toAscii().constData(), 0); - gpgme_op_keylist_next(mCtx, &signers[i]); - gpgme_op_keylist_end(mCtx); - - err = gpgme_signers_add (mCtx, signers[i]); - checkErr(err); - } - - err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); - checkErr(err); - err = gpgme_data_new (&out); - checkErr(err); - - /* - `GPGME_SIG_MODE_NORMAL' - A normal signature is made, the output includes the plaintext - and the signature. - - `GPGME_SIG_MODE_DETACH' - A detached signature is made. - - `GPGME_SIG_MODE_CLEAR' - A clear text signature is made. The ASCII armor and text - mode settings of the context are ignored. - */ - - err = gpgme_op_sign (mCtx, in, out, GPGME_SIG_MODE_CLEAR); - checkErr (err); - - if (err == GPG_ERR_CANCELED) { - return false; - } - - if (err != GPG_ERR_NO_ERROR) { - QMessageBox::critical(0, tr("Error signing:"), gpgme_strerror(err)); - return false; - } - - result = gpgme_op_sign_result (mCtx); - err = readToBuffer(out, outBuffer); - checkErr (err); - - gpgme_data_release(in); - gpgme_data_release(out); - - return (err == GPG_ERR_NO_ERROR); -} - -/* - * if there is no '\n' before the PGP-Begin-Block, but for example a whitespace, - * GPGME doesn't recognise the Message as encrypted. This function adds '\n' - * before the PGP-Begin-Block, if missing. - */ -void Context::preventNoDataErr(QByteArray *in) -{ - int block_start = in->indexOf("-----BEGIN PGP MESSAGE-----"); - if (block_start > 0 && in->at(block_start - 1) != '\n') { - in->insert(block_start, '\n'); - } - block_start = in->indexOf("-----BEGIN PGP SIGNED MESSAGE-----"); - if (block_start > 0 && in->at(block_start - 1) != '\n') { - in->insert(block_start, '\n'); - } -} - -/* - * isSigned returns: - * - 0, if text isn't signed at all - * - 1, if text is partially signed - * - 2, if text is completly signed - */ -int Context::textIsSigned(const QByteArray &text) { - if (text.trimmed().startsWith("-----BEGIN PGP SIGNED MESSAGE-----") && text.trimmed().endsWith("-----END PGP SIGNATURE-----")) { - return 2; - } - if (text.contains("-----BEGIN PGP SIGNED MESSAGE-----") && text.contains("-----END PGP SIGNATURE-----")) { - return 1; - } - return 0; -} - -QString Context::beautifyFingerprint(QString fingerprint) -{ - uint len = fingerprint.length(); - if ((len > 0) && (len % 4 == 0)) - for (uint n = 0; 4 *(n + 1) < len; ++n) - fingerprint.insert(5 * n + 4, ' '); - return fingerprint; -} - -} - - - - - diff --git a/context.h b/context.h deleted file mode 100644 index ac53a6c..0000000 --- a/context.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * context.h - * - * Copyright 2008 gpg4usb-team - * - * This file is part of gpg4usb. - * - * Gpg4usb 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 3 of the License, or - * (at your option) any later version. - * - * Gpg4usb 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 gpg4usb. If not, see - */ - -#ifndef __SGPGMEPP_CONTEXT_H__ -#define __SGPGMEPP_CONTEXT_H__ - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QMessageBox; -class sstream; -class QApplication; -class QByteArray; -class QString; -QT_END_NAMESPACE - -class GpgKey -{ -public: - GpgKey() { - privkey = false; - } - QString id; - QString name; - QString email; - QString fpr; - bool privkey; - bool expired; -}; - -typedef QLinkedList< GpgKey > GpgKeyList; - -namespace GpgME -{ - -class Context : public QObject -{ - Q_OBJECT - -public: - Context(); // Constructor - ~Context(); // Destructor - - void importKey(QByteArray inBuffer); - bool exportKeys(QStringList *uidList, QByteArray *outBuffer); - void generateKey(QString *params); - GpgKeyList listKeys(); - void deleteKeys(QStringList *uidList); - bool encrypt(QStringList *uidList, const QByteArray &inBuffer, - QByteArray *outBuffer); - bool decrypt(const QByteArray &inBuffer, QByteArray *outBuffer); - void clearPasswordCache(); - void exportSecretKey(QString uid, QByteArray *outBuffer); - gpgme_key_t getKeyDetails(QString uid); - gpgme_signature_t verify(QByteArray in); -// void decryptVerify(QByteArray in); - bool sign(QStringList *uidList, const QByteArray &inBuffer, QByteArray *outBuffer ); - /** - * @details If text contains PGP-message, put a linebreak before the message, - * so that gpgme can decrypt correctly - * - * @param in Pointer to the QBytearray to check. - */ - void preventNoDataErr(QByteArray *in); - - /** - * @brief - * - * @param text - * @return \li 2, if the text is completly signed, - * \li 1, if the text is partially signed, - * \li 0, if the text is not signed at all. - */ - int textIsSigned(const QByteArray &text); - QString beautifyFingerprint(QString fingerprint); - -signals: - void keyDBChanged(); - -private: - gpgme_ctx_t mCtx; - gpgme_data_t in, out; - gpgme_error_t err; - gpgme_error_t readToBuffer(gpgme_data_t in, QByteArray *outBuffer); - QByteArray mPasswordCache; - QSettings settings; - bool debug; - int checkErr(gpgme_error_t err) const; - int checkErr(gpgme_error_t err, QString comment) const; - - static gpgme_error_t passphraseCb(void *hook, const char *uid_hint, - const char *passphrase_info, - int last_was_bad, int fd); - gpgme_error_t passphrase(const char *uid_hint, - const char *passphrase_info, - int last_was_bad, int fd); - - void executeGpgCommand(QStringList arguments, - QByteArray *stdOut, - QByteArray *stdErr); - -}; -} // namespace GpgME - -#endif // __SGPGMEPP_CONTEXT_H__ diff --git a/fileencryptiondialog.cpp b/fileencryptiondialog.cpp index 58a3e2d..53bf8f7 100755 --- a/fileencryptiondialog.cpp +++ b/fileencryptiondialog.cpp @@ -21,7 +21,7 @@ #include "fileencryptiondialog.h" -FileEncryptionDialog::FileEncryptionDialog(GpgME::Context *ctx, QString iconPath, QStringList keyList, QWidget *parent) +FileEncryptionDialog::FileEncryptionDialog(GpgME::GpgContext *ctx, QString iconPath, QStringList keyList, QWidget *parent) : QDialog(parent) { diff --git a/fileencryptiondialog.h b/fileencryptiondialog.h index 2fe0c62..7ba380b 100755 --- a/fileencryptiondialog.h +++ b/fileencryptiondialog.h @@ -22,7 +22,7 @@ #ifndef __FILEENCRYPTIONDIALOG_H__ #define __FILEENCRYPTIONDIALOG_H__ -#include "context.h" +#include "gpgcontext.h" #include "keylist.h" QT_BEGIN_NAMESPACE @@ -58,7 +58,7 @@ public: * @param keyList * @param parent */ - FileEncryptionDialog(GpgME::Context *ctx, QString iconPath, QStringList keyList , QWidget *parent = 0); + FileEncryptionDialog(GpgME::GpgContext *ctx, QString iconPath, QStringList keyList , QWidget *parent = 0); public slots: /** @@ -99,7 +99,7 @@ private: QRadioButton *radioDec; /**< TODO */ protected: - GpgME::Context *mCtx; /**< TODO */ + GpgME::GpgContext *mCtx; /**< TODO */ KeyList *mKeyList; /**< TODO */ }; diff --git a/gpg4usb.pro b/gpg4usb.pro index 0614090..4cce0ca 100644 --- a/gpg4usb.pro +++ b/gpg4usb.pro @@ -16,8 +16,8 @@ CONFIG += debug QT += network # Input HEADERS += attachments.h \ - context.h \ - gpgwin.h \ + gpgcontext.h \ + mainwindow.h \ keylist.h \ keymgmt.h \ fileencryptiondialog.h \ @@ -34,8 +34,8 @@ HEADERS += attachments.h \ verifydetailsdialog.h \ verifykeydetailbox.h SOURCES += attachments.cpp \ - context.cpp \ - gpgwin.cpp \ + gpgcontext.cpp \ + mainwindow.cpp \ main.cpp \ keylist.cpp \ keymgmt.cpp \ diff --git a/gpgcontext.cpp b/gpgcontext.cpp new file mode 100644 index 0000000..77856f9 --- /dev/null +++ b/gpgcontext.cpp @@ -0,0 +1,671 @@ +/* + * context.cpp + * + * Copyright 2008 gpg4usb-team + * + * This file is part of gpg4usb. + * + * Gpg4usb 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 3 of the License, or + * (at your option) any later version. + * + * Gpg4usb 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 gpg4usb. If not, see + */ + +#include "gpgcontext.h" + +#ifdef _WIN32 +#include +#include /* contains read/write */ +#endif + + +namespace GpgME +{ + +/** Constructor + * Set up gpgme-context, set paths to app-run path + */ +GpgContext::GpgContext() +{ + + /** get application path */ + QString appPath = qApp->applicationDirPath(); + + /** The function `gpgme_check_version' must be called before any other + * function in the library, because it initializes the thread support + * subsystem in GPGME. (from the info page) */ + gpgme_check_version(NULL); + + // TODO: Set gpgme_language to config + // http://lavica.fesb.hr/cgi-bin/info2html?%28gpgme%29Locale + setlocale(LC_ALL, ""); + /** set locale, because tests do also */ + gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); + //qDebug() << "Locale set to" << LC_CTYPE << " - " << setlocale(LC_CTYPE, NULL); +#ifndef _WIN32 + gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); +#endif + + err = gpgme_new(&mCtx); + checkErr(err); + /** here come the settings, instead of /usr/bin/gpg + * a executable in the same path as app is used. + * also lin/win must be checked, for calling gpg.exe if needed + */ +#ifdef _WIN32 + QString gpgBin = appPath + "/bin/gpg.exe"; +#else + QString gpgBin = appPath + "/bin/gpg"; +#endif + QString gpgKeys = appPath + "/keydb"; + /* err = gpgme_ctx_set_engine_info(mCtx, GPGME_PROTOCOL_OpenPGP, + gpgBin.toUtf8().constData(), + gpgKeys.toUtf8().constData());*/ + err = gpgme_ctx_set_engine_info(mCtx, GPGME_PROTOCOL_OpenPGP, + gpgBin.toLocal8Bit().constData(), + gpgKeys.toLocal8Bit().constData()); + checkErr(err); + + + /** Setting the output type must be done at the beginning */ + /** think this means ascii-armor --> ? */ + gpgme_set_armor(mCtx, 1); + /** passphrase-callback */ + gpgme_set_passphrase_cb(mCtx, passphraseCb, this); + + /** check if app is called with -d from command line */ + if (qApp->arguments().contains("-d")) { + qDebug() << "gpgme_data_t debug on"; + debug = true; + } else { + debug = false; + } + +} + +/** Destructor + * Release gpgme-context + */ +GpgContext::~GpgContext() +{ + if (mCtx) gpgme_release(mCtx); + mCtx = 0; +} + +/** Import Key from QByteArray + * + */ +void GpgContext::importKey(QByteArray inBuffer) +{ + err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); + checkErr(err); + err = gpgme_op_import(mCtx, in); + checkErr(err); + gpgme_data_release(in); + emit keyDBChanged(); +} + +/** Generate New Key with values params + * + */ +void GpgContext::generateKey(QString *params) +{ + err = gpgme_op_genkey(mCtx, params->toAscii().data(), NULL, NULL); + checkErr(err); + emit keyDBChanged(); +} + +/** Export Key to QByteArray + * + */ +bool GpgContext::exportKeys(QStringList *uidList, QByteArray *outBuffer) +{ + size_t read_bytes; + gpgme_data_t out = 0; + outBuffer->resize(0); + + if (uidList->count() == 0) { + QMessageBox::critical(0, "Export Keys Error", "No Keys Selected"); + return false; + } + + for (int i = 0; i < uidList->count(); i++) { + err = gpgme_data_new(&out); + checkErr(err); + + err = gpgme_op_export(mCtx, uidList->at(i).toAscii().constData(), 0, out); + checkErr(err); + + read_bytes = gpgme_data_seek(out, 0, SEEK_END); + + err = readToBuffer(out, outBuffer); + checkErr(err); + gpgme_data_release(out); + } + return true; +} + +gpgme_key_t GpgContext::getKeyDetails(QString uid) +{ + gpgme_key_t key; + + // try secret + gpgme_get_key(mCtx, uid.toAscii().constData(), &key, 1); + // ok, its a public key + if (!key) { + gpgme_get_key(mCtx, uid.toAscii().constData(), &key, 0); + } + return key; +} + +/** List all availabe Keys (VERY much like kgpgme) + */ +GpgKeyList GpgContext::listKeys() +{ + gpgme_error_t err; + gpgme_key_t key; + + GpgKeyList keys; + //TODO dont run the loop more often than necessary + // list all keys ( the 0 is for all ) + err = gpgme_op_keylist_start(mCtx, NULL, 0); + checkErr(err); + while (!(err = gpgme_op_keylist_next(mCtx, &key))) { + GpgKey gpgkey; + + if (!key->subkeys) + continue; + + gpgkey.id = key->subkeys->keyid; + gpgkey.fpr = key->subkeys->fpr; + gpgkey.expired = (key->expired != 0); + + if (key->uids) { + gpgkey.name = key->uids->name; + gpgkey.email = key->uids->email; + } + keys.append(gpgkey); + gpgme_key_unref(key); + } + gpgme_op_keylist_end(mCtx); + + // list only private keys ( the 1 does ) + gpgme_op_keylist_start(mCtx, NULL, 1); + while (!(err = gpgme_op_keylist_next(mCtx, &key))) { + if (!key->subkeys) + continue; + // iterate keys, mark privates + GpgKeyList::iterator it = keys.begin(); + while (it != keys.end()) { + if (key->subkeys->keyid == it->id.toStdString()) + it->privkey = true; + it++; + } + + gpgme_key_unref(key); + } + gpgme_op_keylist_end(mCtx); + + return keys; +} + +/** Delete keys + */ + +void GpgContext::deleteKeys(QStringList *uidList) +{ + QString tmp; + gpgme_key_t key; + + foreach(tmp, *uidList) { + gpgme_op_keylist_start(mCtx, tmp.toAscii().constData(), 0); + gpgme_op_keylist_next(mCtx, &key); + gpgme_op_keylist_end(mCtx); + gpgme_op_delete(mCtx, key, 1); + } + emit keyDBChanged(); +} + +/** Encrypt inBuffer for reciepients-uids, write + * result to outBuffer + */ +bool GpgContext::encrypt(QStringList *uidList, const QByteArray &inBuffer, QByteArray *outBuffer) +{ + + gpgme_data_t in = 0, out = 0; + outBuffer->resize(0); + + if (uidList->count() == 0) { + QMessageBox::critical(0, tr("No Key Selected"), tr("No Key Selected")); + return false; + } + + //gpgme_encrypt_result_t e_result; + gpgme_key_t recipients[uidList->count()+1]; + + /* get key for user */ + for (int i = 0; i < uidList->count(); i++) { + // the last 0 is for public keys, 1 would return private keys + gpgme_op_keylist_start(mCtx, uidList->at(i).toAscii().constData(), 0); + gpgme_op_keylist_next(mCtx, &recipients[i]); + gpgme_op_keylist_end(mCtx); + } + //Last entry in array has to be NULL + recipients[uidList->count()] = NULL; + + //If the last parameter isnt 0, a private copy of data is made + if (mCtx) { + err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); + checkErr(err); + if (!err) { + err = gpgme_data_new(&out); + checkErr(err); + if (!err) { + err = gpgme_op_encrypt(mCtx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); + checkErr(err); + if (!err) { + err = readToBuffer(out, outBuffer); + checkErr(err); + } + } + } + } + /* unref all keys */ + for (int i = 0; i <= uidList->count(); i++) { + gpgme_key_unref(recipients[i]); + } + if (in) { + gpgme_data_release(in); + } + if (out) { + gpgme_data_release(out); + } + return (err == GPG_ERR_NO_ERROR); +} + +/** Decrypt QByteAarray, return QByteArray + * mainly from http://basket.kde.org/ (kgpgme.cpp) + */ +bool GpgContext::decrypt(const QByteArray &inBuffer, QByteArray *outBuffer) +{ + gpgme_data_t in = 0, out = 0; + gpgme_decrypt_result_t result = 0; + + outBuffer->resize(0); + if (mCtx) { + err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); + checkErr(err); + if (!err) { + err = gpgme_data_new(&out); + checkErr(err); + if (!err) { + err = gpgme_op_decrypt(mCtx, in, out); + checkErr(err); + if (!err) { + result = gpgme_op_decrypt_result(mCtx); + if (result->unsupported_algorithm) { + QMessageBox::critical(0, tr("Unsupported algorithm"), result->unsupported_algorithm); + } else { + err = readToBuffer(out, outBuffer); + checkErr(err); + } + } + } + } + } + if (err != GPG_ERR_NO_ERROR && err != GPG_ERR_CANCELED) { + QMessageBox::critical(0, tr("Error decrypting:"), gpgme_strerror(err)); + return false; + } + + if (! settings.value("general/rememberPassword").toBool()) { + clearPasswordCache(); + } + + if (in) { + gpgme_data_release(in); + } + if (out) { + gpgme_data_release(out); + } + return (err == GPG_ERR_NO_ERROR); +} + +/** Read gpgme-Data to QByteArray + * mainly from http://basket.kde.org/ (kgpgme.cpp) + */ +#define BUF_SIZE (32 * 1024) +gpgme_error_t GpgContext::readToBuffer(gpgme_data_t in, QByteArray *outBuffer) +{ + int ret; + gpgme_error_t err = GPG_ERR_NO_ERROR; + + ret = gpgme_data_seek(in, 0, SEEK_SET); + if (ret) { + err = gpgme_err_code_from_errno(errno); + checkErr(err, "failed dataseek in readToBuffer"); + } else { + char *buf = new char[BUF_SIZE + 2]; + + if (buf) { + while ((ret = gpgme_data_read(in, buf, BUF_SIZE)) > 0) { + uint size = outBuffer->size(); + outBuffer->resize(size + ret); + memcpy(outBuffer->data() + size, buf, ret); + } + if (ret < 0) { + err = gpgme_err_code_from_errno(errno); + checkErr(err, "failed data_read in readToBuffer"); + } + delete[] buf; + } + } + return err; +} + +/** The Passphrase window, if not provided by env-Var GPG_AGENT_INFO + * originally copied from http://basket.kde.org/ (kgpgme.cpp), but modified + */ +gpgme_error_t GpgContext::passphraseCb(void *hook, const char *uid_hint, + const char *passphrase_info, + int last_was_bad, int fd) +{ + GpgContext *gpg = static_cast(hook); + return gpg->passphrase(uid_hint, passphrase_info, last_was_bad, fd); +} + +gpgme_error_t GpgContext::passphrase(const char *uid_hint, + const char * /*passphrase_info*/, + int last_was_bad, int fd) +{ + gpgme_error_t returnValue = GPG_ERR_CANCELED; + QString passwordDialogMessage; + QString gpgHint = uid_hint; + bool result; + + if (last_was_bad) { + passwordDialogMessage += ""+tr("Wrong password")+".

\n\n"; + clearPasswordCache(); + } + + /** if uid provided */ + if (!gpgHint.isEmpty()) { + // remove UID, leave only username & email + gpgHint.remove(0, gpgHint.indexOf(" ")); + passwordDialogMessage += "Enter Password for
\n" + gpgHint + "\n"; + } + + if (mPasswordCache.isEmpty()) { + QString password = QInputDialog::getText(0, tr("Enter Password"), + passwordDialogMessage, QLineEdit::Password, + "", &result, Qt::Window); + + if (result) mPasswordCache = password.toAscii(); + } else { + result = true; + } + + if (result) { + +#ifndef _WIN32 + if (write(fd, mPasswordCache.data(), mPasswordCache.length()) == -1) { + qDebug() << "something is terribly broken"; + } +#else + DWORD written; + WriteFile((HANDLE) fd, mPasswordCache.data(), mPasswordCache.length(), &written, 0); +#endif + + returnValue = 0; + } + +#ifndef _WIN32 + if (write(fd, "\n", 1) == -1) { + qDebug() << "something is terribly broken"; + } +#else + DWORD written; + WriteFile((HANDLE) fd, "\n", 1, &written, 0); +#endif + + return returnValue; +} + +/** also from kgpgme.cpp, seems to clear password from mem */ +void GpgContext::clearPasswordCache() +{ + if (mPasswordCache.size() > 0) { + mPasswordCache.fill('\0'); + mPasswordCache.truncate(0); + } +} + +// error-handling +int GpgContext::checkErr(gpgme_error_t err, QString comment) const +{ + //if (err != GPG_ERR_NO_ERROR && err != GPG_ERR_CANCELED) { + if (err != GPG_ERR_NO_ERROR) { + qDebug() << "[Error " << comment << "] Source: " << gpgme_strsource(err) << " String: " << gpgme_strerror(err); + } + return err; +} + +int GpgContext::checkErr(gpgme_error_t err) const +{ + //if (err != GPG_ERR_NO_ERROR && err != GPG_ERR_CANCELED) { + if (err != GPG_ERR_NO_ERROR) { + qDebug() << "[Error] Source: " << gpgme_strsource(err) << " String: " << gpgme_strerror(err); + } + return err; +} + + +/** export private key, TODO errohandling, e.g. like in seahorse (seahorse-gpg-op.c) **/ + +void GpgContext::exportSecretKey(QString uid, QByteArray *outBuffer) +{ + // export private key to outBuffer + QStringList arguments; + arguments << "--armor" << "--export-secret-key" << uid; + QByteArray *err = new QByteArray(); + executeGpgCommand(arguments, outBuffer, err); + + // append public key to outBuffer + QByteArray *pubKey = new QByteArray(); + QStringList keyList; + keyList.append(uid); + exportKeys(&keyList,pubKey); + outBuffer->append(*pubKey); +} + +/** return type should be gpgme_error_t*/ +void GpgContext::executeGpgCommand(QStringList arguments, QByteArray *stdOut, QByteArray *stdErr) +{ + gpgme_engine_info_t engine = gpgme_ctx_get_engine_info(mCtx); + + QStringList args; + args << "--homedir" << engine->home_dir << "--batch" << arguments; + + QProcess gpg; + gpg.start(engine->file_name, args); + gpg.waitForFinished(); + + *stdOut = gpg.readAllStandardOutput(); + *stdErr = gpg.readAllStandardError(); +} + +/*** + * TODO: return type should contain: + * -> list of sigs + * -> valid + * -> errors + */ +gpgme_signature_t GpgContext::verify(QByteArray inBuffer) { + + int error=0; + gpgme_data_t in; + gpgme_error_t err; + gpgme_signature_t sign; + gpgme_verify_result_t result; + + err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); + checkErr(err); + + err = gpgme_op_verify (mCtx, in, NULL, in); + error = checkErr(err); + + if (error != 0) { + return NULL; + } + + result = gpgme_op_verify_result (mCtx); + sign = result->signatures; + return sign; +} + +/*** + * return type should contain: + * -> list of sigs + * -> valid + * -> decrypted message + */ +//void GpgContext::decryptVerify(QByteArray in) { + +/* gpgme_error_t err; + gpgme_data_t in, out; + + gpgme_decrypt_result_t decrypt_result; + gpgme_verify_result_t verify_result; + + err = gpgme_op_decrypt_verify (mCtx, in, out); + decrypt_result = gpgme_op_decrypt_result (mCtx); + + verify_result = gpgme_op_verify_result (mCtx); + */ +//} + +bool GpgContext::sign(QStringList *uidList, const QByteArray &inBuffer, QByteArray *outBuffer ) { + + gpgme_error_t err; + gpgme_data_t in, out; + gpgme_sign_result_t result; + + if (uidList->count() == 0) { + QMessageBox::critical(0, tr("Key Selection"), tr("No Private Key Selected")); + return false; + } + + // at start or end? + gpgme_signers_clear(mCtx); + + //gpgme_encrypt_result_t e_result; + gpgme_key_t signers[uidList->count()+1]; + + + // TODO: do we really need array? adding one key in loop should be ok + for (int i = 0; i < uidList->count(); i++) { + // the last 0 is for public keys, 1 would return private keys + gpgme_op_keylist_start(mCtx, uidList->at(i).toAscii().constData(), 0); + gpgme_op_keylist_next(mCtx, &signers[i]); + gpgme_op_keylist_end(mCtx); + + err = gpgme_signers_add (mCtx, signers[i]); + checkErr(err); + } + + err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1); + checkErr(err); + err = gpgme_data_new (&out); + checkErr(err); + + /* + `GPGME_SIG_MODE_NORMAL' + A normal signature is made, the output includes the plaintext + and the signature. + + `GPGME_SIG_MODE_DETACH' + A detached signature is made. + + `GPGME_SIG_MODE_CLEAR' + A clear text signature is made. The ASCII armor and text + mode settings of the context are ignored. + */ + + err = gpgme_op_sign (mCtx, in, out, GPGME_SIG_MODE_CLEAR); + checkErr (err); + + if (err == GPG_ERR_CANCELED) { + return false; + } + + if (err != GPG_ERR_NO_ERROR) { + QMessageBox::critical(0, tr("Error signing:"), gpgme_strerror(err)); + return false; + } + + result = gpgme_op_sign_result (mCtx); + err = readToBuffer(out, outBuffer); + checkErr (err); + + gpgme_data_release(in); + gpgme_data_release(out); + + return (err == GPG_ERR_NO_ERROR); +} + +/* + * if there is no '\n' before the PGP-Begin-Block, but for example a whitespace, + * GPGME doesn't recognise the Message as encrypted. This function adds '\n' + * before the PGP-Begin-Block, if missing. + */ +void GpgContext::preventNoDataErr(QByteArray *in) +{ + int block_start = in->indexOf("-----BEGIN PGP MESSAGE-----"); + if (block_start > 0 && in->at(block_start - 1) != '\n') { + in->insert(block_start, '\n'); + } + block_start = in->indexOf("-----BEGIN PGP SIGNED MESSAGE-----"); + if (block_start > 0 && in->at(block_start - 1) != '\n') { + in->insert(block_start, '\n'); + } +} + +/* + * isSigned returns: + * - 0, if text isn't signed at all + * - 1, if text is partially signed + * - 2, if text is completly signed + */ +int GpgContext::textIsSigned(const QByteArray &text) { + if (text.trimmed().startsWith("-----BEGIN PGP SIGNED MESSAGE-----") && text.trimmed().endsWith("-----END PGP SIGNATURE-----")) { + return 2; + } + if (text.contains("-----BEGIN PGP SIGNED MESSAGE-----") && text.contains("-----END PGP SIGNATURE-----")) { + return 1; + } + return 0; +} + +QString GpgContext::beautifyFingerprint(QString fingerprint) +{ + uint len = fingerprint.length(); + if ((len > 0) && (len % 4 == 0)) + for (uint n = 0; 4 *(n + 1) < len; ++n) + fingerprint.insert(5 * n + 4, ' '); + return fingerprint; +} + +} + + + + + diff --git a/gpgcontext.h b/gpgcontext.h new file mode 100644 index 0000000..101dbdf --- /dev/null +++ b/gpgcontext.h @@ -0,0 +1,127 @@ +/* + * context.h + * + * Copyright 2008 gpg4usb-team + * + * This file is part of gpg4usb. + * + * Gpg4usb 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 3 of the License, or + * (at your option) any later version. + * + * Gpg4usb 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 gpg4usb. If not, see + */ + +#ifndef __SGPGMEPP_CONTEXT_H__ +#define __SGPGMEPP_CONTEXT_H__ + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QMessageBox; +class sstream; +class QApplication; +class QByteArray; +class QString; +QT_END_NAMESPACE + +class GpgKey +{ +public: + GpgKey() { + privkey = false; + } + QString id; + QString name; + QString email; + QString fpr; + bool privkey; + bool expired; +}; + +typedef QLinkedList< GpgKey > GpgKeyList; + +namespace GpgME +{ + +class GpgContext : public QObject +{ + Q_OBJECT + +public: + GpgContext(); // Constructor + ~GpgContext(); // Destructor + + void importKey(QByteArray inBuffer); + bool exportKeys(QStringList *uidList, QByteArray *outBuffer); + void generateKey(QString *params); + GpgKeyList listKeys(); + void deleteKeys(QStringList *uidList); + bool encrypt(QStringList *uidList, const QByteArray &inBuffer, + QByteArray *outBuffer); + bool decrypt(const QByteArray &inBuffer, QByteArray *outBuffer); + void clearPasswordCache(); + void exportSecretKey(QString uid, QByteArray *outBuffer); + gpgme_key_t getKeyDetails(QString uid); + gpgme_signature_t verify(QByteArray in); +// void decryptVerify(QByteArray in); + bool sign(QStringList *uidList, const QByteArray &inBuffer, QByteArray *outBuffer ); + /** + * @details If text contains PGP-message, put a linebreak before the message, + * so that gpgme can decrypt correctly + * + * @param in Pointer to the QBytearray to check. + */ + void preventNoDataErr(QByteArray *in); + + /** + * @brief + * + * @param text + * @return \li 2, if the text is completly signed, + * \li 1, if the text is partially signed, + * \li 0, if the text is not signed at all. + */ + int textIsSigned(const QByteArray &text); + QString beautifyFingerprint(QString fingerprint); + +signals: + void keyDBChanged(); + +private: + gpgme_ctx_t mCtx; + gpgme_data_t in, out; + gpgme_error_t err; + gpgme_error_t readToBuffer(gpgme_data_t in, QByteArray *outBuffer); + QByteArray mPasswordCache; + QSettings settings; + bool debug; + int checkErr(gpgme_error_t err) const; + int checkErr(gpgme_error_t err, QString comment) const; + + static gpgme_error_t passphraseCb(void *hook, const char *uid_hint, + const char *passphrase_info, + int last_was_bad, int fd); + gpgme_error_t passphrase(const char *uid_hint, + const char *passphrase_info, + int last_was_bad, int fd); + + void executeGpgCommand(QStringList arguments, + QByteArray *stdOut, + QByteArray *stdErr); + +}; +} // namespace GpgME + +#endif // __SGPGMEPP_CONTEXT_H__ diff --git a/gpgwin.cpp b/gpgwin.cpp deleted file mode 100644 index dac830d..0000000 --- a/gpgwin.cpp +++ /dev/null @@ -1,782 +0,0 @@ -/* - * gpgwin.cpp - * - * Copyright 2008 gpg4usb-team - * - * This file is part of gpg4usb. - * - * Gpg4usb 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 3 of the License, or - * (at your option) any later version. - * - * Gpg4usb 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 gpg4usb. If not, see - */ - -#include "gpgwin.h" - -GpgWin::GpgWin() -{ - mCtx = new GpgME::Context(); - - /* get path were app was started */ - QString appPath = qApp->applicationDirPath(); - iconPath = appPath + "/icons/"; - - setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - - edit = new TextEdit(iconPath); - setCentralWidget(edit); - - /* the list of Keys available*/ - mKeyList = new KeyList(mCtx, iconPath); - - /* List of binary Attachments */ - attachmentDockCreated = false; - - keyMgmt = new KeyMgmt(mCtx, iconPath); - keyMgmt->hide(); - - /* test attachmentdir for files alll 15s */ - QTimer *timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(checkAttachmentFolder())); - timer->start(5000); - - createActions(); - createMenus(); - createToolBars(); - createStatusBar(); - createDockWindows(); - - mKeyList->addMenuAction(appendSelectedKeysAct); - mKeyList->addMenuAction(copyMailAddressToClipboardAct); - mKeyList->addMenuAction(showKeyDetailsAct); - - restoreSettings(); - - // open filename if provided as first command line parameter - QStringList args = qApp->arguments(); - if (args.size() > 1) { - if (!args[1].startsWith("-")) { - if (QFile::exists(args[1])) - edit->loadFile(args[1]); - } - } - edit->curTextPage()->setFocus(); - this->setWindowTitle(qApp->applicationName()); -} - -void GpgWin::restoreSettings() -{ - // state sets pos & size of dock-widgets - this->restoreState(settings.value("window/windowState").toByteArray()); - - // Restore window size & location - if (settings.value("window/windowSave").toBool()) { - QPoint pos = settings.value("window/pos", QPoint(100, 100)).toPoint(); - QSize size = settings.value("window/size", QSize(800, 450)).toSize(); - this->resize(size); - this->move(pos); - } else { - this->resize(QSize(800, 450)); - this->move(QPoint(100, 100)); - } - - // Iconsize - QSize iconSize = settings.value("toolbar/iconsize", QSize(32, 32)).toSize(); - this->setIconSize(iconSize); - - // set list of keyserver if not defined - QStringList *keyServerDefaultList; - keyServerDefaultList = new QStringList("http://gpg-keyserver.de"); - keyServerDefaultList->append("http://pgp.mit.edu"); - keyServerDefaultList->append("http://pool.sks-keyservers.net"); - keyServerDefaultList->append("http://subkeys.pgp.net"); - - QStringList keyServerList = settings.value("keyserver/keyServerList", *keyServerDefaultList).toStringList(); - settings.setValue("keyserver/keyServerList", keyServerList); - - // set default keyserver, if it's not set - QString defaultKeyServer = settings.value("keyserver/defaultKeyServer", QString("http://pgp.mit.edu")).toString(); - settings.setValue("keyserver/defaultKeyServer", defaultKeyServer); - - // Iconstyle - Qt::ToolButtonStyle buttonStyle = static_cast(settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon).toUInt()); - this->setToolButtonStyle(buttonStyle); - - // Checked Keys - if (settings.value("keys/keySave").toBool()) { - QStringList keyIds = settings.value("keys/keyList").toStringList(); - mKeyList->setChecked(&keyIds); - } -} - -void GpgWin::saveSettings() -{ - // window position and size - settings.setValue("window/windowState", saveState()); - settings.setValue("window/pos", pos()); - settings.setValue("window/size", size()); - - // keyid-list of private checked keys - if (settings.value("keys/keySave").toBool()) { - QStringList *keyIds = mKeyList->getPrivateChecked(); - if (!keyIds->isEmpty()) { - settings.setValue("keys/keyList", *keyIds); - } else { - settings.setValue("keys/keyList", ""); - } - } else { - settings.remove("keys/keyList"); - } -} - -void GpgWin::createActions() -{ - /* Main Menu - */ - newTabAct = new QAction(tr("&New"), this); - QList newTabActShortcutList; - newTabActShortcutList.append(QKeySequence (Qt::CTRL + Qt::Key_N)); - newTabActShortcutList.append(QKeySequence (Qt::CTRL + Qt::Key_T)); - newTabAct->setShortcuts(newTabActShortcutList); - - newTabAct->setToolTip(tr("Open a new file")); - connect(newTabAct, SIGNAL(triggered()), edit, SLOT(newTab())); - - openAct = new QAction(tr("&Open..."), this); - openAct->setIcon(QIcon(iconPath + "fileopen.png")); - openAct->setShortcut(QKeySequence::Open); - openAct->setToolTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), edit, SLOT(open())); - - saveAct = new QAction(tr("&Save"), this); - saveAct->setIcon(QIcon(iconPath + "filesave.png")); - saveAct->setShortcut(QKeySequence::Save); - saveAct->setToolTip(tr("Save the current File")); - connect(saveAct, SIGNAL(triggered()), edit, SLOT(save())); - - saveAsAct = new QAction(tr("Save &As")+"...", this); - saveAsAct->setIcon(QIcon(iconPath + "filesaveas.png")); - saveAsAct->setShortcut(QKeySequence::SaveAs); - saveAsAct->setToolTip(tr("Save the current File as...")); - connect(saveAsAct, SIGNAL(triggered()), edit, SLOT(saveAs())); - - printAct = new QAction(tr("&Print"), this); - printAct->setIcon(QIcon(iconPath + "fileprint.png")); - printAct->setShortcut(QKeySequence::Print); - printAct->setToolTip(tr("Print Document")); - connect(printAct, SIGNAL(triggered()), edit, SLOT(print())); - - closeTabAct = new QAction(tr("&Close"), this); - closeTabAct->setShortcut(QKeySequence::Close); - closeTabAct->setToolTip(tr("Close file")); - connect(closeTabAct, SIGNAL(triggered()), edit, SLOT(closeTab())); - - quitAct = new QAction(tr("&Quit"), this); - quitAct->setShortcut(QKeySequence::Quit); - quitAct->setIcon(QIcon(iconPath + "exit.png")); - quitAct->setToolTip(tr("Quit Program")); - connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); - - /* Edit Menu - */ - undoAct = new QAction(tr("&Undo"), this); - undoAct->setShortcut(QKeySequence::Undo); - undoAct->setToolTip(tr("Undo Last Edit Action")); - connect(undoAct, SIGNAL(triggered()), edit, SLOT(undo())); - - redoAct = new QAction(tr("&Redo"), this); - redoAct->setShortcut(QKeySequence::Redo); - redoAct->setToolTip(tr("Redo Last Edit Action")); - connect(redoAct, SIGNAL(triggered()), edit, SLOT(redo())); - - pasteAct = new QAction(tr("&Paste"), this); - pasteAct->setIcon(QIcon(iconPath + "button_paste.png")); - pasteAct->setShortcut(QKeySequence::Paste); - pasteAct->setToolTip(tr("Paste Text From Clipboard")); - connect(pasteAct, SIGNAL(triggered()), edit, SLOT(paste())); - - cutAct = new QAction(tr("Cu&t"), this); - cutAct->setIcon(QIcon(iconPath + "button_cut.png")); - cutAct->setShortcut(QKeySequence::Cut); - cutAct->setToolTip(tr("Cut the current selection's contents to the " - "clipboard")); - connect(cutAct, SIGNAL(triggered()), edit, SLOT(cut())); - - copyAct = new QAction(tr("&Copy"), this); - copyAct->setIcon(QIcon(iconPath + "button_copy.png")); - copyAct->setShortcut(QKeySequence::Copy); - copyAct->setToolTip(tr("Copy the current selection's contents to the " - "clipboard")); - connect(copyAct, SIGNAL(triggered()), edit, SLOT(copy())); - - quoteAct = new QAction(tr("&Quote"), this); - quoteAct->setIcon(QIcon(iconPath + "quote.png")); - quoteAct->setToolTip(tr("Quote whole text")); - connect(quoteAct, SIGNAL(triggered()), edit, SLOT(quote())); - - selectallAct = new QAction(tr("Select &All"), this); - selectallAct->setIcon(QIcon(iconPath + "edit.png")); - selectallAct->setShortcut(QKeySequence::SelectAll); - selectallAct->setToolTip(tr("Select the whole text")); - connect(selectallAct, SIGNAL(triggered()), edit, SLOT(selectAll())); - - cleanDoubleLinebreaksAct = new QAction(tr("Remove double &Linebreaks"), this); - //cleanDoubleLineBreaksAct->setIcon(QIcon(iconPath + "edit.png")); - //cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll); - cleanDoubleLinebreaksAct->setToolTip(tr("Remove double linebreaks, e.g. in pasted text from webmailer")); - connect(cleanDoubleLinebreaksAct, SIGNAL(triggered()), this, SLOT(cleanDoubleLinebreaks())); - - openSettingsAct = new QAction(tr("Se&ttings"), this); - openSettingsAct->setToolTip(tr("Open settings dialog")); - openSettingsAct->setShortcut(QKeySequence::Preferences); - connect(openSettingsAct, SIGNAL(triggered()), this, SLOT(openSettingsDialog())); - - /* Crypt Menu - */ - encryptAct = new QAction(tr("&Encrypt"), this); - encryptAct->setIcon(QIcon(iconPath + "encrypted.png")); - encryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); - encryptAct->setToolTip(tr("Encrypt Message")); - connect(encryptAct, SIGNAL(triggered()), this, SLOT(encrypt())); - - decryptAct = new QAction(tr("&Decrypt"), this); - decryptAct->setIcon(QIcon(iconPath + "decrypted.png")); - decryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); - decryptAct->setToolTip(tr("Decrypt Message")); - connect(decryptAct, SIGNAL(triggered()), this, SLOT(decrypt())); - - fileEncryptionAct = new QAction(tr("&File Encryption"), this); - fileEncryptionAct->setIcon(QIcon(iconPath + "fileencrytion.png")); - fileEncryptionAct->setToolTip(tr("Encrypt/Decrypt File")); - connect(fileEncryptionAct, SIGNAL(triggered()), this, SLOT(fileEncryption())); - - signAct = new QAction(tr("&Sign"), this); - signAct->setIcon(QIcon(iconPath + "signature.png")); - signAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I)); - signAct->setToolTip(tr("Sign Message")); - connect(signAct, SIGNAL(triggered()), this, SLOT(sign())); - - verifyAct = new QAction(tr("&Verify"), this); - verifyAct->setIcon(QIcon(iconPath + "verify.png")); - verifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V)); - verifyAct->setToolTip(tr("Verify Message")); - connect(verifyAct, SIGNAL(triggered()), this, SLOT(verify())); - - /* Key Menu - */ - - importKeyFromEditAct = new QAction(tr("&Editor"), this); - importKeyFromEditAct->setIcon(QIcon(iconPath + "txt.png")); - importKeyFromEditAct->setToolTip(tr("Import New Key From Editor")); - connect(importKeyFromEditAct, SIGNAL(triggered()), this, SLOT(importKeyFromEdit())); - - openKeyManagementAct = new QAction(tr("Key Management"), this); - openKeyManagementAct->setIcon(QIcon(iconPath + "keymgmt.png")); - openKeyManagementAct->setToolTip(tr("Open Keymanagement")); - connect(openKeyManagementAct, SIGNAL(triggered()), this, SLOT(openKeyManagement())); - - importKeyDialogAct = new QAction(tr("Import Key"), this); - importKeyDialogAct->setIcon(QIcon(iconPath + "key_import.png")); - importKeyDialogAct->setToolTip(tr("Open Import New Key Dialog")); - connect(importKeyDialogAct, SIGNAL(triggered()), this, SLOT(importKeyDialog())); - - /* About Menu - */ - aboutAct = new QAction(tr("&About"), this); - aboutAct->setIcon(QIcon(iconPath + "help.png")); - aboutAct->setToolTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - openTutorialAct = new QAction(tr("Online &Tutorial"), this); - openTutorialAct->setIcon(QIcon(iconPath + "help.png")); - openTutorialAct->setToolTip(tr("Open Online Tutorial")); - connect(openTutorialAct, SIGNAL(triggered()), this, SLOT(openTutorial())); - - openTranslateAct = new QAction(tr("Translate gpg4usb"), this); - openTranslateAct->setToolTip(tr("Translate gpg4usb yourself")); - connect(openTranslateAct, SIGNAL(triggered()), this, SLOT(openTranslate())); - - /* Popup-Menu-Action for KeyList - */ - appendSelectedKeysAct = new QAction(tr("Append Selected Key(s) To Text"), this); - appendSelectedKeysAct->setToolTip(tr("Append The Selected Keys To Text in Editor")); - connect(appendSelectedKeysAct, SIGNAL(triggered()), this, SLOT(appendSelectedKeys())); - - copyMailAddressToClipboardAct = new QAction(tr("Copy EMail-address"), this); - copyMailAddressToClipboardAct->setToolTip(tr("Copy selected EMailaddress to clipboard")); - connect(copyMailAddressToClipboardAct, SIGNAL(triggered()), this, SLOT(copyMailAddressToClipboard())); - - // TODO: find central place for shared actions, to avoid code-duplication with keymgmt.cpp - showKeyDetailsAct = new QAction(tr("Show Keydetails"), this); - showKeyDetailsAct->setToolTip(tr("Show Details for this Key")); - connect(showKeyDetailsAct, SIGNAL(triggered()), this, SLOT(showKeyDetails())); - - /* Key-Shortcuts for Tab-Switchung-Action - */ - switchTabUpAct = new QAction(this); - switchTabUpAct->setShortcut(QKeySequence::NextChild); - connect(switchTabUpAct, SIGNAL(triggered()), edit, SLOT(switchTabUp())); - this->addAction(switchTabUpAct); - - switchTabDownAct = new QAction(this); - switchTabDownAct->setShortcut(QKeySequence::PreviousChild); - connect(switchTabDownAct, SIGNAL(triggered()), edit, SLOT(switchTabDown())); - this->addAction(switchTabDownAct); -} - -void GpgWin::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newTabAct); - fileMenu->addAction(openAct); - fileMenu->addSeparator(); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(printAct); - fileMenu->addSeparator(); - fileMenu->addAction(closeTabAct); - fileMenu->addAction(quitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(undoAct); - editMenu->addAction(redoAct); - editMenu->addSeparator(); - editMenu->addAction(copyAct); - editMenu->addAction(cutAct); - editMenu->addAction(pasteAct); - editMenu->addAction(selectallAct); - editMenu->addAction(quoteAct); - editMenu->addAction(cleanDoubleLinebreaksAct); - editMenu->addSeparator(); - editMenu->addAction(openSettingsAct); - - cryptMenu = menuBar()->addMenu(tr("&Crypt")); - cryptMenu->addAction(encryptAct); - cryptMenu->addAction(decryptAct); - cryptMenu->addSeparator(); - cryptMenu->addAction(signAct); - cryptMenu->addAction(verifyAct); - cryptMenu->addSeparator(); - cryptMenu->addAction(fileEncryptionAct); - - keyMenu = menuBar()->addMenu(tr("&Keys")); - importKeyMenu = keyMenu->addMenu(tr("&Import Key From...")); - importKeyMenu->setIcon(QIcon(iconPath + "key_import.png")); - importKeyMenu->addAction(keyMgmt->importKeyFromFileAct); - importKeyMenu->addAction(importKeyFromEditAct); - importKeyMenu->addAction(keyMgmt->importKeyFromClipboardAct); - importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); - importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); - keyMenu->addAction(openKeyManagementAct); - - viewMenu = menuBar()->addMenu(tr("&View")); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(openTutorialAct); - helpMenu->addAction(openTranslateAct); - helpMenu->addAction(aboutAct); -} - -void GpgWin::createToolBars() -{ - cryptToolBar = addToolBar(tr("Crypt")); - cryptToolBar->setObjectName("cryptToolBar"); - cryptToolBar->addAction(encryptAct); - cryptToolBar->addAction(decryptAct); - cryptToolBar->addAction(signAct); - cryptToolBar->addAction(verifyAct); - cryptToolBar->addAction(fileEncryptionAct); - viewMenu->addAction(cryptToolBar->toggleViewAction()); - - keyToolBar = addToolBar(tr("Key")); - keyToolBar->setObjectName("keyToolBar"); - keyToolBar->addAction(importKeyDialogAct); - keyToolBar->addAction(openKeyManagementAct); - viewMenu->addAction(keyToolBar->toggleViewAction()); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->setObjectName("editToolBar"); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); - editToolBar->addAction(selectallAct); - editToolBar->addAction(quoteAct); - viewMenu->addAction(editToolBar->toggleViewAction()); -} - -void GpgWin::createStatusBar() -{ - QWidget *statusBarBox = new QWidget(); - QHBoxLayout *statusBarBoxLayout = new QHBoxLayout(); - QPixmap *pixmap; - - // icon which should be shown if there are files in attachments-folder - pixmap = new QPixmap(iconPath + "statusbar_icon.png"); - statusBarIcon = new QLabel(statusBar()); - statusBarIcon->setPixmap(*pixmap); - statusBar()->insertPermanentWidget(0,statusBarIcon,0); - statusBarIcon->hide(); - statusBar()->showMessage(tr("Ready"),2000); - statusBarBox->setLayout(statusBarBoxLayout); -} - -void GpgWin::createDockWindows() -{ - /* KeyList-Dockwindow - */ - keylistDock = new QDockWidget(tr("Encrypt for:"), this); - keylistDock->setObjectName("EncryptDock"); - keylistDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - addDockWidget(Qt::RightDockWidgetArea, keylistDock); - keylistDock->setWidget(mKeyList); - viewMenu->addAction(keylistDock->toggleViewAction()); - - /* Attachments-Dockwindow - */ - if(settings.value("mime/parseMime").toBool()) { - createAttachmentDock(); - } -} - -void GpgWin::createAttachmentDock() { - if (attachmentDockCreated) { - return; - } - mAttachments = new Attachments(iconPath); - attachmentDock = new QDockWidget(tr("Attached files:"), this); - attachmentDock->setObjectName("AttachmentDock"); - attachmentDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); - addDockWidget(Qt::BottomDockWidgetArea, attachmentDock); - attachmentDock->setWidget(mAttachments); - // hide till attachment is decrypted - viewMenu->addAction(attachmentDock->toggleViewAction()); - attachmentDock->hide(); - attachmentDockCreated = true; -} - -void GpgWin::closeAttachmentDock() { - if (!attachmentDockCreated) { - return; - } - attachmentDock->close(); - attachmentDock->deleteLater(); - attachmentDockCreated = false; -} - -void GpgWin::closeEvent(QCloseEvent *event) -{ - /* - * ask to save changes, if there are - * modified documents in any tab - */ - if (edit->maybeSaveAnyTab()) { - saveSettings(); - event->accept(); - } else { - event->ignore(); - } - - // clear password from memory - mCtx->clearPasswordCache(); -} - -void GpgWin::about() -{ - QPixmap *pixmap = new QPixmap(iconPath + "gpg4usb-logo.png"); - QString *title = new QString(tr("About ") + qApp->applicationName()); - QString *text = new QString("

" + qApp->applicationName() + " " - + qApp->applicationVersion() + "

" - + tr("
This application allows simple encryption
" - "and decryption of text messages or files.
" - "It's licensed under the GPL v3

" - "Developer:
" - "Bene, Heimer, Juergen, Nils, Ubbo

" - "Translation:
" - "Alessandro (pt_br), Kirill (ru), Viriato (es), Serse (it)

" - "If you have any questions or suggestions have a look
" - "at our " - "contact page or send a mail to our
mailing list at" - " gpg4usb@gzehn.de.")); - - QDialog *dialog = new QDialog(this); - dialog->setWindowTitle(*title); - QPushButton *closeButton = new QPushButton(tr("&Close")); - connect(closeButton, SIGNAL(clicked()), dialog, SLOT(close())); - - QGridLayout *layout = new QGridLayout(dialog); - QLabel *pixmapLabel = new QLabel(); - pixmapLabel->setPixmap(*pixmap); - layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); - QLabel *aboutLabel = new QLabel(); - aboutLabel->setText(*text); - aboutLabel->setOpenExternalLinks(true); - layout->addWidget(aboutLabel, 1, 0, 1, -1); - layout->addItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, - QSizePolicy::Fixed), 2, 1, 1, 1); - layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 0, 1, 1); - layout->addWidget(closeButton, 3, 1, 1, 1); - layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 2, 1, 1); - - dialog->exec(); -} - -void GpgWin::openTranslate() { - QDesktopServices::openUrl(QUrl("http://gpg4usb.cpunk.de/docu_translate.html")); -} - -void GpgWin::openTutorial() { - QDesktopServices::openUrl(QUrl("http://gpg4usb.cpunk.de/docu.html")); -} - -/* - * if this is mime, split text and attachments... - * message contains only text afterwards - */ -void GpgWin::parseMime(QByteArray *message) -{ - /*if (! Mime::isMultipart(message)) { - qDebug() << "no multipart"; - return; - }*/ - //qDebug() << "multipart"; - - QString pText; - bool showmadock = false; - - Mime *mime = new Mime(message); - foreach(MimePart tmp, mime->parts()) { - if (tmp.header.getValue("Content-Type") == "text/plain" - && tmp.header.getValue("Content-Transfer-Encoding") != "base64") { - - QByteArray body; - if (tmp.header.getValue("Content-Transfer-Encoding") == "quoted-printable") { - Mime::quotedPrintableDecode(tmp.body, body); - } else { - body = tmp.body; - } - pText.append(QString(body)); - } else { - (mAttachments->addMimePart(&tmp)); - showmadock = true; - } - } - *message = pText.toUtf8(); - if (showmadock) { - attachmentDock->show(); - } -} - -void GpgWin::checkAttachmentFolder() { - // TODO: always check? - if(!settings.value("mime/parseMime").toBool()) { - return; - } - - QString attachmentDir = qApp->applicationDirPath() + "/attachments/"; - // filenum minus . and .. - int filenum = QDir(attachmentDir).count() - 2 ; - if(filenum > 0) { - QString statusText; - if(filenum == 1) { - statusText = tr("There is one unencrypted file in attachment folder"); - } else { - statusText = tr("There are ") + QString::number(filenum) + tr(" unencrypted files in attachment folder"); - } - statusBarIcon->setStatusTip(statusText); - statusBarIcon->show(); - } else { - statusBarIcon->hide(); - } -} - -void GpgWin::importKeyFromEdit() -{ - mCtx->importKey(edit->curTextPage()->toPlainText().toAscii()); -} - -void GpgWin::openKeyManagement() -{ - keyMgmt->show(); - keyMgmt->raise(); - keyMgmt->activateWindow(); -} - -void GpgWin::encrypt() -{ - QStringList *uidList = mKeyList->getChecked(); - - QByteArray *tmp = new QByteArray(); - if (mCtx->encrypt(uidList, edit->curTextPage()->toPlainText().toUtf8(), tmp)) { - QString *tmp2 = new QString(*tmp); - edit->fillTextEditWithText(*tmp2); - } -} - -void GpgWin::sign() -{ - QStringList *uidList = mKeyList->getPrivateChecked(); - - QByteArray *tmp = new QByteArray(); - // TODO: toUtf8() here? - if (mCtx->sign(uidList, edit->curTextPage()->toPlainText().toAscii(), tmp)) { - QString *tmp2 = new QString(*tmp); - edit->fillTextEditWithText(*tmp2); - } -} - -void GpgWin::decrypt() -{ - QByteArray *decrypted = new QByteArray(); - QByteArray text = edit->curTextPage()->toPlainText().toAscii(); // TODO: toUtf8() here? - mCtx->preventNoDataErr(&text); - - // try decrypt, if fail do nothing, especially don't replace text - if(!mCtx->decrypt(text, decrypted)) { - return; - } - - /* - * 1) is it mime (content-type:) - * 2) parse header - * 2) choose action depending on content-type - */ - if(Mime::isMime(decrypted)) { - Header header = Mime::getHeader(decrypted); - // is it multipart, is multipart-parsing enabled - if(header.getValue("Content-Type") == "multipart/mixed" - && settings.value("mime/parseMime").toBool()) { - parseMime(decrypted); - } else if(header.getValue("Content-Type") == "text/plain" - && settings.value("mime/parseQP").toBool()){ - if (header.getValue("Content-Transfer-Encoding") == "quoted-printable") { - QByteArray *decoded = new QByteArray(); - Mime::quotedPrintableDecode(*decrypted, *decoded); - //TODO: remove header - decrypted = decoded; - } - } - } - edit->fillTextEditWithText(QString::fromUtf8(*decrypted)); -} - -void GpgWin::verify() -{ - // At first close verifynotification, if existing - edit->curPage()->closeNoteByClass("verifyNotification"); - - // create new verfiy notification - VerifyNotification *vn = new VerifyNotification(this, mCtx, mKeyList, edit->curTextPage()); - - // if signing information is found, show the notification, otherwise close it - if (vn->refresh()) { - edit->curPage()->showNotificationWidget(vn, "verifyNotification"); - } else { - vn->close(); - } -} - -void GpgWin::importKeyDialog() -{ - QDialog *dialog = new QDialog(); - - dialog->setWindowTitle(tr("Import Key")); - dialog->setModal(true); - - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); - - QGroupBox *groupBox = new QGroupBox(tr("Import Key From...")); - QRadioButton *radio1 = new QRadioButton(tr("&File")); - QRadioButton *radio2 = new QRadioButton(tr("&Editor")); - QRadioButton *radio3 = new QRadioButton(tr("&Clipboard")); - QRadioButton *radio4 = new QRadioButton(tr("&Keyserver")); - radio1->setChecked(true); - - QVBoxLayout *vbox1 = new QVBoxLayout(); - vbox1->addWidget(radio1); - vbox1->addWidget(radio2); - vbox1->addWidget(radio3); - vbox1->addWidget(radio4); - groupBox->setLayout(vbox1); - - QVBoxLayout *vbox2 = new QVBoxLayout(); - vbox2->addWidget(groupBox); - vbox2->addWidget(buttonBox); - dialog->setLayout(vbox2); - - if (dialog->exec() == QDialog::Accepted) { - if (radio1->isChecked()) keyMgmt->importKeyFromFile(); - if (radio2->isChecked()) importKeyFromEdit(); - if (radio3->isChecked()) keyMgmt->importKeyFromClipboard(); - if (radio4->isChecked()) keyMgmt->importKeyFromKeyServer(); - } -} - -/* - * Append the selected (not checked!) Key(s) To Textedit - */ -void GpgWin::appendSelectedKeys() -{ - QByteArray *keyArray = new QByteArray(); - mCtx->exportKeys(mKeyList->getSelected(), keyArray); - edit->curTextPage()->appendPlainText(*keyArray); -} - -void GpgWin::copyMailAddressToClipboard() -{ - gpgme_key_t key = mCtx->getKeyDetails(mKeyList->getSelected()->first()); - QClipboard *cb = QApplication::clipboard(); - QString mail = key->uids->email; - cb->setText(mail); -} - -void GpgWin::showKeyDetails() -{ - // TODO: first...? - gpgme_key_t key = mCtx->getKeyDetails(mKeyList->getSelected()->first()); - new KeyDetailsDialog(mCtx, key, this); -} - -void GpgWin::fileEncryption() -{ - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, iconPath, *keyList, this); -} - -void GpgWin::openSettingsDialog() -{ - new SettingsDialog(this); - // Iconsize - QSize iconSize = settings.value("toolbar/iconsize", QSize(32, 32)).toSize(); - this->setIconSize(iconSize); - - // Iconstyle - Qt::ToolButtonStyle buttonStyle = static_cast(settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon).toUInt()); - this->setToolButtonStyle(buttonStyle); - - if(settings.value("mime/parseMime").toBool()) { - createAttachmentDock(); - } else if(attachmentDockCreated) { - closeAttachmentDock(); - } - -} - -void GpgWin::cleanDoubleLinebreaks() -{ - QString content = edit->curTextPage()->toPlainText(); - content.replace("\n\n", "\n"); - edit->fillTextEditWithText(content); -} diff --git a/gpgwin.h b/gpgwin.h deleted file mode 100644 index a46094a..0000000 --- a/gpgwin.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * gpgwin.h - * - * Copyright 2008 gpg4usb-team - * - * This file is part of gpg4usb. - * - * Gpg4usb 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 3 of the License, or - * (at your option) any later version. - * - * Gpg4usb 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 gpg4usb. If not, see - */ - -#ifndef __GPGWIN_H__ -#define __GPGWIN_H__ - -#include "attachments.h" -#include "keymgmt.h" -#include "textedit.h" -#include "fileencryptiondialog.h" -#include "settingsdialog.h" -#include "verifynotification.h" - -QT_BEGIN_NAMESPACE -class QMainWindow; -class QPlainTextEdit; -class QWidget; -class QVBoxLayout; -class QGridLayout; -class iostream; -class QtGui; -class QString; -class QFileDialog; -class QStringList; -class QIcon; -class QMessageBox; -class QVBoxLayout; -class QAction; -class QMenu; -class QPlainTextEdit; -class QComboBox; -class QPushButton; -class QRadioButton; -class QButtonGroup; -class QApplication; -class QDockWidget; -QT_END_NAMESPACE - - -/** - * @brief - * - */ -class GpgWin : public QMainWindow -{ - Q_OBJECT - -public: - /** - * @brief - * - */ - GpgWin(); - -protected: - /** - * @details Close event shows a save dialog, if there are unsaved documents on exit. - * @param event - */ - void closeEvent(QCloseEvent *event); - -private slots: - /** - * @details encrypt the text of currently active textedit-page - * with the currently checked keys - */ - void encrypt(); - - /** - * @details Show a passphrase dialog and decrypt the text of currently active tab. - */ - void decrypt(); - - /** - * @details Sign the text of currently active tab with the checked private keys - */ - void sign(); - - /** - * @details Verify the text of currently active tab and show verify information. - * If document is signed with a key, which is not in keylist, show import missing - * key from keyserver in Menu of verifynotification. - */ - void verify(); - - void showKeyDetails(); - - /** - * @details Import keys from currently active tab to keylist if possible. - */ - void importKeyFromEdit(); - - /** - * @details Open a dialog, in which you can choose, where keys should be imported from. - */ - void importKeyDialog(); - - /** - * @details Append the selected keys to currently active textedit. - */ - void appendSelectedKeys(); - - /** - * @details Copy the mailaddress of selected key to clipboard. - * Method for keylists contextmenu. - */ - void copyMailAddressToClipboard(); - - /** - * @details Open key management dialog. - */ - void openKeyManagement(); - - /** - * @details Open about-dialog. - */ - void about(); - - /** - * @details Open fileencrytion dialog. - */ - void fileEncryption(); - - /** - * @details Open settings-dialog. - */ - void openSettingsDialog(); - - /** - * @details Open online-tutorial in default browser. - */ - void openTutorial(); - - /** - * @details Show a warn message in status bar, if there are files in attachment folder. - */ - void checkAttachmentFolder(); - - /** - * @details Open online translation tutorial in default browser. - */ - void openTranslate(); - - /** - * @details Replace double linebreaks by single linebreaks in currently active tab. - */ - void cleanDoubleLinebreaks(); -// void dropEvent(QDropEvent *event); - -private: - /** - * @details Create actions for the main-menu and the context-menu of the keylist. - */ - void createActions(); - - /** - * @details create the menu of the main-window. - */ - void createMenus(); - - /** - * @details Create edit-, crypt- and key-toolbars. - */ - void createToolBars(); - - /** - * @details Create statusbar of mainwindow. - */ - void createStatusBar(); - - /** - * @details Create keylist- and attachment-dockwindows. - */ - void createDockWindows(); - - /** - * @details Create attachment-dockwindow. - */ - void createAttachmentDock(); - - /** - * @details close attachment-dockwindow. - */ - void closeAttachmentDock(); - - /** - * @details Load settings from ini-file. - */ - void restoreSettings(); - - /** - * @details Save settings to ini-file. - */ - void saveSettings(); - - /** - * @brief - * - * @param message - */ - void parseMime(QByteArray *message); - - TextEdit *edit; /** Tabwidget holding the edit-windows */ - QMenu *fileMenu; /** Submenu for file-operations*/ - QMenu *editMenu; /** Submenu for text-operations*/ - QMenu *cryptMenu; /** Submenu for crypt-operations */ - QMenu *helpMenu; /** Submenu for help-operations */ - QMenu *keyMenu; /** Submenu for key-operations */ - QMenu *viewMenu; /** View submenu */ - QMenu *importKeyMenu; /** Sumenu for import operations */ - QToolBar *cryptToolBar; /** Toolbar holding crypt actions */ - QToolBar *editToolBar; /** Toolbar holding edit actions */ - QToolBar *keyToolBar; /** Toolbar holding key operations */ - QDockWidget *keylistDock; /** Encrypt Dock*/ - QDockWidget *attachmentDock; /** Attachment Dock */ - QDialog *genkeyDialog; /** Dialog for key generation */ - - QAction *newTabAct; /** Action to create new tab */ - QAction *switchTabUpAct; /** Action to switch tab up*/ - QAction *switchTabDownAct; /** Action to switch tab down */ - QAction *openAct; /** Action to open file */ - QAction *saveAct; /** Action to save file */ - QAction *saveAsAct; /** Action to save file as */ - QAction *printAct; /** Action to print */ - QAction *closeTabAct; /** Action to print */ - QAction *quitAct; /** Action to quit application */ - QAction *encryptAct; /** Action to encrypt text */ - QAction *decryptAct; /** Action to decrypt text */ - QAction *signAct; /** Action to sign text */ - QAction *verifyAct; /** Action to verify text */ - QAction *importKeyDialogAct; /** Action to open key dialog */ - QAction *importKeyFromEditAct; /** Action to import key from edit */ - QAction *cleanDoubleLinebreaksAct; /** Action to remove double line breaks */ - - QAction *appendSelectedKeysAct; /** Action to append selected keys to edit */ - QAction *copyMailAddressToClipboardAct; /** Action to copy mail to clipboard */ - QAction *openKeyManagementAct; /** Action to open key management */ - QAction *copyAct; /** Action to copy text */ - QAction *quoteAct; /** Action to quote text */ - QAction *cutAct; /** Action to cut text */ - QAction *pasteAct; /** Action to paste text */ - QAction *selectallAct; /** Action to select whole text */ - QAction *undoAct; /** Action to undo last action */ - QAction *redoAct; /** Action to redo last action */ - QAction *aboutAct; /** Action to open about dialog */ - QAction *fileEncryptionAct; /** Action to open file-encryption dialog */ - QAction *openSettingsAct; /** Action to open settings dialog */ - QAction *openTranslateAct; /** Action to open translate doc*/ - QAction *openTutorialAct; /** Action to open tutorial */ - QAction *showKeyDetailsAct; /** Action to open key-details dialog */ - QLineEdit *nameEdit; /**< TODO */ - QLineEdit *emailEdit; /**< TODO */ - QLineEdit *commentEdit; /**< TODO */ - QLineEdit *passwordEdit; /**< TODO */ - QLineEdit *repeatpwEdit; /**< TODO */ - QSpinBox *keysizeSpinBox; /**< TODO */ - QLabel *nameLabel; /**< TODO */ - QLabel *emailLabel; /**< TODO */ - QLabel *commentLabel; /**< TODO */ - QLabel *keysizeLabel; /**< TODO */ - QLabel *passwordLabel; /**< TODO */ - QLabel *repeatpwLabel; /**< TODO */ - QLabel *errorLabel; /**< TODO */ - QLabel *statusBarIcon; /**< TODO */ - - QSettings settings; /**< TODO */ - KeyList *mKeyList; /**< TODO */ - Attachments *mAttachments; /**< TODO */ - GpgME::Context *mCtx; /**< TODO */ - QString iconPath; /**< TODO */ - KeyMgmt *keyMgmt; /**< TODO */ - KeyServerImportDialog *importDialog; /**< TODO */ - bool attachmentDockCreated; -}; - -#endif // __GPGWIN_H__ diff --git a/keydetailsdialog.cpp b/keydetailsdialog.cpp index 3570bb6..6911fe1 100644 --- a/keydetailsdialog.cpp +++ b/keydetailsdialog.cpp @@ -21,7 +21,7 @@ #include "keydetailsdialog.h" -KeyDetailsDialog::KeyDetailsDialog(GpgME::Context* ctx, gpgme_key_t key, QWidget *parent) +KeyDetailsDialog::KeyDetailsDialog(GpgME::GpgContext* ctx, gpgme_key_t key, QWidget *parent) : QDialog(parent) { diff --git a/keydetailsdialog.h b/keydetailsdialog.h index c282749..a655a4b 100644 --- a/keydetailsdialog.h +++ b/keydetailsdialog.h @@ -22,7 +22,7 @@ #ifndef __KEYDETAILSDIALOG_H__ #define __KEYDETAILSDIALOG_H__ -#include "context.h" +#include "gpgcontext.h" #include QT_BEGIN_NAMESPACE @@ -42,7 +42,7 @@ class KeyDetailsDialog : public QDialog Q_OBJECT public: - KeyDetailsDialog(GpgME::Context* ctx, gpgme_key_t key, QWidget *parent = 0); + KeyDetailsDialog(GpgME::GpgContext* ctx, gpgme_key_t key, QWidget *parent = 0); static QString beautifyFingerprint(QString fingerprint); private slots: @@ -50,7 +50,7 @@ private slots: private: QString *keyid; - GpgME::Context *mCtx; + GpgME::GpgContext *mCtx; QGroupBox *ownerBox; QGroupBox *keyBox; diff --git a/keygenthread.cpp b/keygenthread.cpp index ecab317..0065ea8 100644 --- a/keygenthread.cpp +++ b/keygenthread.cpp @@ -21,7 +21,7 @@ #include "keygenthread.h" -KeyGenThread::KeyGenThread(QString keyGenParams, GpgME::Context *ctx) +KeyGenThread::KeyGenThread(QString keyGenParams, GpgME::GpgContext *ctx) { this->keyGenParams = keyGenParams; this->ctx = ctx; diff --git a/keygenthread.h b/keygenthread.h index 3a52e7f..5e9c78d 100644 --- a/keygenthread.h +++ b/keygenthread.h @@ -22,7 +22,7 @@ #ifndef __KEYGENTHREAD_H__ #define __KEYGENTHREAD_H__ -#include "context.h" +#include "gpgcontext.h" #include #include #include @@ -38,14 +38,14 @@ class KeyGenThread : public QThread Q_OBJECT public: - KeyGenThread(QString keyGenParams, GpgME::Context *ctx); + KeyGenThread(QString keyGenParams, GpgME::GpgContext *ctx); signals: void keyGenerated(); private: QString keyGenParams; - GpgME::Context *ctx; + GpgME::GpgContext *ctx; bool abort; QMutex mutex; diff --git a/keylist.cpp b/keylist.cpp index 585c707..c098ba4 100644 --- a/keylist.cpp +++ b/keylist.cpp @@ -21,7 +21,7 @@ #include "keylist.h" -KeyList::KeyList(GpgME::Context *ctx, QString iconpath, QWidget *parent) +KeyList::KeyList(GpgME::GpgContext *ctx, QString iconpath, QWidget *parent) : QWidget(parent) { mCtx = ctx; diff --git a/keylist.h b/keylist.h index 7184441..800e9fc 100644 --- a/keylist.h +++ b/keylist.h @@ -22,7 +22,7 @@ #ifndef __KEYLIST_H__ #define __KEYLIST_H__ -#include "context.h" +#include "gpgcontext.h" QT_BEGIN_NAMESPACE class QWidget; @@ -37,7 +37,7 @@ class KeyList : public QWidget Q_OBJECT public: - KeyList(GpgME::Context *ctx, QString iconpath, QWidget *parent = 0); + KeyList(GpgME::GpgContext *ctx, QString iconpath, QWidget *parent = 0); void setColumnWidth(int row, int size); void addMenuAction(QAction *act); @@ -55,7 +55,7 @@ public slots: void refresh(); private: - GpgME::Context *mCtx; + GpgME::GpgContext *mCtx; QTableWidget *mKeyList; QString iconPath; QMenu *popupMenu; diff --git a/keymgmt.cpp b/keymgmt.cpp index 730ecdb..602d8b9 100755 --- a/keymgmt.cpp +++ b/keymgmt.cpp @@ -22,7 +22,7 @@ #include "keymgmt.h" -KeyMgmt::KeyMgmt(GpgME::Context *ctx, QString iconpath) +KeyMgmt::KeyMgmt(GpgME::GpgContext *ctx, QString iconpath) { mCtx = ctx; mIconPath = iconpath; diff --git a/keymgmt.h b/keymgmt.h index a287f21..c4a5122 100755 --- a/keymgmt.h +++ b/keymgmt.h @@ -48,7 +48,7 @@ class KeyMgmt : public QMainWindow Q_OBJECT public: - KeyMgmt(GpgME::Context* ctx, QString iconpath); + KeyMgmt(GpgME::GpgContext* ctx, QString iconpath); QAction *importKeyFromClipboardAct; QAction *importKeyFromFileAct; QAction *importKeyFromKeyServerAct; @@ -79,7 +79,7 @@ private: KeyList *mKeyList; QString mIconPath; - GpgME::Context *mCtx; + GpgME::GpgContext *mCtx; QMenu *fileMenu; QMenu *keyMenu; QMenu *importKeyMenu; diff --git a/keyserverimportdialog.cpp b/keyserverimportdialog.cpp index b545e1b..1e85e69 100644 --- a/keyserverimportdialog.cpp +++ b/keyserverimportdialog.cpp @@ -22,7 +22,7 @@ #include "keyserverimportdialog.h" -KeyServerImportDialog::KeyServerImportDialog(GpgME::Context *ctx, QWidget *parent) +KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, QWidget *parent) : QDialog(parent) { mCtx = ctx; diff --git a/keyserverimportdialog.h b/keyserverimportdialog.h index 6c92b2c..b42953a 100644 --- a/keyserverimportdialog.h +++ b/keyserverimportdialog.h @@ -23,7 +23,7 @@ #ifndef __KEYSERVERIMPORTDIALOG_H__ #define __KEYSERVERIMPORTDIALOG_H__ -#include "context.h" +#include "gpgcontext.h" #include #include @@ -50,7 +50,7 @@ class KeyServerImportDialog : public QDialog Q_OBJECT public: - KeyServerImportDialog(GpgME::Context *ctx, QWidget *parent = 0); + KeyServerImportDialog(GpgME::GpgContext *ctx, QWidget *parent = 0); void import(QStringList keyIds); void import(QStringList keyIds, QUrl keyserverUrl); @@ -68,7 +68,7 @@ private: QPushButton *createButton(const QString &text, const char *member); QComboBox *createComboBox(); - GpgME::Context *mCtx; + GpgME::GpgContext *mCtx; QLineEdit *searchLineEdit; QComboBox *keyServerComboBox; QLabel *searchLabel; diff --git a/main.cpp b/main.cpp index a55bd9a..cfe7ae2 100644 --- a/main.cpp +++ b/main.cpp @@ -20,7 +20,7 @@ */ #include -#include "gpgwin.h" +#include "mainwindow.h" int main(int argc, char *argv[]) { @@ -83,7 +83,7 @@ int main(int argc, char *argv[]) QString styleSheet = QLatin1String(file.readAll()); qApp->setStyleSheet(styleSheet); - GpgWin *window = new GpgWin(); + MainWindow *window = new MainWindow(); window->show(); return app.exec(); diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..dd7c63e --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,782 @@ +/* + * gpgwin.cpp + * + * Copyright 2008 gpg4usb-team + * + * This file is part of gpg4usb. + * + * Gpg4usb 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 3 of the License, or + * (at your option) any later version. + * + * Gpg4usb 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 gpg4usb. If not, see + */ + +#include "mainwindow.h" + +MainWindow::MainWindow() +{ + mCtx = new GpgME::GpgContext(); + + /* get path were app was started */ + QString appPath = qApp->applicationDirPath(); + iconPath = appPath + "/icons/"; + + setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + + edit = new TextEdit(iconPath); + setCentralWidget(edit); + + /* the list of Keys available*/ + mKeyList = new KeyList(mCtx, iconPath); + + /* List of binary Attachments */ + attachmentDockCreated = false; + + keyMgmt = new KeyMgmt(mCtx, iconPath); + keyMgmt->hide(); + + /* test attachmentdir for files alll 15s */ + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(checkAttachmentFolder())); + timer->start(5000); + + createActions(); + createMenus(); + createToolBars(); + createStatusBar(); + createDockWindows(); + + mKeyList->addMenuAction(appendSelectedKeysAct); + mKeyList->addMenuAction(copyMailAddressToClipboardAct); + mKeyList->addMenuAction(showKeyDetailsAct); + + restoreSettings(); + + // open filename if provided as first command line parameter + QStringList args = qApp->arguments(); + if (args.size() > 1) { + if (!args[1].startsWith("-")) { + if (QFile::exists(args[1])) + edit->loadFile(args[1]); + } + } + edit->curTextPage()->setFocus(); + this->setWindowTitle(qApp->applicationName()); +} + +void MainWindow::restoreSettings() +{ + // state sets pos & size of dock-widgets + this->restoreState(settings.value("window/windowState").toByteArray()); + + // Restore window size & location + if (settings.value("window/windowSave").toBool()) { + QPoint pos = settings.value("window/pos", QPoint(100, 100)).toPoint(); + QSize size = settings.value("window/size", QSize(800, 450)).toSize(); + this->resize(size); + this->move(pos); + } else { + this->resize(QSize(800, 450)); + this->move(QPoint(100, 100)); + } + + // Iconsize + QSize iconSize = settings.value("toolbar/iconsize", QSize(32, 32)).toSize(); + this->setIconSize(iconSize); + + // set list of keyserver if not defined + QStringList *keyServerDefaultList; + keyServerDefaultList = new QStringList("http://gpg-keyserver.de"); + keyServerDefaultList->append("http://pgp.mit.edu"); + keyServerDefaultList->append("http://pool.sks-keyservers.net"); + keyServerDefaultList->append("http://subkeys.pgp.net"); + + QStringList keyServerList = settings.value("keyserver/keyServerList", *keyServerDefaultList).toStringList(); + settings.setValue("keyserver/keyServerList", keyServerList); + + // set default keyserver, if it's not set + QString defaultKeyServer = settings.value("keyserver/defaultKeyServer", QString("http://pgp.mit.edu")).toString(); + settings.setValue("keyserver/defaultKeyServer", defaultKeyServer); + + // Iconstyle + Qt::ToolButtonStyle buttonStyle = static_cast(settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon).toUInt()); + this->setToolButtonStyle(buttonStyle); + + // Checked Keys + if (settings.value("keys/keySave").toBool()) { + QStringList keyIds = settings.value("keys/keyList").toStringList(); + mKeyList->setChecked(&keyIds); + } +} + +void MainWindow::saveSettings() +{ + // window position and size + settings.setValue("window/windowState", saveState()); + settings.setValue("window/pos", pos()); + settings.setValue("window/size", size()); + + // keyid-list of private checked keys + if (settings.value("keys/keySave").toBool()) { + QStringList *keyIds = mKeyList->getPrivateChecked(); + if (!keyIds->isEmpty()) { + settings.setValue("keys/keyList", *keyIds); + } else { + settings.setValue("keys/keyList", ""); + } + } else { + settings.remove("keys/keyList"); + } +} + +void MainWindow::createActions() +{ + /* Main Menu + */ + newTabAct = new QAction(tr("&New"), this); + QList newTabActShortcutList; + newTabActShortcutList.append(QKeySequence (Qt::CTRL + Qt::Key_N)); + newTabActShortcutList.append(QKeySequence (Qt::CTRL + Qt::Key_T)); + newTabAct->setShortcuts(newTabActShortcutList); + + newTabAct->setToolTip(tr("Open a new file")); + connect(newTabAct, SIGNAL(triggered()), edit, SLOT(newTab())); + + openAct = new QAction(tr("&Open..."), this); + openAct->setIcon(QIcon(iconPath + "fileopen.png")); + openAct->setShortcut(QKeySequence::Open); + openAct->setToolTip(tr("Open an existing file")); + connect(openAct, SIGNAL(triggered()), edit, SLOT(open())); + + saveAct = new QAction(tr("&Save"), this); + saveAct->setIcon(QIcon(iconPath + "filesave.png")); + saveAct->setShortcut(QKeySequence::Save); + saveAct->setToolTip(tr("Save the current File")); + connect(saveAct, SIGNAL(triggered()), edit, SLOT(save())); + + saveAsAct = new QAction(tr("Save &As")+"...", this); + saveAsAct->setIcon(QIcon(iconPath + "filesaveas.png")); + saveAsAct->setShortcut(QKeySequence::SaveAs); + saveAsAct->setToolTip(tr("Save the current File as...")); + connect(saveAsAct, SIGNAL(triggered()), edit, SLOT(saveAs())); + + printAct = new QAction(tr("&Print"), this); + printAct->setIcon(QIcon(iconPath + "fileprint.png")); + printAct->setShortcut(QKeySequence::Print); + printAct->setToolTip(tr("Print Document")); + connect(printAct, SIGNAL(triggered()), edit, SLOT(print())); + + closeTabAct = new QAction(tr("&Close"), this); + closeTabAct->setShortcut(QKeySequence::Close); + closeTabAct->setToolTip(tr("Close file")); + connect(closeTabAct, SIGNAL(triggered()), edit, SLOT(closeTab())); + + quitAct = new QAction(tr("&Quit"), this); + quitAct->setShortcut(QKeySequence::Quit); + quitAct->setIcon(QIcon(iconPath + "exit.png")); + quitAct->setToolTip(tr("Quit Program")); + connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); + + /* Edit Menu + */ + undoAct = new QAction(tr("&Undo"), this); + undoAct->setShortcut(QKeySequence::Undo); + undoAct->setToolTip(tr("Undo Last Edit Action")); + connect(undoAct, SIGNAL(triggered()), edit, SLOT(undo())); + + redoAct = new QAction(tr("&Redo"), this); + redoAct->setShortcut(QKeySequence::Redo); + redoAct->setToolTip(tr("Redo Last Edit Action")); + connect(redoAct, SIGNAL(triggered()), edit, SLOT(redo())); + + pasteAct = new QAction(tr("&Paste"), this); + pasteAct->setIcon(QIcon(iconPath + "button_paste.png")); + pasteAct->setShortcut(QKeySequence::Paste); + pasteAct->setToolTip(tr("Paste Text From Clipboard")); + connect(pasteAct, SIGNAL(triggered()), edit, SLOT(paste())); + + cutAct = new QAction(tr("Cu&t"), this); + cutAct->setIcon(QIcon(iconPath + "button_cut.png")); + cutAct->setShortcut(QKeySequence::Cut); + cutAct->setToolTip(tr("Cut the current selection's contents to the " + "clipboard")); + connect(cutAct, SIGNAL(triggered()), edit, SLOT(cut())); + + copyAct = new QAction(tr("&Copy"), this); + copyAct->setIcon(QIcon(iconPath + "button_copy.png")); + copyAct->setShortcut(QKeySequence::Copy); + copyAct->setToolTip(tr("Copy the current selection's contents to the " + "clipboard")); + connect(copyAct, SIGNAL(triggered()), edit, SLOT(copy())); + + quoteAct = new QAction(tr("&Quote"), this); + quoteAct->setIcon(QIcon(iconPath + "quote.png")); + quoteAct->setToolTip(tr("Quote whole text")); + connect(quoteAct, SIGNAL(triggered()), edit, SLOT(quote())); + + selectallAct = new QAction(tr("Select &All"), this); + selectallAct->setIcon(QIcon(iconPath + "edit.png")); + selectallAct->setShortcut(QKeySequence::SelectAll); + selectallAct->setToolTip(tr("Select the whole text")); + connect(selectallAct, SIGNAL(triggered()), edit, SLOT(selectAll())); + + cleanDoubleLinebreaksAct = new QAction(tr("Remove double &Linebreaks"), this); + //cleanDoubleLineBreaksAct->setIcon(QIcon(iconPath + "edit.png")); + //cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll); + cleanDoubleLinebreaksAct->setToolTip(tr("Remove double linebreaks, e.g. in pasted text from webmailer")); + connect(cleanDoubleLinebreaksAct, SIGNAL(triggered()), this, SLOT(cleanDoubleLinebreaks())); + + openSettingsAct = new QAction(tr("Se&ttings"), this); + openSettingsAct->setToolTip(tr("Open settings dialog")); + openSettingsAct->setShortcut(QKeySequence::Preferences); + connect(openSettingsAct, SIGNAL(triggered()), this, SLOT(openSettingsDialog())); + + /* Crypt Menu + */ + encryptAct = new QAction(tr("&Encrypt"), this); + encryptAct->setIcon(QIcon(iconPath + "encrypted.png")); + encryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); + encryptAct->setToolTip(tr("Encrypt Message")); + connect(encryptAct, SIGNAL(triggered()), this, SLOT(encrypt())); + + decryptAct = new QAction(tr("&Decrypt"), this); + decryptAct->setIcon(QIcon(iconPath + "decrypted.png")); + decryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); + decryptAct->setToolTip(tr("Decrypt Message")); + connect(decryptAct, SIGNAL(triggered()), this, SLOT(decrypt())); + + fileEncryptionAct = new QAction(tr("&File Encryption"), this); + fileEncryptionAct->setIcon(QIcon(iconPath + "fileencrytion.png")); + fileEncryptionAct->setToolTip(tr("Encrypt/Decrypt File")); + connect(fileEncryptionAct, SIGNAL(triggered()), this, SLOT(fileEncryption())); + + signAct = new QAction(tr("&Sign"), this); + signAct->setIcon(QIcon(iconPath + "signature.png")); + signAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I)); + signAct->setToolTip(tr("Sign Message")); + connect(signAct, SIGNAL(triggered()), this, SLOT(sign())); + + verifyAct = new QAction(tr("&Verify"), this); + verifyAct->setIcon(QIcon(iconPath + "verify.png")); + verifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V)); + verifyAct->setToolTip(tr("Verify Message")); + connect(verifyAct, SIGNAL(triggered()), this, SLOT(verify())); + + /* Key Menu + */ + + importKeyFromEditAct = new QAction(tr("&Editor"), this); + importKeyFromEditAct->setIcon(QIcon(iconPath + "txt.png")); + importKeyFromEditAct->setToolTip(tr("Import New Key From Editor")); + connect(importKeyFromEditAct, SIGNAL(triggered()), this, SLOT(importKeyFromEdit())); + + openKeyManagementAct = new QAction(tr("Key Management"), this); + openKeyManagementAct->setIcon(QIcon(iconPath + "keymgmt.png")); + openKeyManagementAct->setToolTip(tr("Open Keymanagement")); + connect(openKeyManagementAct, SIGNAL(triggered()), this, SLOT(openKeyManagement())); + + importKeyDialogAct = new QAction(tr("Import Key"), this); + importKeyDialogAct->setIcon(QIcon(iconPath + "key_import.png")); + importKeyDialogAct->setToolTip(tr("Open Import New Key Dialog")); + connect(importKeyDialogAct, SIGNAL(triggered()), this, SLOT(importKeyDialog())); + + /* About Menu + */ + aboutAct = new QAction(tr("&About"), this); + aboutAct->setIcon(QIcon(iconPath + "help.png")); + aboutAct->setToolTip(tr("Show the application's About box")); + connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); + + openTutorialAct = new QAction(tr("Online &Tutorial"), this); + openTutorialAct->setIcon(QIcon(iconPath + "help.png")); + openTutorialAct->setToolTip(tr("Open Online Tutorial")); + connect(openTutorialAct, SIGNAL(triggered()), this, SLOT(openTutorial())); + + openTranslateAct = new QAction(tr("Translate gpg4usb"), this); + openTranslateAct->setToolTip(tr("Translate gpg4usb yourself")); + connect(openTranslateAct, SIGNAL(triggered()), this, SLOT(openTranslate())); + + /* Popup-Menu-Action for KeyList + */ + appendSelectedKeysAct = new QAction(tr("Append Selected Key(s) To Text"), this); + appendSelectedKeysAct->setToolTip(tr("Append The Selected Keys To Text in Editor")); + connect(appendSelectedKeysAct, SIGNAL(triggered()), this, SLOT(appendSelectedKeys())); + + copyMailAddressToClipboardAct = new QAction(tr("Copy EMail-address"), this); + copyMailAddressToClipboardAct->setToolTip(tr("Copy selected EMailaddress to clipboard")); + connect(copyMailAddressToClipboardAct, SIGNAL(triggered()), this, SLOT(copyMailAddressToClipboard())); + + // TODO: find central place for shared actions, to avoid code-duplication with keymgmt.cpp + showKeyDetailsAct = new QAction(tr("Show Keydetails"), this); + showKeyDetailsAct->setToolTip(tr("Show Details for this Key")); + connect(showKeyDetailsAct, SIGNAL(triggered()), this, SLOT(showKeyDetails())); + + /* Key-Shortcuts for Tab-Switchung-Action + */ + switchTabUpAct = new QAction(this); + switchTabUpAct->setShortcut(QKeySequence::NextChild); + connect(switchTabUpAct, SIGNAL(triggered()), edit, SLOT(switchTabUp())); + this->addAction(switchTabUpAct); + + switchTabDownAct = new QAction(this); + switchTabDownAct->setShortcut(QKeySequence::PreviousChild); + connect(switchTabDownAct, SIGNAL(triggered()), edit, SLOT(switchTabDown())); + this->addAction(switchTabDownAct); +} + +void MainWindow::createMenus() +{ + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(newTabAct); + fileMenu->addAction(openAct); + fileMenu->addSeparator(); + fileMenu->addAction(saveAct); + fileMenu->addAction(saveAsAct); + fileMenu->addSeparator(); + fileMenu->addAction(printAct); + fileMenu->addSeparator(); + fileMenu->addAction(closeTabAct); + fileMenu->addAction(quitAct); + + editMenu = menuBar()->addMenu(tr("&Edit")); + editMenu->addAction(undoAct); + editMenu->addAction(redoAct); + editMenu->addSeparator(); + editMenu->addAction(copyAct); + editMenu->addAction(cutAct); + editMenu->addAction(pasteAct); + editMenu->addAction(selectallAct); + editMenu->addAction(quoteAct); + editMenu->addAction(cleanDoubleLinebreaksAct); + editMenu->addSeparator(); + editMenu->addAction(openSettingsAct); + + cryptMenu = menuBar()->addMenu(tr("&Crypt")); + cryptMenu->addAction(encryptAct); + cryptMenu->addAction(decryptAct); + cryptMenu->addSeparator(); + cryptMenu->addAction(signAct); + cryptMenu->addAction(verifyAct); + cryptMenu->addSeparator(); + cryptMenu->addAction(fileEncryptionAct); + + keyMenu = menuBar()->addMenu(tr("&Keys")); + importKeyMenu = keyMenu->addMenu(tr("&Import Key From...")); + importKeyMenu->setIcon(QIcon(iconPath + "key_import.png")); + importKeyMenu->addAction(keyMgmt->importKeyFromFileAct); + importKeyMenu->addAction(importKeyFromEditAct); + importKeyMenu->addAction(keyMgmt->importKeyFromClipboardAct); + importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); + importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); + keyMenu->addAction(openKeyManagementAct); + + viewMenu = menuBar()->addMenu(tr("&View")); + + helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(openTutorialAct); + helpMenu->addAction(openTranslateAct); + helpMenu->addAction(aboutAct); +} + +void MainWindow::createToolBars() +{ + cryptToolBar = addToolBar(tr("Crypt")); + cryptToolBar->setObjectName("cryptToolBar"); + cryptToolBar->addAction(encryptAct); + cryptToolBar->addAction(decryptAct); + cryptToolBar->addAction(signAct); + cryptToolBar->addAction(verifyAct); + cryptToolBar->addAction(fileEncryptionAct); + viewMenu->addAction(cryptToolBar->toggleViewAction()); + + keyToolBar = addToolBar(tr("Key")); + keyToolBar->setObjectName("keyToolBar"); + keyToolBar->addAction(importKeyDialogAct); + keyToolBar->addAction(openKeyManagementAct); + viewMenu->addAction(keyToolBar->toggleViewAction()); + + editToolBar = addToolBar(tr("Edit")); + editToolBar->setObjectName("editToolBar"); + editToolBar->addAction(copyAct); + editToolBar->addAction(pasteAct); + editToolBar->addAction(selectallAct); + editToolBar->addAction(quoteAct); + viewMenu->addAction(editToolBar->toggleViewAction()); +} + +void MainWindow::createStatusBar() +{ + QWidget *statusBarBox = new QWidget(); + QHBoxLayout *statusBarBoxLayout = new QHBoxLayout(); + QPixmap *pixmap; + + // icon which should be shown if there are files in attachments-folder + pixmap = new QPixmap(iconPath + "statusbar_icon.png"); + statusBarIcon = new QLabel(statusBar()); + statusBarIcon->setPixmap(*pixmap); + statusBar()->insertPermanentWidget(0,statusBarIcon,0); + statusBarIcon->hide(); + statusBar()->showMessage(tr("Ready"),2000); + statusBarBox->setLayout(statusBarBoxLayout); +} + +void MainWindow::createDockWindows() +{ + /* KeyList-Dockwindow + */ + keylistDock = new QDockWidget(tr("Encrypt for:"), this); + keylistDock->setObjectName("EncryptDock"); + keylistDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + addDockWidget(Qt::RightDockWidgetArea, keylistDock); + keylistDock->setWidget(mKeyList); + viewMenu->addAction(keylistDock->toggleViewAction()); + + /* Attachments-Dockwindow + */ + if(settings.value("mime/parseMime").toBool()) { + createAttachmentDock(); + } +} + +void MainWindow::createAttachmentDock() { + if (attachmentDockCreated) { + return; + } + mAttachments = new Attachments(iconPath); + attachmentDock = new QDockWidget(tr("Attached files:"), this); + attachmentDock->setObjectName("AttachmentDock"); + attachmentDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); + addDockWidget(Qt::BottomDockWidgetArea, attachmentDock); + attachmentDock->setWidget(mAttachments); + // hide till attachment is decrypted + viewMenu->addAction(attachmentDock->toggleViewAction()); + attachmentDock->hide(); + attachmentDockCreated = true; +} + +void MainWindow::closeAttachmentDock() { + if (!attachmentDockCreated) { + return; + } + attachmentDock->close(); + attachmentDock->deleteLater(); + attachmentDockCreated = false; +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + /* + * ask to save changes, if there are + * modified documents in any tab + */ + if (edit->maybeSaveAnyTab()) { + saveSettings(); + event->accept(); + } else { + event->ignore(); + } + + // clear password from memory + mCtx->clearPasswordCache(); +} + +void MainWindow::about() +{ + QPixmap *pixmap = new QPixmap(iconPath + "gpg4usb-logo.png"); + QString *title = new QString(tr("About ") + qApp->applicationName()); + QString *text = new QString("

" + qApp->applicationName() + " " + + qApp->applicationVersion() + "

" + + tr("
This application allows simple encryption
" + "and decryption of text messages or files.
" + "It's licensed under the GPL v3

" + "Developer:
" + "Bene, Heimer, Juergen, Nils, Ubbo

" + "Translation:
" + "Alessandro (pt_br), Kirill (ru), Viriato (es), Serse (it)

" + "If you have any questions or suggestions have a look
" + "at our " + "contact page or send a mail to our
mailing list at" + " gpg4usb@gzehn.de.")); + + QDialog *dialog = new QDialog(this); + dialog->setWindowTitle(*title); + QPushButton *closeButton = new QPushButton(tr("&Close")); + connect(closeButton, SIGNAL(clicked()), dialog, SLOT(close())); + + QGridLayout *layout = new QGridLayout(dialog); + QLabel *pixmapLabel = new QLabel(); + pixmapLabel->setPixmap(*pixmap); + layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); + QLabel *aboutLabel = new QLabel(); + aboutLabel->setText(*text); + aboutLabel->setOpenExternalLinks(true); + layout->addWidget(aboutLabel, 1, 0, 1, -1); + layout->addItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, + QSizePolicy::Fixed), 2, 1, 1, 1); + layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 0, 1, 1); + layout->addWidget(closeButton, 3, 1, 1, 1); + layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 2, 1, 1); + + dialog->exec(); +} + +void MainWindow::openTranslate() { + QDesktopServices::openUrl(QUrl("http://gpg4usb.cpunk.de/docu_translate.html")); +} + +void MainWindow::openTutorial() { + QDesktopServices::openUrl(QUrl("http://gpg4usb.cpunk.de/docu.html")); +} + +/* + * if this is mime, split text and attachments... + * message contains only text afterwards + */ +void MainWindow::parseMime(QByteArray *message) +{ + /*if (! Mime::isMultipart(message)) { + qDebug() << "no multipart"; + return; + }*/ + //qDebug() << "multipart"; + + QString pText; + bool showmadock = false; + + Mime *mime = new Mime(message); + foreach(MimePart tmp, mime->parts()) { + if (tmp.header.getValue("Content-Type") == "text/plain" + && tmp.header.getValue("Content-Transfer-Encoding") != "base64") { + + QByteArray body; + if (tmp.header.getValue("Content-Transfer-Encoding") == "quoted-printable") { + Mime::quotedPrintableDecode(tmp.body, body); + } else { + body = tmp.body; + } + pText.append(QString(body)); + } else { + (mAttachments->addMimePart(&tmp)); + showmadock = true; + } + } + *message = pText.toUtf8(); + if (showmadock) { + attachmentDock->show(); + } +} + +void MainWindow::checkAttachmentFolder() { + // TODO: always check? + if(!settings.value("mime/parseMime").toBool()) { + return; + } + + QString attachmentDir = qApp->applicationDirPath() + "/attachments/"; + // filenum minus . and .. + int filenum = QDir(attachmentDir).count() - 2 ; + if(filenum > 0) { + QString statusText; + if(filenum == 1) { + statusText = tr("There is one unencrypted file in attachment folder"); + } else { + statusText = tr("There are ") + QString::number(filenum) + tr(" unencrypted files in attachment folder"); + } + statusBarIcon->setStatusTip(statusText); + statusBarIcon->show(); + } else { + statusBarIcon->hide(); + } +} + +void MainWindow::importKeyFromEdit() +{ + mCtx->importKey(edit->curTextPage()->toPlainText().toAscii()); +} + +void MainWindow::openKeyManagement() +{ + keyMgmt->show(); + keyMgmt->raise(); + keyMgmt->activateWindow(); +} + +void MainWindow::encrypt() +{ + QStringList *uidList = mKeyList->getChecked(); + + QByteArray *tmp = new QByteArray(); + if (mCtx->encrypt(uidList, edit->curTextPage()->toPlainText().toUtf8(), tmp)) { + QString *tmp2 = new QString(*tmp); + edit->fillTextEditWithText(*tmp2); + } +} + +void MainWindow::sign() +{ + QStringList *uidList = mKeyList->getPrivateChecked(); + + QByteArray *tmp = new QByteArray(); + // TODO: toUtf8() here? + if (mCtx->sign(uidList, edit->curTextPage()->toPlainText().toAscii(), tmp)) { + QString *tmp2 = new QString(*tmp); + edit->fillTextEditWithText(*tmp2); + } +} + +void MainWindow::decrypt() +{ + QByteArray *decrypted = new QByteArray(); + QByteArray text = edit->curTextPage()->toPlainText().toAscii(); // TODO: toUtf8() here? + mCtx->preventNoDataErr(&text); + + // try decrypt, if fail do nothing, especially don't replace text + if(!mCtx->decrypt(text, decrypted)) { + return; + } + + /* + * 1) is it mime (content-type:) + * 2) parse header + * 2) choose action depending on content-type + */ + if(Mime::isMime(decrypted)) { + Header header = Mime::getHeader(decrypted); + // is it multipart, is multipart-parsing enabled + if(header.getValue("Content-Type") == "multipart/mixed" + && settings.value("mime/parseMime").toBool()) { + parseMime(decrypted); + } else if(header.getValue("Content-Type") == "text/plain" + && settings.value("mime/parseQP").toBool()){ + if (header.getValue("Content-Transfer-Encoding") == "quoted-printable") { + QByteArray *decoded = new QByteArray(); + Mime::quotedPrintableDecode(*decrypted, *decoded); + //TODO: remove header + decrypted = decoded; + } + } + } + edit->fillTextEditWithText(QString::fromUtf8(*decrypted)); +} + +void MainWindow::verify() +{ + // At first close verifynotification, if existing + edit->curPage()->closeNoteByClass("verifyNotification"); + + // create new verfiy notification + VerifyNotification *vn = new VerifyNotification(this, mCtx, mKeyList, edit->curTextPage()); + + // if signing information is found, show the notification, otherwise close it + if (vn->refresh()) { + edit->curPage()->showNotificationWidget(vn, "verifyNotification"); + } else { + vn->close(); + } +} + +void MainWindow::importKeyDialog() +{ + QDialog *dialog = new QDialog(); + + dialog->setWindowTitle(tr("Import Key")); + dialog->setModal(true); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); + + QGroupBox *groupBox = new QGroupBox(tr("Import Key From...")); + QRadioButton *radio1 = new QRadioButton(tr("&File")); + QRadioButton *radio2 = new QRadioButton(tr("&Editor")); + QRadioButton *radio3 = new QRadioButton(tr("&Clipboard")); + QRadioButton *radio4 = new QRadioButton(tr("&Keyserver")); + radio1->setChecked(true); + + QVBoxLayout *vbox1 = new QVBoxLayout(); + vbox1->addWidget(radio1); + vbox1->addWidget(radio2); + vbox1->addWidget(radio3); + vbox1->addWidget(radio4); + groupBox->setLayout(vbox1); + + QVBoxLayout *vbox2 = new QVBoxLayout(); + vbox2->addWidget(groupBox); + vbox2->addWidget(buttonBox); + dialog->setLayout(vbox2); + + if (dialog->exec() == QDialog::Accepted) { + if (radio1->isChecked()) keyMgmt->importKeyFromFile(); + if (radio2->isChecked()) importKeyFromEdit(); + if (radio3->isChecked()) keyMgmt->importKeyFromClipboard(); + if (radio4->isChecked()) keyMgmt->importKeyFromKeyServer(); + } +} + +/* + * Append the selected (not checked!) Key(s) To Textedit + */ +void MainWindow::appendSelectedKeys() +{ + QByteArray *keyArray = new QByteArray(); + mCtx->exportKeys(mKeyList->getSelected(), keyArray); + edit->curTextPage()->appendPlainText(*keyArray); +} + +void MainWindow::copyMailAddressToClipboard() +{ + gpgme_key_t key = mCtx->getKeyDetails(mKeyList->getSelected()->first()); + QClipboard *cb = QApplication::clipboard(); + QString mail = key->uids->email; + cb->setText(mail); +} + +void MainWindow::showKeyDetails() +{ + // TODO: first...? + gpgme_key_t key = mCtx->getKeyDetails(mKeyList->getSelected()->first()); + new KeyDetailsDialog(mCtx, key, this); +} + +void MainWindow::fileEncryption() +{ + QStringList *keyList; + keyList = mKeyList->getChecked(); + new FileEncryptionDialog(mCtx, iconPath, *keyList, this); +} + +void MainWindow::openSettingsDialog() +{ + new SettingsDialog(this); + // Iconsize + QSize iconSize = settings.value("toolbar/iconsize", QSize(32, 32)).toSize(); + this->setIconSize(iconSize); + + // Iconstyle + Qt::ToolButtonStyle buttonStyle = static_cast(settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon).toUInt()); + this->setToolButtonStyle(buttonStyle); + + if(settings.value("mime/parseMime").toBool()) { + createAttachmentDock(); + } else if(attachmentDockCreated) { + closeAttachmentDock(); + } + +} + +void MainWindow::cleanDoubleLinebreaks() +{ + QString content = edit->curTextPage()->toPlainText(); + content.replace("\n\n", "\n"); + edit->fillTextEditWithText(content); +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..4aabfd4 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,294 @@ +/* + * gpgwin.h + * + * Copyright 2008 gpg4usb-team + * + * This file is part of gpg4usb. + * + * Gpg4usb 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 3 of the License, or + * (at your option) any later version. + * + * Gpg4usb 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 gpg4usb. If not, see + */ + +#ifndef __GPGWIN_H__ +#define __GPGWIN_H__ + +#include "attachments.h" +#include "keymgmt.h" +#include "textedit.h" +#include "fileencryptiondialog.h" +#include "settingsdialog.h" +#include "verifynotification.h" + +QT_BEGIN_NAMESPACE +class QMainWindow; +class QPlainTextEdit; +class QWidget; +class QVBoxLayout; +class QGridLayout; +class iostream; +class QtGui; +class QString; +class QFileDialog; +class QStringList; +class QIcon; +class QMessageBox; +class QVBoxLayout; +class QAction; +class QMenu; +class QPlainTextEdit; +class QComboBox; +class QPushButton; +class QRadioButton; +class QButtonGroup; +class QApplication; +class QDockWidget; +QT_END_NAMESPACE + + +/** + * @brief + * + */ +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + /** + * @brief + * + */ + MainWindow(); + +protected: + /** + * @details Close event shows a save dialog, if there are unsaved documents on exit. + * @param event + */ + void closeEvent(QCloseEvent *event); + +private slots: + /** + * @details encrypt the text of currently active textedit-page + * with the currently checked keys + */ + void encrypt(); + + /** + * @details Show a passphrase dialog and decrypt the text of currently active tab. + */ + void decrypt(); + + /** + * @details Sign the text of currently active tab with the checked private keys + */ + void sign(); + + /** + * @details Verify the text of currently active tab and show verify information. + * If document is signed with a key, which is not in keylist, show import missing + * key from keyserver in Menu of verifynotification. + */ + void verify(); + + void showKeyDetails(); + + /** + * @details Import keys from currently active tab to keylist if possible. + */ + void importKeyFromEdit(); + + /** + * @details Open a dialog, in which you can choose, where keys should be imported from. + */ + void importKeyDialog(); + + /** + * @details Append the selected keys to currently active textedit. + */ + void appendSelectedKeys(); + + /** + * @details Copy the mailaddress of selected key to clipboard. + * Method for keylists contextmenu. + */ + void copyMailAddressToClipboard(); + + /** + * @details Open key management dialog. + */ + void openKeyManagement(); + + /** + * @details Open about-dialog. + */ + void about(); + + /** + * @details Open fileencrytion dialog. + */ + void fileEncryption(); + + /** + * @details Open settings-dialog. + */ + void openSettingsDialog(); + + /** + * @details Open online-tutorial in default browser. + */ + void openTutorial(); + + /** + * @details Show a warn message in status bar, if there are files in attachment folder. + */ + void checkAttachmentFolder(); + + /** + * @details Open online translation tutorial in default browser. + */ + void openTranslate(); + + /** + * @details Replace double linebreaks by single linebreaks in currently active tab. + */ + void cleanDoubleLinebreaks(); +// void dropEvent(QDropEvent *event); + +private: + /** + * @details Create actions for the main-menu and the context-menu of the keylist. + */ + void createActions(); + + /** + * @details create the menu of the main-window. + */ + void createMenus(); + + /** + * @details Create edit-, crypt- and key-toolbars. + */ + void createToolBars(); + + /** + * @details Create statusbar of mainwindow. + */ + void createStatusBar(); + + /** + * @details Create keylist- and attachment-dockwindows. + */ + void createDockWindows(); + + /** + * @details Create attachment-dockwindow. + */ + void createAttachmentDock(); + + /** + * @details close attachment-dockwindow. + */ + void closeAttachmentDock(); + + /** + * @details Load settings from ini-file. + */ + void restoreSettings(); + + /** + * @details Save settings to ini-file. + */ + void saveSettings(); + + /** + * @brief + * + * @param message + */ + void parseMime(QByteArray *message); + + TextEdit *edit; /** Tabwidget holding the edit-windows */ + QMenu *fileMenu; /** Submenu for file-operations*/ + QMenu *editMenu; /** Submenu for text-operations*/ + QMenu *cryptMenu; /** Submenu for crypt-operations */ + QMenu *helpMenu; /** Submenu for help-operations */ + QMenu *keyMenu; /** Submenu for key-operations */ + QMenu *viewMenu; /** View submenu */ + QMenu *importKeyMenu; /** Sumenu for import operations */ + QToolBar *cryptToolBar; /** Toolbar holding crypt actions */ + QToolBar *editToolBar; /** Toolbar holding edit actions */ + QToolBar *keyToolBar; /** Toolbar holding key operations */ + QDockWidget *keylistDock; /** Encrypt Dock*/ + QDockWidget *attachmentDock; /** Attachment Dock */ + QDialog *genkeyDialog; /** Dialog for key generation */ + + QAction *newTabAct; /** Action to create new tab */ + QAction *switchTabUpAct; /** Action to switch tab up*/ + QAction *switchTabDownAct; /** Action to switch tab down */ + QAction *openAct; /** Action to open file */ + QAction *saveAct; /** Action to save file */ + QAction *saveAsAct; /** Action to save file as */ + QAction *printAct; /** Action to print */ + QAction *closeTabAct; /** Action to print */ + QAction *quitAct; /** Action to quit application */ + QAction *encryptAct; /** Action to encrypt text */ + QAction *decryptAct; /** Action to decrypt text */ + QAction *signAct; /** Action to sign text */ + QAction *verifyAct; /** Action to verify text */ + QAction *importKeyDialogAct; /** Action to open key dialog */ + QAction *importKeyFromEditAct; /** Action to import key from edit */ + QAction *cleanDoubleLinebreaksAct; /** Action to remove double line breaks */ + + QAction *appendSelectedKeysAct; /** Action to append selected keys to edit */ + QAction *copyMailAddressToClipboardAct; /** Action to copy mail to clipboard */ + QAction *openKeyManagementAct; /** Action to open key management */ + QAction *copyAct; /** Action to copy text */ + QAction *quoteAct; /** Action to quote text */ + QAction *cutAct; /** Action to cut text */ + QAction *pasteAct; /** Action to paste text */ + QAction *selectallAct; /** Action to select whole text */ + QAction *undoAct; /** Action to undo last action */ + QAction *redoAct; /** Action to redo last action */ + QAction *aboutAct; /** Action to open about dialog */ + QAction *fileEncryptionAct; /** Action to open file-encryption dialog */ + QAction *openSettingsAct; /** Action to open settings dialog */ + QAction *openTranslateAct; /** Action to open translate doc*/ + QAction *openTutorialAct; /** Action to open tutorial */ + QAction *showKeyDetailsAct; /** Action to open key-details dialog */ + QLineEdit *nameEdit; /**< TODO */ + QLineEdit *emailEdit; /**< TODO */ + QLineEdit *commentEdit; /**< TODO */ + QLineEdit *passwordEdit; /**< TODO */ + QLineEdit *repeatpwEdit; /**< TODO */ + QSpinBox *keysizeSpinBox; /**< TODO */ + QLabel *nameLabel; /**< TODO */ + QLabel *emailLabel; /**< TODO */ + QLabel *commentLabel; /**< TODO */ + QLabel *keysizeLabel; /**< TODO */ + QLabel *passwordLabel; /**< TODO */ + QLabel *repeatpwLabel; /**< TODO */ + QLabel *errorLabel; /**< TODO */ + QLabel *statusBarIcon; /**< TODO */ + + QSettings settings; /**< TODO */ + KeyList *mKeyList; /**< TODO */ + Attachments *mAttachments; /**< TODO */ + GpgME::GpgContext *mCtx; /**< TODO */ + QString iconPath; /**< TODO */ + KeyMgmt *keyMgmt; /**< TODO */ + KeyServerImportDialog *importDialog; /**< TODO */ + bool attachmentDockCreated; +}; + +#endif // __GPGWIN_H__ diff --git a/verifydetailsdialog.cpp b/verifydetailsdialog.cpp index 945e928..8f160fb 100644 --- a/verifydetailsdialog.cpp +++ b/verifydetailsdialog.cpp @@ -21,7 +21,7 @@ #include "verifydetailsdialog.h" -VerifyDetailsDialog::VerifyDetailsDialog(QWidget *parent, GpgME::Context* ctx, KeyList* keyList, QPlainTextEdit *edit) : +VerifyDetailsDialog::VerifyDetailsDialog(QWidget *parent, GpgME::GpgContext* ctx, KeyList* keyList, QPlainTextEdit *edit) : QDialog(parent) { mCtx = ctx; diff --git a/verifydetailsdialog.h b/verifydetailsdialog.h index b839695..83519f9 100644 --- a/verifydetailsdialog.h +++ b/verifydetailsdialog.h @@ -30,13 +30,13 @@ class VerifyDetailsDialog : public QDialog { Q_OBJECT public: - explicit VerifyDetailsDialog(QWidget *parent, GpgME::Context* ctx, KeyList* mKeyList, QPlainTextEdit *edit); + explicit VerifyDetailsDialog(QWidget *parent, GpgME::GpgContext* ctx, KeyList* mKeyList, QPlainTextEdit *edit); private slots: void refresh(); private: - GpgME::Context *mCtx; + GpgME::GpgContext *mCtx; KeyList *mKeyList; QHBoxLayout *mainLayout; QVBoxLayout *mVboxLayout; diff --git a/verifykeydetailbox.cpp b/verifykeydetailbox.cpp index f71a88f..3d8d538 100644 --- a/verifykeydetailbox.cpp +++ b/verifykeydetailbox.cpp @@ -21,7 +21,7 @@ #include "verifykeydetailbox.h" -VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget *parent, GpgME::Context* ctx, KeyList* keyList, gpgme_signature_t signature) : +VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget *parent, GpgME::GpgContext* ctx, KeyList* keyList, gpgme_signature_t signature) : QGroupBox(parent) { this->mCtx = ctx; diff --git a/verifykeydetailbox.h b/verifykeydetailbox.h index 82f7987..adfea1c 100644 --- a/verifykeydetailbox.h +++ b/verifykeydetailbox.h @@ -31,13 +31,13 @@ class VerifyKeyDetailBox: public QGroupBox { Q_OBJECT public: - explicit VerifyKeyDetailBox(QWidget *parent, GpgME::Context* ctx, KeyList* mKeyList, gpgme_signature_t signature); + explicit VerifyKeyDetailBox(QWidget *parent, GpgME::GpgContext* ctx, KeyList* mKeyList, gpgme_signature_t signature); private slots: void importFormKeyserver(); private: - GpgME::Context* mCtx; + GpgME::GpgContext* mCtx; KeyList* mKeyList; QString beautifyFingerprint(QString fingerprint); QString fpr; diff --git a/verifynotification.cpp b/verifynotification.cpp index 83d2307..d588007 100644 --- a/verifynotification.cpp +++ b/verifynotification.cpp @@ -21,7 +21,7 @@ #include "verifynotification.h" -VerifyNotification::VerifyNotification(QWidget *parent, GpgME::Context *ctx, KeyList *keyList,QPlainTextEdit *edit) : +VerifyNotification::VerifyNotification(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList,QPlainTextEdit *edit) : QWidget(parent) { mCtx = ctx; diff --git a/verifynotification.h b/verifynotification.h index 11abc95..7da445b 100644 --- a/verifynotification.h +++ b/verifynotification.h @@ -58,7 +58,7 @@ public: * @param ctx The GPGme-Context * @param parent The parent widget */ - explicit VerifyNotification(QWidget *parent, GpgME::Context *ctx, KeyList *keyList,QPlainTextEdit *edit); + explicit VerifyNotification(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList,QPlainTextEdit *edit); /** * @details Set the text and background-color of verify notification. * @@ -99,7 +99,7 @@ private: QAction *showVerifyDetailsAct; /** Action for showing verify detail dialog */ QPushButton *detailsButton; /** Button shown in verifynotification */ QLabel *verifyLabel; /** Label holding the text shown in verifyNotification */ - GpgME::Context *mCtx; /** GpgME Context */ + GpgME::GpgContext *mCtx; /** GpgME Context */ KeyList *mKeyList; /** Table holding the keys */ QPlainTextEdit *mTextpage; /** Textedit associated to the notification */ QHBoxLayout *notificationWidgetLayout; /** Layout for verify-notification */ -- cgit v1.2.3