Skip to content
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

LOGIN AUTH next handler should unconditionally succeed if more is false #94

Closed
james-d-elliott opened this issue Jan 6, 2023 · 5 comments · Fixed by #95
Closed

LOGIN AUTH next handler should unconditionally succeed if more is false #94

james-d-elliott opened this issue Jan 6, 2023 · 5 comments · Fixed by #95
Assignees
Labels
bug Something isn't working

Comments

@james-d-elliott
Copy link
Contributor

james-d-elliott commented Jan 6, 2023

Description

Looking at the following code portions:

It appears to me that when the more is false, then the authentication should be considered successful. Let me give my reasoning step by step:

1, Next is called here if err is nil.
2. The err var is only potentially set here as non-nil as it was prechecked here
3. Here are the possible codes (334 and 235) which are NOT an error and this seems to align with the spec
4. Here we see that more is set true if code is 334, so we can assume a 235 if it's not set and the Next implementation was called.

To Reproduce

Use a SMTP Server which doesn't respond with the suffix Authentication successful and instead uses something like Authentication succeeded. Example ProtonMail Bridge.

Expected behaviour

If a server responds with an irregular response as long as the response follows the spec that it's dealt with accordingly.

I'm happy to fix this, but wanted to see what you thought first and maybe there's a reason this has been done that I'm no aware of, the SMTP landscape is a bit wild west.

Screenshots

No response

Attempted Fixes

func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
	if more {
		switch string(fromServer) {
		case ServerRespUsername:
			return []byte(a.username), nil
		case ServerRespPassword:
			return []byte(a.password), nil
		default:
			return nil, fmt.Errorf("unexpected server response: %s", string(fromServer))
		}
	}

	return nil, nil
}

Additional context

Introduced In:

I wish Next included the SMTP code for starters, and that SMTP servers used the examples in the spec.. but officially a 235 indicates a successful response. See RFC2554 Section 4

@wneessen
Copy link
Owner

wneessen commented Jan 7, 2023

Thanks for the bug report James. I'll have a closed look and prepare a fix tomorrow (given you already provided code, the fix should be quick ;) ).

@james-d-elliott
Copy link
Contributor Author

I think the revert to what it was prior should work. I direct messaged you so if you need me to test it I can

wneessen added a commit that referenced this issue Jan 7, 2023
This fixes #94 and basically reverts d0f0435. As James points out correctly in #94, we should not assume specific responses from the server. As long as the spec is followed and the server returns the correct SMTP code, we should not do our own magic.

I've also extended the `getTestConnection` method in client_test.go, so that we can specify more test environment options like `TEST_PORT` and `TEST_TLS_SKIP_VERIFY`. This was needed for testing with the ProtonMail Bridge which listens on a different port and has non-trusted certificates.
@wneessen
Copy link
Owner

wneessen commented Jan 7, 2023

You were completely right James. I've reverted the change accordingly and tested with my usual test server as well as ProtonMail Bridge. Both work as expected now. I believe the change was made by me trying to be overly smart with the server responses, expecting that all servers would respond in a standardized way, which if of course foolish in the the SMTP world (as you call it "wild west" 😄 ). Sorry for causing the trouble with that and thanks again for the thorough report.

I would normaly not release a new version for such a small change, but given that Authelia users are actively affected, I'll create a new release today.

@james-d-elliott
Copy link
Contributor Author

james-d-elliott commented Jan 7, 2023

No drama at all. I went from handling all of this (multipart, auth, proper encoding detection, etc) in Authelia because the go stdlib was lacking to using this lib. So I'm fully aware it's very hard to get 100% right!

Also no rush on a release as we're probably not releasing for about a week as we're in a feature release cycle. I can just use the HEAD commit to test if you're not ready.

Edit: Side note, the fact stdlib doesn't return the status codes and it's completely frozen may turn out to be a reason to fork it later, though I have no specific knowledge that would confirm that other than it being the wild west.

@wneessen
Copy link
Owner

wneessen commented Jan 7, 2023

Edit: Side note, the fact stdlib doesn't return the status codes and it's completely frozen may turn out to be a reason to fork it later, though I have no specific knowledge that would confirm that other than it being the wild west.

Agreed. The frozen part made me thinking about exactly that already as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants