From 1f49778cb04027b5b0d043f95561cb44c69b80f3 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 13 May 2024 16:53:02 +0200 Subject: Support cow-token in browser-login mode --- src/global.cpp | 23 +++++++++++++++++++++++ src/global.h | 4 ++++ src/qrlogin.cpp | 11 +++-------- src/webview.cpp | 12 ++++++++---- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/global.cpp b/src/global.cpp index 4efccad..ab2519b 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include bool Global::m_testMode = false; @@ -116,3 +118,24 @@ QStringList Global::urlWhitelist() return QStringList(); return loadUrlList(path); } + +void Global::writeCowToken(const QString &user, const QString &token) +{ + QString userHash = QString::fromLocal8Bit(QCryptographicHash::hash(user.toLocal8Bit(), QCryptographicHash::Md5).toHex()); + QFile file(QLatin1String("/run/openslx/lightdm/") + userHash); + if (file.open(QFile::WriteOnly | QFile::Truncate)) { + file.write(token.toLocal8Bit()); + file.close(); + file.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner); + } +} + +bool Global::isValidShibCreds(const QString &ustr, const QString &upass) +{ + static QRegularExpression R_USER("^[a-z_A-Z][a-zA-Z0-9_@.-]{1,32}$"); + static QRegularExpression R_PASS("^[a-z0-9]{1,32}$"); + + return ustr.contains('@') + && R_USER.match(ustr).hasMatch() + && R_PASS.match(upass).hasMatch(); +} diff --git a/src/global.h b/src/global.h index bdc79cd..d581c07 100644 --- a/src/global.h +++ b/src/global.h @@ -52,6 +52,10 @@ public: static QStringList urlBlacklist(); + static void writeCowToken(const QString &user, const QString &token); + + static bool isValidShibCreds(const QString &ustr, const QString &upass); + private: static bool m_testMode; static QLightDM::Greeter *m_Greeter; diff --git a/src/qrlogin.cpp b/src/qrlogin.cpp index 22ea7e9..c562e98 100644 --- a/src/qrlogin.cpp +++ b/src/qrlogin.cpp @@ -1,5 +1,6 @@ #include "qrlogin.h" #include "settings.h" +#include "global.h" #include @@ -155,15 +156,9 @@ void QrLogin::renderReceivedSvg() void QrLogin::handleAuthReceived(const QStringList &lines) { if (lines.size() >= 2) { - if (lines.size() >= 3) { + if (lines.size() >= 3 && !lines[2].isEmpty()) { // Admin token for editing VMs - QString userHash = QString::fromLocal8Bit(QCryptographicHash::hash(lines[0].toLocal8Bit(), QCryptographicHash::Md5).toHex()); - QFile file(QLatin1String("/run/openslx/lightdm/") + userHash); - if (file.open(QFile::WriteOnly | QFile::Truncate)) { - file.write(lines[2].toLocal8Bit()); - file.close(); - file.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner); - } + Global::writeCowToken(lines[0], lines[2]); } emit startAuthentication(lines[0], QLatin1String("shib=") + lines[1]); } else { diff --git a/src/webview.cpp b/src/webview.cpp index 54d19eb..9ebc1ba 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -15,9 +15,6 @@ #include #include -static QRegularExpression R_USER("^[a-z_A-Z][a-zA-Z0-9_@.-]{1,32}$"); -static QRegularExpression R_PASS("^[a-z0-9]{1,32}$"); - static QRegularExpression urlListToRegExp(const QStringList &list); // Override user-agent to make it appear mobile @@ -137,6 +134,7 @@ void WebView::onLoadFinished(bool ok) auto pass = this->page()->mainFrame()->documentElement().findFirst("#bwlp-password"); auto err = this->page()->mainFrame()->documentElement().findFirst("#bwlp-error"); auto hash = this->page()->mainFrame()->documentElement().findFirst("#bwlp-hash"); + auto adminToken = this->page()->mainFrame()->documentElement().findFirst("#bwlp-cow-token"); if (!user.isNull() && !pass.isNull() && !hash.isNull()) { if (hash.toPlainText() != QCryptographicHash::hash(_token.toLatin1(), QCryptographicHash::Md5).toHex()) { qDebug() << " *** Invalid security hash ***"; @@ -145,8 +143,14 @@ void WebView::onLoadFinished(bool ok) } auto ustr = user.toPlainText(); auto upass = pass.toPlainText(); - if (ustr.contains('@') && R_USER.match(ustr).hasMatch() && R_PASS.match(upass).hasMatch()) { + if (Global::isValidShibCreds(ustr, upass)) { + QString token = adminToken.toPlainText(); + if (!token.isEmpty()) { + Global::writeCowToken(ustr, token); + } emit startAuthentication(ustr, "shib=" + _token + upass); + } else { + emit triggerReset("Invalid user or passhash format"); } } else if (!err.isNull()) { this->stop(); -- cgit v1.2.3-55-g7522