Bug 428078

Summary: SMTP AUTH Login truncates Base64 representation of username
Product: [Applications] trojita Reporter: Marcel Bosling <marcel.bosling>
Component: SMTPAssignee: Trojita default assignee <trojita-bugs>
Status: RESOLVED FIXED    
Severity: normal CC: espen
Priority: NOR    
Version First Reported In: git   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description Marcel Bosling 2020-10-21 23:15:27 UTC
The username is truncated for my usecase when using a AUTH Login. Therefore the authentication fails with error 5.7.3. 


STEPS TO REPRODUCE
1. Try to connect to an SMTP server via AUTH Login/StartTLS (my case: rather long mail address)

OBSERVED RESULT
Authentication fails with error 5.7.3.

EXPECTED RESULT
Authentication should reach the next step and process the given password.


SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Arch Linux Kernel 5.9.1 x64
(available in About System)
KDE Plasma Version: 5.20.1
KDE Frameworks Version: 5.75.0
Qt Version: 5.15.1

ADDITIONAL INFORMATION

PATCH:

diff --git a/src/qwwsmtpclient/qwwsmtpclient.cpp b/src/qwwsmtpclient/qwwsmtpclient.cpp
index 1c34fb86..619244dc 100644
--- a/src/qwwsmtpclient/qwwsmtpclient.cpp
+++ b/src/qwwsmtpclient/qwwsmtpclient.cpp
@@ -12,6 +12,7 @@
 #include "qwwsmtpclient.h"
 #include <QSslSocket>
 #include <QtDebug>
+#include <QDebug>
 #include <QRegularExpression>
 #include <QQueue>
 #include <QVariant>
@@ -544,7 +545,7 @@ void QwwSmtpClientPrivate::sendAuthPlain(const QString & username, const QString
 
 void QwwSmtpClientPrivate::sendAuthLogin(const QString & username, const QString & password, int stage) {
     if (stage==1) {
-        auto buf = username.toUtf8().toBase64() + "\r\n";
+        QByteArray buf = username.toUtf8().toBase64() + "\r\n";
         emit q->logSent(buf);
         socket->write(buf);
     } else if (stage==2) {
Comment 1 Jan Kundrát 2020-10-22 10:14:59 UTC
I do not understand how the proposed patch is supposed to fix the reported issue. Inclusion of <QDebug> looks like a leftover from some debugging. Instead of specifying type of that local variable as `auto`, it's now `QByteArray`. However, looking at the docs, `username` is a QString, then it calls toUtf8() which returns a QByteArray, then toBase64() which remains a QByteArray, and there's an operator+(QByteArray, const char*) which once again yields QByteArray. Unlike with QString, there's no QStringBuilder involved in there as far as I can tell.

Are you sure you're *really* comparing results with the recent master, and then recent master with this particular patch applied? Can you share what's in `buf` before and after this patch?
Comment 2 Marcel Bosling 2020-10-22 12:24:34 UTC
Hi Jan,

indeed the <QDebug> statement is a leftover of my investigations.

These are the results when using auto and QByteArray for buf:

const QString &sername:  "someexampleusername@whereever.org"
auto buf:  "a\x00u\x00t\x00o\x00 \x00""b\r\n"
QByteArray buf:  "c29tZWV4YW1wbGV1c2VybmFtZUB3aGVyZWV2ZXIub3Jn\r\n"



SIDENOTE:


I've tried to reproduce the problem with a simple QT program doing just the conversion with auto and QByteArray. The resulting variables hold the same (correct) base64 encoded data, yielding:

auto:  "U29tZWxvbmd1c2VybmFtZUB3aGVyZWV2ZXIub3Jn\r\n"
bufQB:  "U29tZWxvbmd1c2VybmFtZUB3aGVyZWV2ZXIub3Jn\r\n"


SOURCE:

#include <QCoreApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    const QString username = "Somelongusername@whereever.org";

    const QString &reftousername = username;

    auto bufAuto = reftousername.toUtf8().toBase64() + "\r\n";
    QByteArray bufQB = reftousername.toUtf8().toBase64() + "\r\n";

    qDebug()<<"auto: " << bufAuto;
    qDebug()<<"bufQB: " << bufQB;

    return a.exec();
}
Comment 3 Marcel Bosling 2020-11-01 15:31:03 UTC
Hi again,

I've used typeid().name() on buf to see what type get's deduced from auto buf and for me it turns out to be the following mangeld type name: 

14QStringBuilderI10QByteArrayA3_cE 

It seems that a QStringBuilder is indeed involved. This is on GCC 10.2.0.
Comment 4 Espen Sandøy Hustad 2023-03-26 18:37:32 UTC
I can confirm that this also happens with gcc (Gentoo 12.2.1_p20230304 p13) 12.2.1 20230304
Comment 5 Bug Janitor Service 2023-03-26 18:42:40 UTC
A possibly relevant merge request was started @ https://invent.kde.org/pim/trojita/-/merge_requests/34
Comment 6 Espen Sandøy Hustad 2023-03-31 08:27:37 UTC
Git commit 64c4358c74ecc0c96a154cc066cba91d5503bbe7 by Espen Sandøy Hustad, on behalf of Marcel Bosling.
Committed on 31/03/2023 at 04:48.
Pushed by jkt into branch 'master'.

fix: SMTP auth login username base64 encoding

Auto deduces buf to be QStringBuilder. This breaks base64 encoding of
the username, which makes auth login fail.

This also fixes a clazy warning: auto-unexpected-qstringbuilder.

Thanks to Marcel Bosling for finding the issue, and providing this
patch.

M  +1    -1    src/qwwsmtpclient/qwwsmtpclient.cpp

https://invent.kde.org/pim/trojita/commit/64c4358c74ecc0c96a154cc066cba91d5503bbe7