diff --git a/banjax-config.yaml b/banjax-config.yaml index 76f8d69..47afcfe 100644 --- a/banjax-config.yaml +++ b/banjax-config.yaml @@ -111,3 +111,5 @@ sites_to_disable_baskerville: localhost: true use_user_agent_in_cookie: localhost: true +# difficulty of sha-inv page, setting above 10 might cause solving to fail +sha_inv_expected_zero_bits: 10 diff --git a/internal/config.go b/internal/config.go index 12f5678..11f981b 100644 --- a/internal/config.go +++ b/internal/config.go @@ -51,6 +51,7 @@ type Config struct { TooManyFailedChallengesThreshold int `yaml:"too_many_failed_challenges_threshold"` PasswordCookieTtlSeconds int `yaml:"password_cookie_ttl_seconds"` ShaInvCookieTtlSeconds int `yaml:"sha_inv_cookie_ttl_seconds"` + ShaInvExpectedZeroBits uint32 `yaml:"sha_inv_expected_zero_bits"` RestartTime int ReloadTime int Hostname string diff --git a/internal/http_server.go b/internal/http_server.go index b016845..d3eec99 100644 --- a/internal/http_server.go +++ b/internal/http_server.go @@ -21,6 +21,11 @@ import ( "github.com/gin-gonic/gin" ) +const ( + PasswordCookieName = "deflect_password3" + ChallengeCookieName = "deflect_challenge3" +) + func RunHttpServer( config *Config, decisionListsMutex *sync.Mutex, @@ -252,16 +257,16 @@ func getUserAgentOrIp(c *gin.Context, config *Config) string { func passwordChallenge(c *gin.Context, config *Config, roaming bool) { cookieTtl := getPerSiteCookieTtlOrDefault(config, c.Request.Header.Get("X-Requested-Host"), config.PasswordCookieTtlSeconds) - challenge(c, config, "deflect_password3", cookieTtl, config.HmacSecret, roaming) + challenge(c, config, PasswordCookieName, cookieTtl, config.HmacSecret, roaming) sessionCookieEndPoint(c, config) c.Data(401, "text/html", applyArgsToPasswordPage(config, config.PasswordPageBytes, roaming, cookieTtl)) c.Abort() } func shaInvChallenge(c *gin.Context, config *Config) { - challenge(c, config, "deflect_challenge3", config.ShaInvCookieTtlSeconds, config.HmacSecret, false) + challenge(c, config, ChallengeCookieName, config.ShaInvCookieTtlSeconds, config.HmacSecret, false) sessionCookieEndPoint(c, config) - c.Data(429, "text/html", applyCookieMaxAge(config.ChallengerBytes, "deflect_challenge3", config.ShaInvCookieTtlSeconds)) + c.Data(429, "text/html", applyArgsToShaInvPage(config)) c.Abort() } @@ -303,14 +308,28 @@ func applyCookieDomain(pageBytes []byte, cookieName string) (modifiedPageBytes [ func applyArgsToPasswordPage(config *Config, pageBytes []byte, roaming bool, cookieTtl int) (modifiedPageBytes []byte) { // apply default or site specific expire time - modifiedPageBytes = applyCookieMaxAge(pageBytes, "deflect_password3", cookieTtl) + modifiedPageBytes = applyCookieMaxAge(pageBytes, PasswordCookieName, cookieTtl) if !roaming { return } // apply domain scope if allow banjax roaming - modifiedPageBytes = applyCookieDomain(modifiedPageBytes, "deflect_password3") + modifiedPageBytes = applyCookieDomain(modifiedPageBytes, PasswordCookieName) + return +} + +func applyArgsToShaInvPage(config *Config) (modifiedPageBytes []byte) { + modifiedPageBytes = applyCookieMaxAge( + config.ChallengerBytes, + ChallengeCookieName, + config.ShaInvCookieTtlSeconds, + ) + modifiedPageBytes = modifyHTMLContent( + modifiedPageBytes, + "new_solver(10)", + fmt.Sprintf("new_solver(%d)", config.ShaInvExpectedZeroBits), + ) return } @@ -468,10 +487,10 @@ func sendOrValidateShaChallenge( requestedHost := c.Request.Header.Get("X-Requested-Host") requestedPath := c.Request.Header.Get("X-Requested-Path") clientUserAgent := c.Request.Header.Get("X-Client-User-Agent") - challengeCookie, err := c.Cookie("deflect_challenge3") + challengeCookie, err := c.Cookie(ChallengeCookieName) requestedMethod := c.Request.Method if err == nil { - err := ValidateShaInvCookie(config.HmacSecret, challengeCookie, time.Now(), getUserAgentOrIp(c, config), 10) // XXX config + err := ValidateShaInvCookie(config.HmacSecret, challengeCookie, time.Now(), getUserAgentOrIp(c, config), config.ShaInvExpectedZeroBits) if err != nil { // log.Println("Sha-inverse challenge failed") // log.Println(err) @@ -570,7 +589,7 @@ func sendOrValidatePassword( requestedHost := c.Request.Header.Get("X-Requested-Host") requestedPath := c.Request.Header.Get("X-Requested-Path") clientUserAgent := c.Request.Header.Get("X-Client-User-Agent") - passwordCookie, err := c.Cookie("deflect_password3") + passwordCookie, err := c.Cookie(PasswordCookieName) requestedMethod := c.Request.Method // log.Println("passwordCookie: ", passwordCookie) if err == nil { @@ -798,7 +817,7 @@ func decisionForNginx2( decisionForNginxResult.DecisionListResult = NotSet // check if user has a valid password cookie, if so, allow them through - passwordCookie, passwordCookieErr := c.Cookie("deflect_password3") + passwordCookie, passwordCookieErr := c.Cookie(PasswordCookieName) if passwordCookieErr == nil { var grantPriorityPass bool = false expectedHashedPassword, hasPasswordHash := passwordProtectedPaths.SiteToPasswordHash[requestedHost] diff --git a/internal/sha-inverse-challenge.html b/internal/sha-inverse-challenge.html index 18d8d79..965cbf9 100644 --- a/internal/sha-inverse-challenge.html +++ b/internal/sha-inverse-challenge.html @@ -279,6 +279,7 @@ +