summaryrefslogtreecommitdiffstats
path: root/roseh.moe.go
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2025-10-06 21:08:45 -0700
committerRose Hogenson <rosehogenson@posteo.net>2025-10-06 21:08:45 -0700
commitc5a5b24cf6370ab549c033b20ad0389ec3ce8ec1 (patch)
treedfd8b0914e2021fdd75e65c1db1beadbb51f74d9 /roseh.moe.go
parentd35bbbd54ed3de79d2a7d709013ff49d4a9413b8 (diff)
downloadroseh.moe-c5a5b24cf6370ab549c033b20ad0389ec3ce8ec1.tar.zst
Simplify simplify simplify
Diffstat (limited to 'roseh.moe.go')
-rw-r--r--roseh.moe.go89
1 files changed, 38 insertions, 51 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index 77c78c1..9b5c1a6 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -9,6 +9,7 @@ import (
"embed"
"encoding/base64"
"encoding/binary"
+ "encoding/hex"
"flag"
"fmt"
"html/template"
@@ -19,8 +20,6 @@ import (
"strings"
"sync"
"time"
-
- "gitlab.com/rhogenson/roseh.moe/internal/pwhash"
)
var (
@@ -40,12 +39,12 @@ func loadSecrets() error {
}
for _, line := range bytes.Split(bytes.TrimSuffix(secrets, []byte("\n")), []byte("\n")) {
if pw, ok := bytes.CutPrefix(line, []byte("notepad-password=")); ok {
- notepadPassword, err = base64.RawURLEncoding.AppendDecode(nil, pw)
+ notepadPassword, err = hex.AppendDecode(nil, pw)
if err != nil {
return err
}
} else if key, ok := bytes.CutPrefix(line, []byte("secret-key=")); ok {
- secretKey, err = base64.RawURLEncoding.AppendDecode(nil, key)
+ secretKey, err = hex.AppendDecode(nil, key)
if err != nil {
return err
}
@@ -135,9 +134,10 @@ type wormholeTemplateArgs struct {
}
func wormhole(w http.ResponseWriter, r *http.Request) {
- buf := make([]byte, 20)
+ const nWords = 10
+ buf := make([]byte, 2*nWords)
rand.Read(buf)
- words := make([]string, 10)
+ words := make([]string, nWords)
for i := range words {
words[i] = wordList[binary.NativeEndian.Uint16(buf[2*i:])&0x1fff]
}
@@ -247,24 +247,22 @@ func wormholeReady(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "event: ready\ndata:\n\n")
}
-func sign(msg []byte, info string) []byte {
+func mac(msg []byte) []byte {
mac := hmac.New(sha256.New, secretKey)
- mac.Write(binary.AppendVarint(nil, int64(len(info))))
- io.WriteString(mac, info)
mac.Write(msg)
- return mac.Sum(msg)
+ return mac.Sum(nil)
+}
+
+func sign(msg []byte) []byte {
+ return append(msg, mac(msg)...)
}
-func verify(msg []byte, info string) ([]byte, bool) {
+func verify(msg []byte) ([]byte, bool) {
if len(msg) < sha256.Size {
return nil, false
}
msg, messageMAC := msg[:len(msg)-sha256.Size], msg[len(msg)-sha256.Size:]
- mac := hmac.New(sha256.New, secretKey)
- mac.Write(binary.AppendVarint(nil, int64(len(info))))
- io.WriteString(mac, info)
- mac.Write(msg)
- expectedMAC := mac.Sum(nil)
+ expectedMAC := mac(msg)
if !hmac.Equal(messageMAC, expectedMAC) {
return nil, false
}
@@ -276,27 +274,11 @@ func makeToken() (string, error) {
if err != nil {
return "", err
}
- return base64.RawURLEncoding.EncodeToString(sign(b, "auth")), nil
+ return base64.RawURLEncoding.EncodeToString(sign(b)), nil
}
const cookieExpiration = 180 * 24 * time.Hour
-func checkToken(token string) bool {
- authCookie, err := base64.RawURLEncoding.DecodeString(token)
- if err != nil {
- return false
- }
- msg, ok := verify(authCookie, "auth")
- if !ok {
- return false
- }
- var t time.Time
- if err := t.UnmarshalBinary(msg); err != nil {
- return false
- }
- return time.Since(t) < cookieExpiration
-}
-
func attachCookie(w http.ResponseWriter) error {
token, err := makeToken()
if err != nil {
@@ -339,10 +321,25 @@ func cookieAuth(w http.ResponseWriter, r *http.Request) (string, bool) {
if err != nil {
return csrfToken, false
}
- if !checkToken(cookie.Value) {
+ authCookie, err := base64.RawURLEncoding.DecodeString(cookie.Value)
+ if err != nil {
return csrfToken, false
}
- attachCookie(w)
+ msg, ok := verify(authCookie)
+ if !ok {
+ return csrfToken, false
+ }
+ var t time.Time
+ if err := t.UnmarshalBinary(msg); err != nil {
+ return csrfToken, false
+ }
+ cookieAge := time.Since(t)
+ if cookieAge > cookieExpiration {
+ return csrfToken, false
+ }
+ if cookieAge > 24*time.Hour {
+ attachCookie(w)
+ }
return csrfToken, true
}
@@ -367,15 +364,11 @@ var (
type loginTemplateArgs struct {
CSRFToken string
- Redirect string
Error bool
}
-func executeLoginTemplate(w io.Writer, csrfToken, redirect string) {
- if err := loginTemplate.Execute(w, loginTemplateArgs{
- Redirect: base64.RawURLEncoding.EncodeToString(sign([]byte(redirect), "redirect")),
- CSRFToken: csrfToken,
- }); err != nil {
+func executeLoginTemplate(w io.Writer, csrfToken string) {
+ if err := loginTemplate.Execute(w, loginTemplateArgs{CSRFToken: csrfToken}); err != nil {
log.Printf("Warning: login: %s", err)
}
}
@@ -385,10 +378,10 @@ func login(w http.ResponseWriter, r *http.Request) {
http.Error(w, "bad CSRF token", http.StatusBadRequest)
return
}
- if err := pwhash.Check(notepadPassword, r.FormValue("password")); err != nil {
+ hash := sha256.Sum256([]byte(r.FormValue("password")))
+ if subtle.ConstantTimeCompare(notepadPassword, hash[:]) == 0 {
if err := loginTemplate.Execute(w, loginTemplateArgs{
Error: true,
- Redirect: r.FormValue("redirect"),
CSRFToken: r.FormValue("csrf-token"),
}); err != nil {
log.Printf("Warning: login: %s", err)
@@ -396,13 +389,7 @@ func login(w http.ResponseWriter, r *http.Request) {
return
}
attachCookie(w)
- redirect := "/"
- if b, err := base64.RawURLEncoding.DecodeString(r.FormValue("redirect")); err == nil {
- if r, ok := verify(b, "redirect"); ok {
- redirect = string(r)
- }
- }
- http.Redirect(w, r, redirect, http.StatusSeeOther)
+ http.Redirect(w, r, "/notepad", http.StatusSeeOther)
}
var (
@@ -422,7 +409,7 @@ type notepadTemplateArgs struct {
func notepad(w http.ResponseWriter, r *http.Request) {
csrfToken, ok := cookieAuth(w, r)
if !ok {
- executeLoginTemplate(w, csrfToken, "/notepad")
+ executeLoginTemplate(w, csrfToken)
return
}
notepadContentsMu.Lock()