package waf import ( "bytes" "encoding/base64" "fmt" "github.com/TeaOSLab/EdgeNode/internal/waf/requests" "github.com/dchest/captcha" "github.com/iwind/TeaGo/logs" stringutil "github.com/iwind/TeaGo/utils/string" "net/http" "time" ) var captchaValidator = &CaptchaValidator{} type CaptchaValidator struct { } func (this *CaptchaValidator) Run(request *requests.Request, writer http.ResponseWriter) { if request.Method == http.MethodPost && len(request.FormValue("TEAWEB_WAF_CAPTCHA_ID")) > 0 { this.validate(request, writer) } else { this.show(request, writer) } } func (this *CaptchaValidator) show(request *requests.Request, writer http.ResponseWriter) { // show captcha captchaId := captcha.NewLen(6) buf := bytes.NewBuffer([]byte{}) err := captcha.WriteImage(buf, captchaId, 200, 100) if err != nil { logs.Error(err) return } _, _ = writer.Write([]byte(` Verify Yourself
` + `

Input verify code above:

`)) } func (this *CaptchaValidator) validate(request *requests.Request, writer http.ResponseWriter) (allow bool) { captchaId := request.FormValue("TEAWEB_WAF_CAPTCHA_ID") if len(captchaId) > 0 { captchaCode := request.FormValue("TEAWEB_WAF_CAPTCHA_CODE") if captcha.VerifyString(captchaId, captchaCode) { // set cookie timestamp := fmt.Sprintf("%d", time.Now().Unix()+CaptchaSeconds) m := stringutil.Md5(captchaSalt + timestamp) http.SetCookie(writer, &http.Cookie{ Name: "TEAWEB_WAF_CAPTCHA", Value: m + timestamp, MaxAge: CaptchaSeconds, Path: "/", // all of dirs }) rawURL := request.URL.Query().Get("url") http.Redirect(writer, request.Raw(), rawURL, http.StatusSeeOther) return false } else { http.Redirect(writer, request.Raw(), request.URL.String(), http.StatusSeeOther) } } return true }