summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorMoritz Heiber <github@heiber.im>2017-07-26 09:33:16 +0200
committerLunny Xiao <xiaolunwen@gmail.com>2017-07-26 15:33:16 +0800
commit7e12aac61c8ffcfb122d299216a88590e2a63e9c (patch)
tree0340dde62e1be57163d2c65901b09bd496abf5d4 /routers
parent1d032f5220e323e14867cfec0b7b06945a47ee06 (diff)
downloadgitea-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.go38
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
}
}