1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
// SPDX-License-Identifier: BSD-2-Clause
// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
package main
import (
"crypto/sha256"
"crypto/subtle"
"encoding/base64"
"errors"
"log"
"net/http"
"strings"
)
type tparams struct {
Identifier string
Message string
Global any
}
func main() {
log.Fatal(http.ListenAndServe(listenAddr, http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
cookie, err := request.Cookie("powxy")
if err != nil {
if !errors.Is(err, http.ErrNoCookie) {
log.Println("COOKIE_ERR", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
http.Error(writer, "error fetching cookie", http.StatusInternalServerError)
return
}
}
identifier, expectedMAC := makeIdentifierMAC(request)
if validateCookie(cookie, expectedMAC) {
log.Println("PROXY", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
proxyRequest(writer, request)
return
}
authPage := func(message string) {
err := tmpl.Execute(writer, tparams{
Identifier: base64.StdEncoding.EncodeToString(identifier),
Message: message,
Global: global,
})
if err != nil {
log.Println("Error executing template:", err)
}
}
if request.ParseForm() != nil {
log.Println("MALFORMED", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
authPage("You submitted a malformed form.")
return
}
formValues, ok := request.PostForm["powxy"]
if !ok {
log.Println("CHALLENGE", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
authPage("")
return
} else if len(formValues) != 1 {
log.Println("FORM_VALUES", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
authPage("You submitted an invalid number of form values.")
return
}
nonce, err := base64.StdEncoding.DecodeString(formValues[0])
if err != nil {
log.Println("BASE64", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
authPage("Your submission was improperly encoded.")
return
}
if len(nonce) > 32 {
log.Println("TOO_LONG", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
authPage("Your submission was too long.")
return
}
h := sha256.New()
h.Write(identifier)
h.Write(nonce)
ck := h.Sum(nil)
if !validateBitZeros(ck, global.NeedBits) {
log.Println("WRONG", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
authPage("Your submission was incorrect, or your session has expired while submitting.")
return
}
http.SetCookie(writer, &http.Cookie{
Name: "powxy",
Value: base64.StdEncoding.EncodeToString(expectedMAC),
Secure: true,
HttpOnly: true,
})
log.Println("ACCEPTED", getRemoteIP(request), request.RequestURI, request.Header.Get("User-Agent"))
http.Redirect(writer, request, "", http.StatusSeeOther)
})))
}
func validateCookie(cookie *http.Cookie, expectedMAC []byte) bool {
if cookie == nil {
return false
}
gotMAC, err := base64.StdEncoding.DecodeString(cookie.Value)
if err != nil {
return false
}
return subtle.ConstantTimeCompare(gotMAC, expectedMAC) == 1
}
func getRemoteIP(request *http.Request) (remoteIP string) {
if secondary {
remoteIP, _, _ = strings.Cut(request.Header.Get("X-Forwarded-For"), ",")
}
if remoteIP == "" {
remoteIP = request.RemoteAddr
index := strings.LastIndex(remoteIP, ":")
if index != -1 {
remoteIP = remoteIP[:index]
}
}
return
}
|