diff options
| author | saturneric <[email protected]> | 2026-09-12 20:17:25 +0200 |
|---|---|---|
| committer | saturneric <[email protected]> | 2026-09-12 20:21:12 +0200 |
| commit | 97c04923c88402ba64aaee8da35cfb66857ec023 (patch) | |
| tree | 753619189c310a81c2c1f58cbfb85fd4f9bc91d1 /src | |
| parent | fix: must init raw pointer *bodyPart (diff) | |
| download | vmime-97c04923c88402ba64aaee8da35cfb66857ec023.tar.gz vmime-97c04923c88402ba64aaee8da35cfb66857ec023.zip | |
feat(smtp): add AUTH LOGIN support
- support servers that offer LOGIN without other mechanisms
- encode username and password as base64 prompt responses
- restrict LOGIN authentication to secured connections
- mark the connection authenticated after a successful exchange
Diffstat (limited to 'src')
| -rw-r--r-- | src/vmime/net/smtp/SMTPConnection.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/vmime/net/smtp/SMTPConnection.cpp b/src/vmime/net/smtp/SMTPConnection.cpp index 07d03765..e7620f79 100644 --- a/src/vmime/net/smtp/SMTPConnection.cpp +++ b/src/vmime/net/smtp/SMTPConnection.cpp @@ -359,6 +359,47 @@ void SMTPConnection::authenticate() { return; } } + + // AUTH LOGIN, for the many servers that offer it and nothing else we + // can speak. Without SASL, PLAIN alone leaves those servers + // unreachable. Still inside the m_secured guard above: LOGIN sends the + // username and password as bare base64, which is encoding and not + // encryption, so it must never touch a cleartext socket. + const string login("LOGIN"); + + if (std::find(authMechs.begin(), authMechs.end(), login) != authMechs.end()) { + + const string username = getAuthenticator()->getUsername(); + const string password = getAuthenticator()->getPassword(); + + // LOGIN is a three-step conversation: the server prompts for each + // field with a 334 and we answer with one base64 line. + const auto sendBase64 = [&](const string& value) -> int { + utility::inputStreamStringAdapter in(value); + string encoded; + utility::outputStreamStringAdapter out(encoded); + + vmime::utility::encoder::b64Encoder encoder; + encoder.encode(in, out); + + m_socket->send(encoded + "\r\n"); + + shared_ptr <SMTPResponse> resp = readResponse(); + return resp ? resp->getCode() : -1; + }; + + sendRequest(SMTPCommand::AUTH(login)); + + shared_ptr <SMTPResponse> response = readResponse(); + + if (response && response->getCode() == 334) { + + if (sendBase64(username) == 334 && sendBase64(password) == 235) { + m_authenticated = true; + return; + } + } + } } #endif // VMIME_HAVE_SASL_SUPPORT |
