-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Authentication state is not reset properly when using NTLM #1095
Comments
Reproduced here, with simple digest auth. (curl 7.51.1) HOWTO:
Only destroy and re-create handle do the trick |
An NTLM problem cannot be reproduced with Digest. You may have a similar symptom, but it is not this same issue. |
I agree here with Daniel, NTLM is strictly connection-bound while Digest ist not. |
I think it could be reproduced by setting ntlm on the first request to a server which does not require authentication, then post body is omitted from the subsequent request (even if the connection is not reused and the easy is reset between operations). Reproduction with '--next' (git-master), against a server on localhost which simply echos back post body: |
Yes that looks like it. You can also reproduce using http://httpbin.org/post as the URL if you don't have a local server |
I think, the digest issue may be related as in digest flow we also may not set authhost.done to true. To my understanding, authhost.multi is used when we know that authentication is not complete yet (we expect 401), that's in order to avoid posting the data unnecessarily. As such, I think it will be safe to clear authhost.multi at http_done() after the flag was used, since even if we'll be still expecting yet another 401 (unlikely), we'll be passing again at output_auth_headers() and it will be set back to true if necessary. As @mkauf noted, a refactoring of this logic would be great, but in the meanwhile, the below patch seem to work (passes make test): |
In fact, the same command can be used to reproduce digest (and is solved by the above commit): |
That is my understanding as well. The only possible conflict I can think of is if it could mess up when multiple authentication methods are provided but reading the code just now it doesn't look like it. I assume that's covered in the automated tests, anyway. |
I don't think it will conflict with multiple auth-methods, in that case the local 'auth' variable in output_auth_headers() does not get set, and so auth.multi gets set to false (then the request gets sent without any auth header and we get the list of supported auth methods from the server and we pick one auth from the intersection of wanted and supported auth-methods). |
yup. my concern was multi might also be used for starting the auth, for example imagine if there was some code like I am going to add a test and I will land this tomorrow/Wed, if there are no objections. |
This flag is meant for the current request based on authentication state, once the request is done we can clear the flag. Also change auth.multi to auth.multipass for better readability. See discussion at curl#1095 Signed-off-by: Isaac Boukris <iboukris@gmail.com> Reported-by: Michael Kaufmann
We should also clear the whole auth state at the bottom of
I don't understand why
... but obviously that's not what |
Yea, the multi name doesn't help much, let's change it to multipass: iboukris@57ce2ec |
@mkauf we probably should reset auth-struct in easy reset, but that by itself will not address the case of easy reuse without reset (i think). |
@Frenche yes, your patch is needed too! we should commit them both. |
Maybe we should have a better fix for curl_easy_reset, I've seen similar. Perhaps we should make a new handle, move over pointers to what is documented to still exist, cleanup the original handle and then memcpy that whole new handle back into the original handle. I'm still in the thought stage but how does that sound. The only problem that could stick is if anything in the new handle is a pointer to itself, though tests would catch it if that happened. |
@jay yea, that's probably how I'd picture easy_reset to look like. |
I think we should go forward and push the two bugfixes that we have developed. |
I opened #1326 to clear the multi(pass) flag at http_done(). |
I have pushed the two bugfixes, thanks to everyone who has worked on this issue! |
I did this
This example program performs two requests. libcurl does not send the request body for the second request - that's the bug.
sleep.php:
submit.php:
I expected the following
libcurl sends the request body for the second request.
curl/libcurl version
operating system
Linux x64
hints
The bug appears even if
curl_easy_reset()
is called between the requests.For NTLM, the flag
state.authhost.multi
is set. Because of this flag,conn->bits.authneg
is set. And because of this flag, the body is omitted, even for subsequent requests.state.authhost
(andstate.authproxy
) should probably be reset incurl_easy_reset()
. For NTLM, it should also be reset when the connection changes (there is already some code for NTLM increate_conn()
). It should also be reset when the URL changes. Probably all members ofstruct UrlState state
should be reset when the URL changes. That's what the name "UrlState" suggests.All NTLM state should be attached to the current connection. It's wrong to attach it directly to the easy handle. Probably a refactoring is necessary to fix this bug properly.
The text was updated successfully, but these errors were encountered: