diff --git a/README.md b/README.md
index d30778c..899c594 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ For technical details, you can try asking Josh (not me) or reverse engineer the
-Donations are always appreciated but never expected nor required:
+I do this shit for free, sometimes to my own detriment, for no good reason. Consider donating if you appreciate this monumental waste of my time.
XMR: `8BjCARiV2uB2gZTbbiMUetfRxcAYZgVM5fXxjEbpmb2nAu8ND1grazZ1EhMGdRqVerAtvEJeiy7SzA3SLXpg2CtRDtCAFfn`
diff --git a/cerberus.go b/cerberus.go
index 6a30e43..63f7a23 100644
--- a/cerberus.go
+++ b/cerberus.go
@@ -30,8 +30,6 @@ type Solution struct {
Nonce uint32 // Solution nonce. This is the "answer" to the problem.
Redirect string // Relative path to redirect to after Solution is accepted.
- Steps int8 // Steps, as described in Challenge.
-
// TODO: Maybe make the redirect shit auto, idk.
host *url.URL
@@ -102,7 +100,6 @@ func genHashes(ctx context.Context, c Challenge) <-chan Solution {
Salt: c.Salt,
Nonce: nonce,
Redirect: "/", // Use sensible default for placeholder, for now.
- Steps: c.Steps - 1,
}
// Ensure we don't hang if out channel is full on ctx close.
select {
diff --git a/cerberus_test.go b/cerberus_test.go
index 7067cb5..d56f69b 100644
--- a/cerberus_test.go
+++ b/cerberus_test.go
@@ -4,9 +4,11 @@ import (
"context"
"errors"
"fmt"
+ "io"
"log"
"net"
"net/http"
+ "net/http/cookiejar"
"strings"
"testing"
@@ -31,26 +33,33 @@ func solveTest(ctx context.Context, hc http.Client, host string) error {
connType = "tor"
}
- log.Printf("Fetching new %s challenge...", connType)
- c, err := NewChallenge(ctx, hc, host)
- if err != nil {
- return err
- }
- log.Printf("Challenge: %s, Difficulty: %d, Steps: %d\n", c.Salt, c.Diff, c.Steps)
+ steps := int8(1)
- s, err := Solve(ctx, c)
- if err != nil {
- return err
- }
- log.Printf("Solution hash: %x, nonce: %d\n", s.Hash, s.Nonce)
+ for steps > 0 {
+ log.Printf("Fetching new %s challenge...", connType)
+ c, err := NewChallenge(ctx, hc, host)
+ if err != nil {
+ return err
+ }
+ log.Printf("Challenge: %s, Difficulty: %d, Steps: %d\n", c.Salt, c.Diff, c.Steps)
+ steps = c.Steps
- resp, err := Submit(ctx, hc, s, "")
- if err != nil {
- return err
- }
- defer resp.Body.Close()
+ s, err := Solve(ctx, c)
+ if err != nil {
+ return err
+ }
+ log.Printf("Solution hash: %x, nonce: %d\n", s.Hash, s.Nonce)
- log.Printf("Response: %s\n\n", resp.Header.Get("Set-Cookie"))
+ resp, err := Submit(ctx, hc, s, "")
+ if err != nil {
+ return err
+ }
+
+ b, err := io.ReadAll(resp.Body)
+ log.Printf("Response: %s\n\n", b[:60])
+
+ resp.Body.Close()
+ }
return nil
}
@@ -67,9 +76,16 @@ func newProxyTransport() *http.Transport {
func TestSubmit(t *testing.T) {
ctx := t.Context()
- err := solveTest(ctx, http.Client{}, _TEST_HOST)
+ jar, err := cookiejar.New(nil)
if err != nil {
t.Error(err)
+ return
+ }
+
+ err = solveTest(ctx, http.Client{Jar: jar}, _TEST_HOST)
+ if err != nil {
+ t.Error(err)
+ return
}
var dnsErr *net.DNSError
diff --git a/go.mod b/go.mod
index 3fe0925..9b37f82 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
-module github.com/y-a-t-s/cerberus
+module gitgud.io/yats/cerberus
-go 1.25.5
+go 1.25.6
require (
github.com/minio/sha256-simd v1.0.1
diff --git a/http.go b/http.go
index ac44856..2e996b6 100644
--- a/http.go
+++ b/http.go
@@ -34,14 +34,16 @@ func NewChallenge(ctx context.Context, hc http.Client, host string) (Challenge,
return Challenge{}, err
}
- // Update host url in case we get redirected across domains.
- hc.CheckRedirect = func(req *http.Request, via []*http.Request) error {
- rh := req.URL.Host
- if rh != u.Host && strings.HasPrefix(rh, "kiwifarms") {
- u.Host = rh
- }
+ if hc.CheckRedirect == nil {
+ // Update host url in case we get redirected across domains.
+ hc.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+ rh := req.URL.Host
+ if rh != u.Host && strings.HasPrefix(rh, "kiwifarms") {
+ u.Host = rh
+ }
- return nil
+ return nil
+ }
}
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
@@ -95,31 +97,7 @@ func Submit(ctx context.Context, hc http.Client, s Solution, redirect string) (*
s.Redirect = redirect
}
- resp, err := postSolution(ctx, hc, s)
- if err != nil {
- return nil, err
- }
-
- // This feels gross, but it works.
- for s.Steps > 0 {
- resp.Body.Close()
-
- c, err := NewChallenge(ctx, hc, s.host.String())
- if err != nil {
- return nil, err
- }
-
- s, err = Solve(ctx, c)
- if err != nil {
- return nil, err
- }
- resp, err = Submit(ctx, hc, s, redirect)
- if err != nil {
- return nil, err
- }
- }
-
- return resp, nil
+ return postSolution(ctx, hc, s)
}
func parseHost(addr string) (*url.URL, error) {
@@ -144,18 +122,7 @@ func postSolution(ctx context.Context, hc http.Client, s Solution) (*http.Respon
return nil, err
}
- resp, err := hc.Do(req)
- if err != nil {
- return nil, err
- }
-
- // TODO: Additionally verify failure from response JSON. Maybe include resp body in err type.
- // Rejected solution response: status=400 body={"success":false,"reason":"invalid_solution","action":"retry"}
- if resp.StatusCode == 400 {
- return resp, &ErrInvalidSolution{s}
- }
-
- return resp, nil
+ return hc.Do(req)
}
func parseTags(r io.Reader) (Challenge, error) {