diff options
author | ubbo <ubbo@34ebc366-c3a9-4b3c-9f84-69acf7962910> | 2012-08-05 22:15:15 +0000 |
---|---|---|
committer | ubbo <ubbo@34ebc366-c3a9-4b3c-9f84-69acf7962910> | 2012-08-05 22:15:15 +0000 |
commit | 6a9338841afd29ff7b2e66b966d48e59287ebec2 (patch) | |
tree | 3e73a6ae5e09faec2186c9e00fa9b83bfa0a8c02 | |
parent | all import functionality should work now, added todo (diff) | |
download | gpg4usb-6a9338841afd29ff7b2e66b966d48e59287ebec2.tar.gz gpg4usb-6a9338841afd29ff7b2e66b966d48e59287ebec2.zip |
signing text works
git-svn-id: http://cpunk.de/svn/src/gpg4usb/branches/0.3.2-mac@942 34ebc366-c3a9-4b3c-9f84-69acf7962910
-rw-r--r-- | TODO.kgpgport | 3 | ||||
-rw-r--r-- | gpg4usb.pro | 8 | ||||
-rw-r--r-- | kgpg/kgpginterface.cpp | 11 | ||||
-rw-r--r-- | kgpg/transactions/kgpgsigntext.cpp | 118 | ||||
-rw-r--r-- | kgpg/transactions/kgpgsigntext.h | 98 | ||||
-rw-r--r-- | kgpg/transactions/kgpgtextorfiletransaction.cpp | 14 | ||||
-rw-r--r-- | kgpg/transactions/kgpgtransaction.cpp | 21 | ||||
-rw-r--r-- | mainwindow.cpp | 48 | ||||
-rw-r--r-- | mainwindow.h | 3 |
9 files changed, 305 insertions, 19 deletions
diff --git a/TODO.kgpgport b/TODO.kgpgport index 2023571..b19fed3 100644 --- a/TODO.kgpgport +++ b/TODO.kgpgport @@ -1,4 +1,5 @@ TODO: - central import, move code duplication from keymgmt, mainwindow and keyserverimport to central place, e.g. keyimportdetaildialog -reactivate keyimportdetaildialog - +- sign should work for more than one secret keyid +- why is listkeys called so often (twice?) diff --git a/gpg4usb.pro b/gpg4usb.pro index 39c979a..5801afd 100644 --- a/gpg4usb.pro +++ b/gpg4usb.pro @@ -41,12 +41,12 @@ HEADERS += attachments.h \ verifykeydetailbox.h \ wizard.h \ helppage.h \ + gpgconstants.h \ kgpg/gpgproc.h \ kgpg/klinebufferedprocess.h \ kgpg/kprocess.h \ kgpg/kprocess_p.h \ kgpg/kgpginterface.h \ - gpgconstants.h \ kgpg/core/kgpgkey.h \ kgpg/core/KGpgSignableNode.h \ kgpg/core/KGpgExpandableNode.h \ @@ -70,7 +70,8 @@ HEADERS += attachments.h \ kgpg/transactions/kgpgexport.h \ kgpg/transactions/kgpgimport.h \ kgpg/transactions/kgpgdelkey.h \ - kgpg/transactions/kgpggeneratekey.h + kgpg/transactions/kgpggeneratekey.h \ + kgpg/transactions/kgpgsigntext.h SOURCES += attachments.cpp \ @@ -124,7 +125,8 @@ SOURCES += attachments.cpp \ kgpg/transactions/kgpgexport.cpp \ kgpg/transactions/kgpgimport.cpp \ kgpg/transactions/kgpgdelkey.cpp \ - kgpg/transactions/kgpggeneratekey.cpp + kgpg/transactions/kgpggeneratekey.cpp \ + kgpg/transactions/kgpgsigntext.cpp RC_FILE = gpg4usb.rc diff --git a/kgpg/kgpginterface.cpp b/kgpg/kgpginterface.cpp index a907fe3..8632897 100644 --- a/kgpg/kgpginterface.cpp +++ b/kgpg/kgpginterface.cpp @@ -146,10 +146,12 @@ void KgpgInterface::setGpgBoolSetting(const QString &name, const bool enable, co int KgpgInterface::sendPassphrase(const QString &text, KProcess *process, QWidget *widget) { + qDebug() << "KgpgInterface::sendPassphrase called"; + QPointer<KProcess> gpgprocess = process; QByteArray passphrase; //int code; - bool result; + bool ok; /*QPointer<KPasswordDialog> dlg = new KPasswordDialog(widget); QObject::connect(process, SIGNAL(processExited()), dlg->button(KDialog::Cancel), SLOT(click())); @@ -166,12 +168,15 @@ int KgpgInterface::sendPassphrase(const QString &text, KProcess *process, QWidge QString password = QInputDialog::getText(QApplication::activeWindow(), QObject::tr("Enter Password"), text, QLineEdit::Password, - "", &result); + "", &ok); + + if(!ok) return 1; passphrase = password.toAscii(); - if (!gpgprocess.isNull()) + if (!gpgprocess.isNull()) { gpgprocess->write(passphrase + '\n'); + } return 0; } diff --git a/kgpg/transactions/kgpgsigntext.cpp b/kgpg/transactions/kgpgsigntext.cpp new file mode 100644 index 0000000..c971214 --- /dev/null +++ b/kgpg/transactions/kgpgsigntext.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2012 Rolf Eike Beer <[email protected]> + */ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kgpgsigntext.h" +#include <QDebug> +#include "../gpgproc.h" + +//#include "kgpgsettings.h" + +KGpgSignText::KGpgSignText(QObject *parent, const QString &signId, const QString &text, const SignOptions &options, const QStringList &extraOptions) + : KGpgTextOrFileTransaction(parent, text), + m_fileIndex(-1), + m_options(options), + m_signId(signId), + m_extraOptions(extraOptions), + m_text(text) +{ +} + +KGpgSignText::KGpgSignText(QObject *parent, const QString &signId, const QList<QUrl> &files, const SignOptions &options, const QStringList &extraOptions) + : KGpgTextOrFileTransaction(parent, files), + m_fileIndex(0), + m_options(options), + m_signId(signId), + m_extraOptions(extraOptions) +{ + /* GnuPG can only handle one file at a time when signing */ + Q_ASSERT(files.count() == 1); +} + +KGpgSignText::~KGpgSignText() +{ +} + +QStringList +KGpgSignText::command() const +{ + QStringList ret = m_extraOptions; + + const QList<QUrl> &files = getInputFiles(); + QString fileName; + + if (!files.isEmpty()) + fileName = files.first().path(); + + ret << QLatin1String("-u") << m_signId; + + if (m_options & AsciiArmored) { + if (fileName.isEmpty()) + ret << QLatin1String("--clearsign"); + else + ret << QLatin1String("--armor"); + } + /*if (KGpgSettings::pgpCompatibility()) + ret << QLatin1String("--pgp6");*/ + + if (!fileName.isEmpty()) { + if (m_options & DetachedSignature) + ret << QLatin1String("--detach-sign") << + QLatin1String("--output") << fileName + QLatin1String(".sig"); + + ret << fileName; + } + + // command-fd for pass? + ret << QLatin1String("--command-fd=0"); + + return ret; +} + +QStringList +KGpgSignText::signedText() const +{ + QStringList result; + + foreach (const QString &line, getMessages()) + if (!line.startsWith(QLatin1String("[GNUPG:] "))) { + result.append(line); + } + + return result; +} + +void +KGpgSignText::postStart() +{ + // do nothing, its to early +} + +bool KGpgSignText::nextLine(const QString &line) { + + if (line.startsWith(QLatin1String("[GNUPG:] BEGIN_SIGNING")) &! m_text.isEmpty()) { + GPGProc *proc = getProcess(); + proc->write(m_text.toUtf8()); + proc->closeWriteChannel(); + } else if (!line.startsWith(QLatin1String("[GNUPG:] SIGEXPIRED")) && !line.startsWith(QLatin1String("[GNUPG:] KEYEXPIRED "))) + m_messages.append(line); + + return false; +} + +const QStringList & +KGpgSignText::getMessages() const +{ + return m_messages; +} + +//#include "kgpgsigntext.moc" diff --git a/kgpg/transactions/kgpgsigntext.h b/kgpg/transactions/kgpgsigntext.h new file mode 100644 index 0000000..14459af --- /dev/null +++ b/kgpg/transactions/kgpgsigntext.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2012 Rolf Eike Beer <[email protected]> + */ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KGPGSIGNTEXT_H +#define KGPGSIGNTEXT_H + +#include "kgpgtextorfiletransaction.h" + +#include <QUrl> +#include <QObject> +#include <QString> +#include <QStringList> + +class QProcess; + +/** + * @brief sign the given text or files + */ +class KGpgSignText: public KGpgTextOrFileTransaction { + Q_OBJECT + + Q_DISABLE_COPY(KGpgSignText) + KGpgSignText(); // = delete C++0x +public: + enum SignOption { + DefaultSignature = 0, ///< use whatever GnuPGs defaults are + AsciiArmored = 0x1, ///< output the data as printable ASCII as opposed to binary data + DetachedSignature = 0x2, ///< save the signature in a separate file + }; + Q_DECLARE_FLAGS(SignOptions, SignOption); + + /** + * @brief sign given text + * @param parent parent object + * @param signId the key to use for signing + * @param text text to sign + * @param options signing options + */ + KGpgSignText(QObject *parent, const QString &signId, const QString &text = QString(), const SignOptions &options = AsciiArmored, const QStringList &extraOptions = QStringList()); + + /** + * @brief sign file + * @param parent parent object + * @param signId the key to use for signing + * @param files list of file locations to sign (must only be 1 file) + * @param options signing options + * + * @warning GnuPG can currently handle only one file per invocation for + * signing, so files may only contain one single file. + */ + KGpgSignText(QObject *parent, const QString &signId, const QList<QUrl> &files, const SignOptions &options = DefaultSignature, const QStringList &extraOptions = QStringList()); + + /** + * @brief destructor + */ + virtual ~KGpgSignText(); + + /** + * @brief get signing result + * @return signed text + */ + QStringList signedText() const; + + /** + * @brief get gpg info message + * @return the raw messages from gpg during the operation + */ + const QStringList &getMessages() const; + +protected: + virtual QStringList command() const; + virtual bool nextLine(const QString &line); + +private: + int m_fileIndex; + const SignOptions m_options; + const QString m_signId; + QStringList m_extraOptions; + const QString m_text; + QStringList m_messages; + +private slots: + void postStart(); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(KGpgSignText::SignOptions); + +#endif // KGPGSIGNTEXT_H diff --git a/kgpg/transactions/kgpgtextorfiletransaction.cpp b/kgpg/transactions/kgpgtextorfiletransaction.cpp index e2e74dd..036d911 100644 --- a/kgpg/transactions/kgpgtextorfiletransaction.cpp +++ b/kgpg/transactions/kgpgtextorfiletransaction.cpp @@ -65,9 +65,7 @@ KGpgTextOrFileTransaction::preStart() if (url.isLocalFile()) { locfiles.append(url.toLocalFile()); - qDebug() << "iffed"; } else { - qDebug() << "not iffed"; /* QString tmpfile; //TODO: QIODevice ...? if (KIO::NetAccess::download(url, tmpfile, 0)) { @@ -81,10 +79,8 @@ KGpgTextOrFileTransaction::preStart() } } - qDebug() << "prestart locf list:"; - foreach(QString l, locfiles) { - qDebug() << l; - } + qDebug() << "m_text: " << m_text; + qDebug() << "hasInputTransaction: " << hasInputTransaction(); if (locfiles.isEmpty() && m_tempfiles.isEmpty() && m_text.isEmpty() && !hasInputTransaction()) { setSuccess(TS_MSG_SEQUENCE); @@ -99,8 +95,10 @@ KGpgTextOrFileTransaction::preStart() if (!locfiles.isEmpty() && !m_tempfiles.isEmpty()) { args << QLatin1String("--command-fd=0"); m_closeInput = false; + qDebug() << "if"; } else { m_closeInput = !args.contains(QLatin1String("--command-fd=0")); + qDebug() << "else"; } if (locfiles.count() + m_tempfiles.count() > 1) args << QLatin1String("--multifile"); @@ -113,17 +111,19 @@ KGpgTextOrFileTransaction::preStart() void KGpgTextOrFileTransaction::postStart() { + qDebug() << "post-start! " << m_text; if (!m_text.isEmpty()){ GPGProc *proc = getProcess(); proc->write(m_text.toUtf8()); if (m_closeInput) proc->closeWriteChannel(); - } + } } bool KGpgTextOrFileTransaction::nextLine(const QString &line) { + qDebug() << "nextline called: " << line; if (!line.startsWith(QLatin1String("[GNUPG:] SIGEXPIRED")) && !line.startsWith(QLatin1String("[GNUPG:] KEYEXPIRED "))) m_messages.append(line); diff --git a/kgpg/transactions/kgpgtransaction.cpp b/kgpg/transactions/kgpgtransaction.cpp index 84783aa..241252c 100644 --- a/kgpg/transactions/kgpgtransaction.cpp +++ b/kgpg/transactions/kgpgtransaction.cpp @@ -77,6 +77,7 @@ void KGpgTransactionPrivate::slotReadReady() { QString line; + QWeakPointer<GPGProc> process(m_process); QWeakPointer<KGpgTransaction> par(m_parent); @@ -84,8 +85,10 @@ KGpgTransactionPrivate::slotReadReady() if (m_quitTries) m_quitLines << line; #ifdef KGPG_DEBUG_TRANSACTIONS - kDebug(2100) << m_parent << line; + qDebug() << m_parent << line; #endif /* KGPG_DEBUG_TRANSACTIONS */ + //qDebug() << "trans-read: " << m_parent << line; + if (line.startsWith(QLatin1String("[GNUPG:] USERID_HINT "))) { m_parent->addIdHint(line); @@ -114,7 +117,11 @@ KGpgTransactionPrivate::slotReadReady() line.startsWith(QLatin1String("[GNUPG:] GOOD_PASSPHRASE"))) { // signal GnuPG that there will be no further input and it can // begin sending output. - m_process->closeWriteChannel(); + + // except when signing text... + if(QString::fromAscii(m_parent->metaObject()->className()) != "KGpgSignText"){ + m_process->closeWriteChannel(); + } } else if (line.startsWith(QLatin1String("[GNUPG:] GET_BOOL "))) { switch (m_parent->boolQuestion(line.mid(18))) { case KGpgTransaction::BA_YES: @@ -206,8 +213,9 @@ KGpgTransactionPrivate::write(const QByteArray &a) { m_process->write(a); #ifdef KGPG_DEBUG_TRANSACTIONS - kDebug(2100) << m_parent << a; + qDebug() << m_parent << a; #endif /* KGPG_DEBUG_TRANSACTIONS */ + qDebug() << "trans-write: " << m_parent << a; } void @@ -259,6 +267,8 @@ KGpgTransaction::write(const int i) void KGpgTransaction::askNewPassphrase(const QString& text) { + qDebug() << "KGpgTransaction::askNewPassphrase called"; + emit statusMessage(tr("Requesting Passphrase")); /*d->m_passwordDialog = new KNewPasswordDialog(qobject_cast<QWidget *>(parent())); @@ -268,6 +278,8 @@ KGpgTransaction::askNewPassphrase(const QString& text) connect(d->m_passwordDialog, SIGNAL(rejected()), SLOT(slotPasswordAborted())); connect(d->m_process, SIGNAL(processExited()), d->m_passwordDialog->button(KDialog::Cancel), SLOT(clicked())); d->m_passwordDialog->show();*/ + + } int @@ -324,6 +336,7 @@ KGpgTransaction::unexpectedLine(const QString &line) KGpgTransaction::ts_passphrase_actions KGpgTransaction::passphraseRequested() { + qDebug() << "KGpgTransaction::passphraseRequested called"; if (!askPassphrase()) return PA_USER_ABORTED; else @@ -432,6 +445,8 @@ KGpgTransaction::addArgumentRef(int *ref) bool KGpgTransaction::askPassphrase(const QString &message) { + qDebug() << "KGpgTransaction::askPassphrase called"; + if (d->m_passphraseAction == PA_USER_ABORTED) return false; diff --git a/mainwindow.cpp b/mainwindow.cpp index 393b9f0..d8e6588 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -887,11 +887,55 @@ void MainWindow::sign() QStringList *uidList = mKeyList->getPrivateChecked(); - QByteArray *tmp = new QByteArray(); + if(uidList->isEmpty()) { + QMessageBox::critical(0, tr("Key Selection"), tr("No Private Key Selected")); + return; + } + + //QByteArray *tmp = new QByteArray(); - if (mCtx->sign(uidList, edit->curTextPage()->toPlainText().toUtf8(), tmp)) { + /*if (mCtx->sign(uidList, edit->curTextPage()->toPlainText().toUtf8(), tmp)) { edit->fillTextEditWithText(QString::fromUtf8(*tmp)); + }*/ + + // TODO: more than one signers + KGpgSignText *signt = new KGpgSignText(this, uidList->first(), edit->curTextPage()->toPlainText()); + connect(signt, SIGNAL(done(int)), SLOT(slotSignDone(int))); + signt->start(); + //KGpgTextInterface *interface = new KGpgTextInterface(message, signkeyid, options); + //connect(interface, SIGNAL(txtSigningFinished(QString)), SLOT(slotSignUpdate(QString))); + //interface->signText(message, signkeyid, options); +} + +void MainWindow::slotSignDone(int result) +{ + const KGpgSignText * const signt = qobject_cast<KGpgSignText *>(sender()); + sender()->deleteLater(); + Q_ASSERT(signt != NULL); + + if (result != KGpgTransaction::TS_OK) { + //KMessageBox::sorry(this, i18n("Signing not possible: bad passphrase or missing key")); + //return; + qDebug() << "Signing not possible: bad passphrase or missing key"; + return; + } else { + edit->fillTextEditWithText(signt->signedText().join(QLatin1String("\n")) + QLatin1String("\n")); } + + //signt->deleteLater(); + //const QString content = signt->signedText().join(QLatin1String("\n")) + QLatin1String("\n"); + //setPlainText(content); + //emit resetEncoding(false); + /*sender()->deleteLater(); + + if (text.isEmpty()) + { + qDebug() << "Signing not possible: bad passphrase or missing key"; + return; + } + + edit->fillTextEditWithText(signt->signedText().join(QLatin1String("\n")) + QLatin1String("\n")); + */ } void MainWindow::decrypt() diff --git a/mainwindow.h b/mainwindow.h index 7108237..ac3c8d2 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -30,11 +30,13 @@ #include "settingsdialog.h" #include "verifynotification.h" #include "wizard.h" +//#include "kgpg/kgpgtextinterface.h" #include "kgpg/core/kgpgkey.h" #include "kgpg/transactions/kgpgencrypt.h" #include "kgpg/transactions/kgpgdecrypt.h" #include "kgpg/transactions/kgpgexport.h" #include "kgpg/transactions/kgpgimport.h" +#include "kgpg/transactions/kgpgsigntext.h" QT_BEGIN_NAMESPACE class QMainWindow; @@ -103,6 +105,7 @@ private slots: * @details Sign the text of currently active tab with the checked private keys */ void sign(); + void slotSignDone(int result); /** * @details Verify the text of currently active tab and show verify information. |