Add pinentry-qt4-clipboard option
authorAndre Heinecke <aheinecke@intevation.de>
Wed, 29 May 2013 17:38:18 +0000 (17:38 +0000)
committerAndre Heinecke <aheinecke@intevation.de>
Wed, 29 May 2013 17:38:18 +0000 (17:38 +0000)
    Enabling this option will make it possible to paste a
    passphrase into pinentry-qt4. This defeats the secmem
    mechanism but drastically increases usability for some
    users.

    * configure.ac: New option pinentry-qt4-clipboard.
    * qt4/qsecurelineedit.cpp, qt4/qsecurelineedit.h: Activate
    clipboard and context menu if PINENTRY_QT4_CLIPBOARD is defined.

configure.ac
qt4/qsecurelineedit.cpp
qt4/qsecurelineedit.h

index 0eb5e74..b4133b0 100644 (file)
@@ -447,6 +447,18 @@ if test "$pinentry_qt4" = "yes"; then
   AC_DEFINE(PINENTRY_QT4, 1, [The Qt4 version of Pinentry is to be build])
 fi
 
+dnl
+dnl Option to add insecure clipboard support to pinentry-qt4
+dnl
+AC_ARG_ENABLE(pinentry-qt4-clipboard,
+              AC_HELP_STRING([--enable-pinentry-qt4-clipboard], [Enable clipboard support in
+                              pinentry-qt4]), pinentry_qt4_clipboard=$enableval)
+
+if test "$pinentry_qt4_clipboard" = "yes" -a "$pinentry_qt4" = "yes"; then
+  AC_DEFINE(PINENTRY_QT4_CLIPBOARD, 1, [Pinentry-qt4 should have clipboard support])
+  pinentry_qt4_clip_msg="(with clipboard support)"
+fi
+
 dnl if test "$pinentry_qt4" = "yes"; then
 dnl Additional checks for Qt4 pinentry.
 dnl End of additional checks for Qt4 pinentry.
@@ -521,7 +533,7 @@ AC_MSG_NOTICE([
        GTK+ Pinentry ....: $pinentry_gtk
        GTK+-2 Pinentry ..: $pinentry_gtk_2
        Qt Pinentry ......: $pinentry_qt
-       Qt4 Pinentry .....: $pinentry_qt4
+       Qt4 Pinentry .....: $pinentry_qt4 $pinentry_qt4_clip_msg
        W32 Pinentry .....: $pinentry_w32
 
        Fallback to Curses: $fallback_curses
index da6bf0c..4384574 100644 (file)
@@ -1325,6 +1325,16 @@ void QSecureLineEdit::deselect()
     d->finishChange();
 }
 
+#ifndef QT_NO_CLIPBOARD
+/* Should only be used if pasting the passphrase is explicitly
+ * wanted. Defeats the purpose of the secmem implmentation */
+void QSecureLineEdit::insert(const QString &newText)
+{
+    if (!newText.isEmpty() && newText.at(0).isPrint()) {
+        insert( secqstring( newText.begin(), newText.end() ) );
+    }
+}
+#endif
 
 /*!
     Deletes any selected text, inserts \a newText, and validates the
@@ -1466,6 +1476,7 @@ void QSecureLineEdit::copy() const
 
 void QSecureLineEdit::paste()
 {
+    Q_D(QSecureLineEdit);
     if(echoMode() == PasswordEchoOnEdit)
     {
         Q_D(QSecureLineEdit);
@@ -1479,12 +1490,14 @@ void QSecureLineEdit::paste()
 void QSecureLineEditPrivate::copy(bool clipboard) const
 {
     Q_Q(const QSecureLineEdit);
-    QString t = q->selectedText();
-    if (!t.isEmpty() && echoMode == QSecureLineEdit::Normal) {
-        q->disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), q, 0);
-        QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection);
-        q->connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
-                   q, SLOT(_q_clipboardChanged()));
+    if (echoMode == QSecureLineEdit::Normal) {
+        QString t = QString(q->selectedText().c_str());
+        if (!t.isEmpty()) {
+            q->disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), q, 0);
+            QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection);
+            q->connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
+                    q, SLOT(_q_clipboardChanged()));
+        }
     }
 }
 
@@ -2603,16 +2616,17 @@ QMenu *QSecureLineEdit::createStandardContextMenu()
     d->actions[QSecureLineEditPrivate::UndoAct]->setEnabled(d->isUndoAvailable());
     d->actions[QSecureLineEditPrivate::RedoAct]->setEnabled(d->isRedoAvailable());
 #ifndef QT_NO_CLIPBOARD
-    d->actions[QSecureLineEditPrivate::CutAct]->setEnabled(!d->readOnly && d->hasSelectedText());
-    d->actions[QSecureLineEditPrivate::CopyAct]->setEnabled(d->hasSelectedText());
+    d->actions[QSecureLineEditPrivate::CutAct]->setEnabled(!d->readOnly && d->hasSelectedText()
+            && d->echoMode == QSecureLineEdit::Normal);
+    d->actions[QSecureLineEditPrivate::CopyAct]->setEnabled(d->hasSelectedText() && d->echoMode == QSecureLineEdit::Normal);
     d->actions[QSecureLineEditPrivate::PasteAct]->setEnabled(!d->readOnly && !QApplication::clipboard()->text().isEmpty());
 #else
     d->actions[QSecureLineEditPrivate::CutAct]->setEnabled(false);
     d->actions[QSecureLineEditPrivate::CopyAct]->setEnabled(false);
     d->actions[QSecureLineEditPrivate::PasteAct]->setEnabled(false);
 #endif
-    d->actions[QSecureLineEditPrivate::ClearAct]->setEnabled(!d->readOnly && !d->text.isEmpty() && d->hasSelectedText());
-    d->actions[QSecureLineEditPrivate::SelectAllAct]->setEnabled(!d->text.isEmpty() && !d->allSelected());
+    d->actions[QSecureLineEditPrivate::ClearAct]->setEnabled(!d->readOnly && !d->text.empty() && d->hasSelectedText());
+    d->actions[QSecureLineEditPrivate::SelectAllAct]->setEnabled(!d->text.empty() && !d->allSelected());
 
     QMenu *popup = new QMenu(this);
     popup->setObjectName(QLatin1String("qt_edit_menu"));
@@ -2640,8 +2654,8 @@ QMenu *QSecureLineEdit::createStandardContextMenu()
     if (!d->readOnly) {
 #endif
         popup->addSeparator();
-        QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup);
-        popup->addMenu(ctrlCharacterMenu);
+        //QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup);
+        //popup->addMenu(ctrlCharacterMenu);
     }
     return popup;
 }
index 963ccc3..4afdbb2 100644 (file)
 #include <QtGui/qframe.h>
 #include <QtCore/qstring.h>
 
+#include <config.h>
+
 #include "secstring.h"
 
+#ifndef PINENTRY_QT4_CLIPBOARD
+// Sacrifice security for usability by allowing clipboard actions
+# ifndef QT_NO_CLIPBOARD
+#  define QT_NO_CLIPBOARD
+# endif
+# ifndef QT_NO_CONTEXTMENU
+#  define QT_NO_CONTEXTMENU
+# endif
+#endif
+
 // for moc, since qt4_automoc doesn't appear to hand over defines when
 // running moc. They should't be visible when #including other Qt
 // headers, since they #ifdef out virtual functions (->BIC).
 #ifndef QT_NO_COMPLETER
 # define QT_NO_COMPLETER
 #endif
-#ifndef QT_NO_CLIPBOARD
-# define QT_NO_CLIPBOARD
-#endif
-#ifndef QT_NO_CONTEXTMENU
-# define QT_NO_CONTEXTMENU
-#endif
 #ifndef QT_NO_DRAGANDDROP
 # define QT_NO_DRAGANDDROP
 #endif
@@ -203,6 +209,9 @@ public Q_SLOTS:
 public:
     void deselect();
     void insert(const secqstring &);
+#ifndef QT_NO_CLIPBOARD
+    void insert(const QString &);
+#endif
 #ifndef QT_NO_CONTEXTMENU
     QMenu *createStandardContextMenu();
 #endif