diff options
author | Moritz Heiber <github@heiber.im> | 2017-07-26 09:33:16 +0200 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2017-07-26 15:33:16 +0800 |
commit | 7e12aac61c8ffcfb122d299216a88590e2a63e9c (patch) | |
tree | 0340dde62e1be57163d2c65901b09bd496abf5d4 /routers | |
parent | 1d032f5220e323e14867cfec0b7b06945a47ee06 (diff) | |
download | gitea-7e12aac61c8ffcfb122d299216a88590e2a63e9c.tar.gz gitea-7e12aac61c8ffcfb122d299216a88590e2a63e9c.zip |
Only allow token authentication with 2FA enabled (#2184)
* Don't allow for plain username/password authentication when 2FA is enabled
* Removed debugging statement
* Don't assume a token belongs to a given user, handle two-factor errors properly
* Simplified user/token matching, refactored error handling for two-factor authentication
* Change authentication response to avoid bruteforcing
* Add TODO item as a comment for changing the response for security purposes
Diffstat (limited to 'routers')
-rw-r--r-- | routers/repo/http.go | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/routers/repo/http.go b/routers/repo/http.go index b7e83536ca..4265c80ac4 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -156,24 +156,50 @@ func HTTP(ctx *context.Context) { ctx.Handle(http.StatusInternalServerError, "UserSignIn error: %v", err) return } + } + + if authUser == nil { + authUser, err = models.GetUserByName(authUsername) + + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.HandleText(http.StatusUnauthorized, "invalid credentials") + } else { + ctx.Handle(http.StatusInternalServerError, "GetUserByName", err) + } + return + } - // Assume username now is a token. - token, err := models.GetAccessTokenBySHA(authUsername) + // Assume password is a token. + token, err := models.GetAccessTokenBySHA(authPasswd) if err != nil { if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) { - ctx.HandleText(http.StatusUnauthorized, "invalid token") + ctx.HandleText(http.StatusUnauthorized, "invalid credentials") } else { ctx.Handle(http.StatusInternalServerError, "GetAccessTokenBySha", err) } return } + + if authUser.ID != token.UID { + ctx.HandleText(http.StatusUnauthorized, "invalid credentials") + return + } + token.Updated = time.Now() if err = models.UpdateAccessToken(token); err != nil { ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err) } - authUser, err = models.GetUserByID(token.UID) - if err != nil { - ctx.Handle(http.StatusInternalServerError, "GetUserByID", err) + + } else { + _, err = models.GetTwoFactorByUID(authUser.ID) + + if err == nil { + // TODO: This response should be changed to "invalid credentials" for security reasons once the expectation behind it (creating an app token to authenticate) is properly documented + ctx.HandleText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page") + return + } else if !models.IsErrTwoFactorNotEnrolled(err) { + ctx.Handle(http.StatusInternalServerError, "IsErrTwoFactorNotEnrolled", err) return } } |