From 6c5d2c5e68e86536b6c511f5067bb26efbc5b1a4 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 5 Jun 2020 12:04:15 +0200 Subject: Add simple RPC to remotely trigger login --- src/loginform.cpp | 89 ++++++++++++++++++++++++++++++++----------------------- src/loginrpc.cpp | 45 ++++++++++++++++++++++++++++ src/loginrpc.h | 25 ++++++++++++++++ src/settings.h | 2 +- 4 files changed, 123 insertions(+), 38 deletions(-) create mode 100644 src/loginrpc.cpp create mode 100644 src/loginrpc.h (limited to 'src') diff --git a/src/loginform.cpp b/src/loginform.cpp index 8076b15..3c82fcd 100644 --- a/src/loginform.cpp +++ b/src/loginform.cpp @@ -13,6 +13,7 @@ #include "settings.h" #include "global.h" #include "namereplace.h" +#include "loginrpc.h" #include "x11util.h" #undef KeyPress #undef KeyRelease @@ -40,6 +41,15 @@ LoginForm::LoginForm(QWidget *parent) : { ui->setupUi(this); initialize(); + int port = Settings::rpcPort(); + if (port != 0) { + auto *car = new LoginRpc(port, this); + connect(car, &LoginRpc::loginRequest, [this](const QString &username, const QString &password, const QString &resolution) { + ui->userInput->setText(username); + ui->passwordInput->setText(password); + this->startAuthentication(); + }); + } } LoginForm::~LoginForm() @@ -94,9 +104,8 @@ void LoginForm::initialize() }); // timer to reset the form to its original state - if (Settings::resetForm() != 0) { - resetFormTimer.setInterval(Settings::resetForm()); - connect(&resetFormTimer, &QTimer::timeout, this, [this]() { + if (Settings::resetForm() > 0) { + connect(&resetFormTimer, &QTimer::timeout, [this]() { int idleTime = static_cast(getIdleTime(QX11Info::display())); int remaining = Settings::resetForm() * 1000 - idleTime; if (remaining <= 0) { @@ -105,7 +114,42 @@ void LoginForm::initialize() } resetFormTimer.start(remaining + 100); }); - resetFormTimer.start(); + resetFormTimer.start(Settings::resetForm() * 1000); + } + + if (Settings::guestSessionEnabled()) { + if (!Settings::guestSessionButtonText().isEmpty()) { + ui->guestButton->setText(Settings::guestSessionButtonText()); + } + if (!Settings::userSessionButtonText().isEmpty()) { + ui->loginButton->setText(Settings::userSessionButtonText()); + } + if (!Settings::guestSessionStartText().isEmpty()) { + ui->guestStartText->setText(Settings::guestSessionStartText()); + } + if (!Settings::guestSessionStartButtonText().isEmpty()) { + ui->guestStartButton->setText(Settings::guestSessionStartButtonText()); + } + connect(ui->loginButton, &QAbstractButton::released, this, [this]() { + ui->loginChooser->setCurrentWidget(ui->loginPage); + ui->userInput->setFocus(); + }); + connect(ui->guestButton, &QAbstractButton::released, this, [this]() { + ui->loginChooser->setCurrentWidget(ui->guestPage); + }); + connect(ui->backButton, &QAbstractButton::released, this, [this]() { + resetForm(); + }); + connect(ui->loginChooser, &QStackedWidget::currentChanged, this, [this]() { + if (ui->loginChooser->currentWidget() == ui->welcomePage) { + ui->backButton->hide(); + } else { + ui->backButton->show(); + } + }); + ui->loginChooser->setCurrentWidget(ui->welcomePage); + } else { + ui->loginChooser->setCurrentWidget(ui->loginPage); } if (!Global::testMode()) { @@ -126,44 +170,12 @@ void LoginForm::initialize() connect(Global::greeter(), &QLightDM::Greeter::authenticationComplete, this, &LoginForm::onAuthenticationComplete); if (Settings::guestSessionEnabled()) { - if (!Settings::guestSessionButtonText().isEmpty()) { - ui->guestButton->setText(Settings::guestSessionButtonText()); - } - if (!Settings::userSessionButtonText().isEmpty()) { - ui->loginButton->setText(Settings::userSessionButtonText()); - } - if (!Settings::guestSessionStartText().isEmpty()) { - ui->guestStartText->setText(Settings::guestSessionStartText()); - } - if (!Settings::guestSessionStartButtonText().isEmpty()) { - ui->guestStartButton->setText(Settings::guestSessionStartButtonText()); - } - connect(ui->loginButton, &QAbstractButton::released, this, [this]() { - ui->loginChooser->setCurrentWidget(ui->loginPage); - ui->userInput->setFocus(); - }); - connect(ui->guestButton, &QAbstractButton::released, this, [this]() { - ui->loginChooser->setCurrentWidget(ui->guestPage); - }); - connect(ui->backButton, &QAbstractButton::released, this, [this]() { - resetForm(); - }); - connect(ui->loginChooser, &QStackedWidget::currentChanged, this, [this]() { - if (ui->loginChooser->currentWidget() == ui->welcomePage) { - ui->backButton->hide(); - } else { - ui->backButton->show(); - } - }); connect(ui->guestStartButton, &QAbstractButton::released, this, []() { if (!Global::autoLoginGuest()) { std::cerr << "Guest login failed..." << std::endl; // TODO warn user about it } }); - ui->loginChooser->setCurrentWidget(ui->welcomePage); - } else { - ui->loginChooser->setCurrentWidget(ui->loginPage); } } @@ -240,8 +252,11 @@ void LoginForm::leaveDropDownActivated(int index) else if (actionName == "suspend") Global::power()->suspend(); } -void LoginForm::onMessage(QString message, QLightDM::Greeter::MessageType /* type */) +void LoginForm::onMessage(QString message, QLightDM::Greeter::MessageType type) { + if (type == QLightDM::Greeter::MessageType::MessageTypeError) { + ui->passwordInput->clear(); + } std::cerr << "Message: " << message.toStdString() << std::endl; showMessage(message, false); clearMsg = true; diff --git a/src/loginrpc.cpp b/src/loginrpc.cpp new file mode 100644 index 0000000..4ced53e --- /dev/null +++ b/src/loginrpc.cpp @@ -0,0 +1,45 @@ +#include "loginrpc.h" + +#include +#include +#include + +LoginRpc::LoginRpc(int port, QObject *parent) + : QObject(parent) +{ + QTcpServer *srv = new QTcpServer(this); + srv->listen(QHostAddress::Any, port); + connect(srv, &QTcpServer::newConnection, [=] { + while (srv->hasPendingConnections()) { + QTcpSocket *sock = srv->nextPendingConnection(); + handleIncoming(sock); + } + }); +} + +void LoginRpc::handleIncoming(QTcpSocket *sock) { + connect(sock, &QTcpSocket::readyRead, [=] { + QByteArray ba = sock->readAll(); // XXX We assume everything arrives in one packet + if (ba.length() < 2) { + sock->deleteLater(); + return; + } + int vers = (ba[0] << 8) + ba[1]; + ba = ba.mid(2); + ba = QByteArray::fromBase64(ba); + if (vers == 1) { + handleCommandV1(QString::fromUtf8(ba)); + } else { + qDebug() << "Ignoring unknown Login RPC version" << vers; + } + }); +} + +void LoginRpc::handleCommandV1(const QString &command) +{ + QStringList lines = command.split('\n'); + while (lines.count() < 3) { + lines.append(QString()); + } + emit loginRequest(lines[0], lines[1], lines[2]); +} diff --git a/src/loginrpc.h b/src/loginrpc.h new file mode 100644 index 0000000..1777ca4 --- /dev/null +++ b/src/loginrpc.h @@ -0,0 +1,25 @@ +#ifndef _LOGIN_RPC_H_ +#define _LOGIN_RPC_H_ + +#include +#include + +class QTcpServer; +class QTcpSocket; + +class LoginRpc : public QObject +{ + Q_OBJECT + +public: + explicit LoginRpc(int port, QObject *parent); + +private: + void handleIncoming(QTcpSocket *sock); + void handleCommandV1(const QString &command); + +signals: + void loginRequest(const QString &username, const QString &password, const QString &resolution); +}; + +#endif diff --git a/src/settings.h b/src/settings.h index cc9cda3..0876889 100644 --- a/src/settings.h +++ b/src/settings.h @@ -44,12 +44,12 @@ public: static QStringList clockShadow() { return s_settings->value("clock-shadow").toString().split(QRegExp("\\s"), QString::SkipEmptyParts); } static QString usernamePlaceholder() { return s_settings->value("username-placeholder").toString(); } static QString passwordPlaceholder() { return s_settings->value("password-placeholder").toString(); } - static bool guestSessionEnabled() { return s_settings->value("guest-session-enabled").toBool(); } static QString userSessionButtonText() { return s_settings->value("user-session-button-text").toString(); } static QString guestSessionButtonText() { return s_settings->value("guest-session-button-text").toString(); } static QString guestSessionStartText() { return s_settings->value("guest-session-start-text").toString(); } static QString guestSessionStartButtonText() { return s_settings->value("guest-session-start-button-text").toString(); } static int resetForm() { return s_settings->value("reset-timeout", "30").toInt(); } + static int rpcPort() { return s_settings->value("rpc-port", "0").toInt(); } }; #endif // SETTINGS_H -- cgit v1.2.3-55-g7522