On Tue, Apr 02, 2013 at 06:54:40PM +0300, Mikko Rapeli wrote: > I have a problem with git (1.7.9 and 1.8.2.357.gcc3e4eb) and https transport > to gerrit server (2.5.1-3-g719dfc7). I'm producing the problem on Cygwin but my > colleagues have same issue on Linux as well. > > Gerrit server is matching corporate policies with single sign on, so after > three failed login attempts the account gets locked until a password reset. > > Git amplifies this problem by asking for users password only once, and if > user made a typo git is still re-using the wrong password enough times to > get an account immediately locked. Hmm. The sequence should be: - request, get 401 - prompt user for password - retry request with password - if 401, die IOW, we should make only a single request with the credential, and immediately die afterwards. We do hit once to get the initial 401, but we do not even provide a username, so unless the corporate policy is locking out based on IP, it should not matter (and if it is, that shows a fundamental misunderstanding about how a 401 is supposed to work). But from your log, I see: > --------------------------------------------------------------- > > $ GIT_CURL_VERBOSE=1 git fetch > ... > > GET /gerrit/.../info/refs?service=git-upload-pack HTTP/1.1 > ... > < HTTP/1.1 401 Authorization Required > ... Here's our first 401. OK. > ---------- I guess git prompts for password here. -------------- Maybe...see below. > * Server auth using Basic with user '...' > > GET /gerrit/.../info/refs?service=git-upload-pack HTTP/1.1 > Authorization: Basic ... > ... > < HTTP/1.1 401 Authorization Required > < Date: ... > * Authentication problem. Ignoring this. > ... > * The requested URL returned error: 401 We get another 401. Now git should die. But it doesn't: > * STATE: PROTOCONNECT => DO handle... > * Server auth using Basic with user '...' > > GET /gerrit/.../info/refs?service=git-upload-pack HTTP/1.1 > Authorization: Basic ... It makes another request instead. Weirdly, this does not result in a 401: > * STATE: DO => DO_DONE handle... > * STATE: DO_DONE => WAITPERFORM handle... > * STATE: WAITPERFORM => PERFORM handle... > ... > < HTTP/1.1 302 Found > ... > < Location: ...funnylongurl > ... > * Ignoring the response-body > * Connection #1 to host ... left intact > * Issue another request to this URL: '...funnylongurl' > ... > * Server auth using Basic with user '...' > > GET ...funnylongurl > Authorization: Basic ... > ... > * The requested URL returned error: 500 Internal Server Error > * Closing connection 1 We get redirected somewhere where we provide the (presumably wrong) credential again. I do not think that is git's fault; the server asked us to make the extra request. Is that part of the lockout procedure? If it is not, it seems odd that the server would issue a redirect for a bogus auth (shouldn't it just keep giving us 401?). I do not know what is going on with the redirection there, but I have a hunch on the extra auth round-trip. What does your remote URL look like? Does it have your username (e.g., https://user@host/project.git)? I have noticed that if curl sees such a URL, it attempts to do a password-less authentication itself, before even handing control back to git. So my above sequence would become: 1. git feeds URL to curl, who makes request 2. we get a 401 3. curl says "Oh, I have a username; let me try that" and re-requests 4. we get another 401, because we need a password 5. curl says "that didn't work" and hands control back to git 6. git requests a password from the user and gives it to curl 7. curl retries with the password, but it's wrong, so that results in a 401, too At the end of it, we've now made _two_ failed requests for user X, rather than one. I don't know if there's a way to tell curl not to try the extra user-only round-trip. But you can strip the username out of your URL to avoid it. -Peff -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html