|
@@ -19,6 +19,9 @@ import (
|
|
|
"io"
|
|
|
"net/http"
|
|
|
"strings"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/fatedier/frp/pkg/util/util"
|
|
|
)
|
|
|
|
|
|
type HTTPAuthWraper struct {
|
|
@@ -46,8 +49,9 @@ func (aw *HTTPAuthWraper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
type HTTPAuthMiddleware struct {
|
|
|
- user string
|
|
|
- passwd string
|
|
|
+ user string
|
|
|
+ passwd string
|
|
|
+ authFailDelay time.Duration
|
|
|
}
|
|
|
|
|
|
func NewHTTPAuthMiddleware(user, passwd string) *HTTPAuthMiddleware {
|
|
@@ -57,32 +61,28 @@ func NewHTTPAuthMiddleware(user, passwd string) *HTTPAuthMiddleware {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func (authMid *HTTPAuthMiddleware) SetAuthFailDelay(delay time.Duration) *HTTPAuthMiddleware {
|
|
|
+ authMid.authFailDelay = delay
|
|
|
+ return authMid
|
|
|
+}
|
|
|
+
|
|
|
func (authMid *HTTPAuthMiddleware) Middleware(next http.Handler) http.Handler {
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
reqUser, reqPasswd, hasAuth := r.BasicAuth()
|
|
|
if (authMid.user == "" && authMid.passwd == "") ||
|
|
|
- (hasAuth && reqUser == authMid.user && reqPasswd == authMid.passwd) {
|
|
|
+ (hasAuth && util.ConstantTimeEqString(reqUser, authMid.user) &&
|
|
|
+ util.ConstantTimeEqString(reqPasswd, authMid.passwd)) {
|
|
|
next.ServeHTTP(w, r)
|
|
|
} else {
|
|
|
+ if authMid.authFailDelay > 0 {
|
|
|
+ time.Sleep(authMid.authFailDelay)
|
|
|
+ }
|
|
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
|
|
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-func HTTPBasicAuth(h http.HandlerFunc, user, passwd string) http.HandlerFunc {
|
|
|
- return func(w http.ResponseWriter, r *http.Request) {
|
|
|
- reqUser, reqPasswd, hasAuth := r.BasicAuth()
|
|
|
- if (user == "" && passwd == "") ||
|
|
|
- (hasAuth && reqUser == user && reqPasswd == passwd) {
|
|
|
- h.ServeHTTP(w, r)
|
|
|
- } else {
|
|
|
- w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
|
|
- http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
type HTTPGzipWraper struct {
|
|
|
h http.Handler
|
|
|
}
|