Skip to content

Initial client responses with GNU SASL #319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
RichardSteele opened this issue Jan 6, 2025 · 2 comments
Open

Initial client responses with GNU SASL #319

RichardSteele opened this issue Jan 6, 2025 · 2 comments

Comments

@RichardSteele
Copy link
Contributor

RichardSteele commented Jan 6, 2025

I've come across a (misconfigured) SMTP server which requires clients to supply an initial response with SASL authentication although it is supposed to be optional. This has lead me to VMime's default SASL implementation based on GNU SASL:

bool builtinSASLMechanism::hasInitialResponse() const {
// It seems GNU SASL does not support initial response
return false;
}

In fact, GNU SASL can be used with initial responses. It's just a matter of the underlying protocol (IMAP/POP3/SMTP) supporting it and the mechanism being client-first. Of the mechanisms implemented by GNU SASL all but CRAM-MD5 and DIGEST-MD5 are client-first.

A minimal change would be to give builtinSASLMechanism a new boolean member m_initialResponse and do something like

builtinSASLMechanism::builtinSASLMechanism(
	const shared_ptr <SASLContext>& ctx,
	const string& name
)
	: m_context(ctx),
	  m_name(name),
	  m_complete(false),
	  m_initialResponse(name == "PLAIN" || name == "LOGIN" || name == "EXTERNAL" || name == "ANONYMOUS" || name == "SCRAM-SHA-1" || name == "SCRAM-SHA-256" || name == "NTLM" || name == "SECURID" || name == "GSSAPI" || name == "GS2-KRB5" || name == "SAML20" || name == "OPENID20") {

}

bool builtinSASLMechanism::hasInitialResponse() const {

	return m_initialResponse;
}

Another way would be to check if the name is contained in a std::unordered_set instead of comparing all names. Or you could reduce the amount down to those mechanisms that are fully supported by SASLSession::gsaslCallback.

Additionally, IMAPConnection::authenticateSASL should be changed so that the initial response is used only if the server supports the SASL-IR capability.

These would be behavioural changes. So what do you think?

@vincent-richard
Copy link
Member

Hi!

This would be a useful addition to the SASL support, indeed.

At first, I didn't like comparing the mech name for determining whether there is an initial response, but after checking the API, it seems there is no easy way of doing it (aside from instantiating a SASL session for each mech and testing whether gsasl_step() with empty input buffer returns GSASL_NEEDS_MORE...).

@RichardSteele
Copy link
Contributor Author

Yes, unfortunately there's no API function for that since it's implicit knowledge. Calling gsasl_step() with an empy input won't help you. If you look at its implementation you'll see that it just delegates to the specific mechanism. And PLAIN doesn't even care about the input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants