aboutsummaryrefslogtreecommitdiffstats
path: root/src/pinentry/pinentry_main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/pinentry/pinentry_main.cpp413
1 files changed, 0 insertions, 413 deletions
diff --git a/src/pinentry/pinentry_main.cpp b/src/pinentry/pinentry_main.cpp
deleted file mode 100644
index fcea7c31..00000000
--- a/src/pinentry/pinentry_main.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
-/* main.cpp - A Qt dialog for PIN entry.
- * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
- * Copyright (C) 2003, 2021 g10 Code GmbH
- * Copyright 2007 Ingo Klöcker
- *
- * Written by Steffen Hansen <[email protected]>.
- * Modified by Marcus Brinkmann <[email protected]>.
- * Modified by Marc Mutz <[email protected]>
- * Software engineering by Ingo Klöcker <[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.
- *
- * This program 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 this program; if not, see <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <QApplication>
-#include <QDebug>
-#include <QIcon>
-#include <QMessageBox>
-#include <QPushButton>
-#include <QString>
-#include <QWidget>
-
-#include "accessibility.h"
-#include "keyboardfocusindication.h"
-#include "pinentry.h"
-#include "pinentryconfirm.h"
-#include "pinentrydialog.h"
-#include "util.h"
-#if QT_VERSION >= 0x050000
-#include <QWindow>
-#endif
-
-#include <errno.h>
-#include <gpg-error.h>
-#include <stdio.h>
-
-#include <stdexcept>
-
-#ifdef FALLBACK_CURSES
-#include <pinentry-curses.h>
-#endif
-
-#if QT_VERSION >= 0x050000 && defined(QT_STATIC)
-#include <QtPlugin>
-#ifdef Q_OS_WIN
-#include <shlobj.h>
-#include <windows.h>
-Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
-#elif defined(Q_OS_MAC)
-Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
-#else
-Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
-#endif
-#endif
-
-#ifdef Q_OS_WIN
-#include <windows.h>
-#endif
-
-#include "pinentry_debug.h"
-
-static QString escape_accel(const QString &s) {
- QString result;
- result.reserve(s.size());
-
- bool afterUnderscore = false;
-
- for (unsigned int i = 0, end = s.size(); i != end; ++i) {
- const QChar ch = s[i];
- if (ch == QLatin1Char('_')) {
- if (afterUnderscore) { // escaped _
- result += QLatin1Char('_');
- afterUnderscore = false;
- } else { // accel
- afterUnderscore = true;
- }
- } else {
- if (afterUnderscore || // accel
- ch == QLatin1Char('&')) { // escape & from being interpreted by Qt
- result += QLatin1Char('&');
- }
- result += ch;
- afterUnderscore = false;
- }
- }
-
- if (afterUnderscore)
- // trailing single underscore: shouldn't happen, but deal with it robustly:
- {
- result += QLatin1Char('_');
- }
-
- return result;
-}
-
-namespace {
-class InvalidUtf8 : public std::invalid_argument {
- public:
- InvalidUtf8() : std::invalid_argument("invalid utf8") {}
- ~InvalidUtf8() throw() {}
-};
-} // namespace
-
-static const bool GPG_AGENT_IS_PORTED_TO_ONLY_SEND_UTF8 = false;
-
-static QString from_utf8(const char *s) {
- const QString result = QString::fromUtf8(s);
- if (result.contains(QChar::ReplacementCharacter)) {
- if (GPG_AGENT_IS_PORTED_TO_ONLY_SEND_UTF8) {
- throw InvalidUtf8();
- } else {
- return QString::fromLocal8Bit(s);
- }
- }
-
- return result;
-}
-
-static void setup_foreground_window(QWidget *widget, WId parentWid) {
-#if QT_VERSION >= 0x050000
- /* For windows set the desktop window as the transient parent */
- QWindow *parentWindow = nullptr;
- if (parentWid) {
- parentWindow = QWindow::fromWinId(parentWid);
- }
-#ifdef Q_OS_WIN
- if (!parentWindow) {
- HWND desktop = GetDesktopWindow();
- if (desktop) {
- parentWindow = QWindow::fromWinId((WId)desktop);
- }
- }
-#endif
- if (parentWindow) {
- // Ensure that we have a native wid
- widget->winId();
- QWindow *wndHandle = widget->windowHandle();
-
- if (wndHandle) {
- wndHandle->setTransientParent(parentWindow);
- }
- }
-#endif
- widget->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint |
- Qt::WindowTitleHint | Qt::WindowCloseButtonHint |
- Qt::WindowStaysOnTopHint |
- Qt::WindowMinimizeButtonHint);
-}
-
-static int qt_cmd_handler(pinentry_t pe) {
- int want_pass = !!pe->pin;
-
- const QString ok = pe->ok ? escape_accel(from_utf8(pe->ok))
- : pe->default_ok ? escape_accel(from_utf8(pe->default_ok))
- :
- /* else */ QLatin1String("&OK");
- const QString cancel = pe->cancel ? escape_accel(from_utf8(pe->cancel))
- : pe->default_cancel
- ? escape_accel(from_utf8(pe->default_cancel))
- :
- /* else */ QLatin1String("&Cancel");
-
- unique_malloced_ptr<char> str{pinentry_get_title(pe)};
- const QString title = str ? from_utf8(str.get()) :
- /* else */ QLatin1String("pinentry-qt");
-
- const QString repeatError = pe->repeat_error_string
- ? from_utf8(pe->repeat_error_string)
- : QLatin1String("Passphrases do not match");
- const QString repeatString =
- pe->repeat_passphrase ? from_utf8(pe->repeat_passphrase) : QString();
- const QString visibilityTT = pe->default_tt_visi
- ? from_utf8(pe->default_tt_visi)
- : QLatin1String("Show passphrase");
- const QString hideTT = pe->default_tt_hide ? from_utf8(pe->default_tt_hide)
- : QLatin1String("Hide passphrase");
-
- const QString capsLockHint = pe->default_capshint
- ? from_utf8(pe->default_capshint)
- : QLatin1String("Caps Lock is on");
-
- const QString generateLbl =
- pe->genpin_label ? from_utf8(pe->genpin_label) : QString();
- const QString generateTT =
- pe->genpin_tt ? from_utf8(pe->genpin_tt) : QString();
-
- if (want_pass) {
- PinEntryDialog pinentry(nullptr, 0, pe->timeout, true, !!pe->quality_bar,
- repeatString, visibilityTT, hideTT);
- setup_foreground_window(&pinentry, pe->parent_wid);
- pinentry.setPinentryInfo(pe);
- pinentry.setPrompt(escape_accel(from_utf8(pe->prompt)));
- pinentry.setDescription(from_utf8(pe->description));
- pinentry.setRepeatErrorText(repeatError);
- pinentry.setGenpinLabel(generateLbl);
- pinentry.setGenpinTT(generateTT);
- pinentry.setCapsLockHint(capsLockHint);
- pinentry.setFormattedPassphrase({bool(pe->formatted_passphrase),
- from_utf8(pe->formatted_passphrase_hint)});
- pinentry.setConstraintsOptions({bool(pe->constraints_enforce),
- from_utf8(pe->constraints_hint_short),
- from_utf8(pe->constraints_hint_long),
- from_utf8(pe->constraints_error_title)});
-
- if (!title.isEmpty()) {
- pinentry.setWindowTitle(title);
- }
-
- /* If we reuse the same dialog window. */
- pinentry.setPin(QString());
-
- pinentry.setOkText(ok);
- pinentry.setCancelText(cancel);
- if (pe->error) {
- pinentry.setError(from_utf8(pe->error));
- }
- if (pe->quality_bar) {
- pinentry.setQualityBar(from_utf8(pe->quality_bar));
- }
- if (pe->quality_bar_tt) {
- pinentry.setQualityBarTT(from_utf8(pe->quality_bar_tt));
- }
- bool ret = pinentry.exec();
- if (!ret) {
- if (pinentry.timedOut()) pe->specific_err = gpg_error(GPG_ERR_TIMEOUT);
- return -1;
- }
-
- const QString pinStr = pinentry.pin();
- QByteArray pin = pinStr.toUtf8();
-
- if (!!pe->repeat_passphrase) {
- /* Should not have been possible to accept
- the dialog in that case but we do a safety
- check here */
- pe->repeat_okay = (pinStr == pinentry.repeatedPin());
- }
-
- int len = strlen(pin.constData());
- if (len >= 0) {
- pinentry_setbufferlen(pe, len + 1);
- if (pe->pin) {
- strcpy(pe->pin, pin.constData());
- return len;
- }
- }
- return -1;
- } else {
- const QString desc =
- pe->description ? from_utf8(pe->description) : QString();
- const QString notok =
- pe->notok ? escape_accel(from_utf8(pe->notok)) : QString();
-
- const QMessageBox::StandardButtons buttons =
- pe->one_button ? QMessageBox::Ok
- : pe->notok ? QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel
- :
- /* else */ QMessageBox::Ok | QMessageBox::Cancel;
-
- PinentryConfirm box{QMessageBox::Information, title, desc, buttons};
- box.setTextFormat(Qt::PlainText);
- box.setTextInteractionFlags(Qt::TextSelectableByMouse);
- box.setTimeout(std::chrono::seconds{pe->timeout});
- setup_foreground_window(&box, pe->parent_wid);
-
- const struct {
- QMessageBox::StandardButton button;
- QString label;
- } buttonLabels[] = {
- {QMessageBox::Ok, ok},
- {QMessageBox::Yes, ok},
- {QMessageBox::No, notok},
- {QMessageBox::Cancel, cancel},
- };
-
- for (size_t i = 0; i < sizeof buttonLabels / sizeof *buttonLabels; ++i)
- if ((buttons & buttonLabels[i].button) &&
- !buttonLabels[i].label.isEmpty()) {
- box.button(buttonLabels[i].button)->setText(buttonLabels[i].label);
- Accessibility::setDescription(box.button(buttonLabels[i].button),
- buttonLabels[i].label);
- }
-
- box.setIconPixmap(applicationIconPixmap());
-
- if (!pe->one_button) {
- box.setDefaultButton(QMessageBox::Cancel);
- }
-
- box.show();
- raiseWindow(&box);
-
- const int rc = box.exec();
-
- if (rc == QMessageBox::Cancel) {
- pe->canceled = true;
- }
- if (box.timedOut()) {
- pe->specific_err = gpg_error(GPG_ERR_TIMEOUT);
- }
-
- return rc == QMessageBox::Ok || rc == QMessageBox::Yes;
- }
-}
-
-static int qt_cmd_handler_ex(pinentry_t pe) {
- try {
- return qt_cmd_handler(pe);
- } catch (const InvalidUtf8 &) {
- pe->locale_err = true;
- return pe->pin ? -1 : false;
- } catch (...) {
- pe->canceled = true;
- return pe->pin ? -1 : false;
- }
-}
-
-pinentry_cmd_handler_t pinentry_cmd_handler = qt_cmd_handler_ex;
-
-int pinentry_main(int argc, char *argv[]) {
- pinentry_init("pinentry-qt");
-
- QApplication *app = NULL;
- int new_argc = 0;
-
-#ifdef FALLBACK_CURSES
-#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
- // check a few environment variables that are usually set on X11 or Wayland
- // sessions
- const bool hasWaylandDisplay = qEnvironmentVariableIsSet("WAYLAND_DISPLAY");
- const bool isWaylandSessionType = qgetenv("XDG_SESSION_TYPE") == "wayland";
- const bool hasX11Display = pinentry_have_display(argc, argv);
- const bool isX11SessionType = qgetenv("XDG_SESSION_TYPE") == "x11";
- const bool isGUISession = hasWaylandDisplay || isWaylandSessionType ||
- hasX11Display || isX11SessionType;
- qCDebug(PINENTRY_LOG) << "hasWaylandDisplay:" << hasWaylandDisplay;
- qCDebug(PINENTRY_LOG) << "isWaylandSessionType:" << isWaylandSessionType;
- qCDebug(PINENTRY_LOG) << "hasX11Display:" << hasX11Display;
- qCDebug(PINENTRY_LOG) << "isX11SessionType:" << isX11SessionType;
- qCDebug(PINENTRY_LOG) << "isGUISession:" << isGUISession;
-#else
- const bool isGUISession = pinentry_have_display(argc, argv);
-#endif
- if (!isGUISession) {
- pinentry_cmd_handler = curses_cmd_handler;
- pinentry_set_flavor_flag("curses");
- } else
-#endif
- {
- /* Qt does only understand -display but not --display; thus we
- are fixing that here. The code is pretty simply and may get
- confused if an argument is called "--display". */
- char **new_argv, *p;
- size_t n;
- int i, done;
-
- for (n = 0, i = 0; i < argc; i++) {
- n += strlen(argv[i]) + 1;
- }
- n++;
- new_argv = (char **)calloc(argc + 1, sizeof *new_argv);
- if (new_argv) {
- *new_argv = (char *)malloc(n);
- }
- if (!new_argv || !*new_argv) {
- fprintf(stderr, "pinentry-qt: can't fixup argument list: %s\n",
- strerror(errno));
- exit(EXIT_FAILURE);
- }
- for (done = 0, p = *new_argv, i = 0; i < argc; i++)
- if (!done && !strcmp(argv[i], "--display")) {
- new_argv[i] = strcpy(p, argv[i] + 1);
- p += strlen(argv[i] + 1) + 1;
- done = 1;
- } else {
- new_argv[i] = strcpy(p, argv[i]);
- p += strlen(argv[i]) + 1;
- }
-
- /* Note: QApplication uses int &argc so argc has to be valid
- * for the full lifetime of the application.
- *
- * As Qt might modify argc / argv we use copies here so that
- * we do not loose options that are handled in both. e.g. display.
- */
- new_argc = argc;
- Q_ASSERT(new_argc);
- app = new QApplication(new_argc, new_argv);
- app->setWindowIcon(QIcon(QLatin1String(":/document-encrypt.png")));
- (void)new KeyboardFocusIndication{app};
- }
-
- pinentry_parse_opts(argc, argv);
-
- int rc = pinentry_loop();
- delete app;
- return rc ? EXIT_FAILURE : EXIT_SUCCESS;
-}