Browse Source

Add Tor support to the client

Go does not allow direct .onion connections.

72c1180852
master
Teran McKinney 2 years ago
parent
commit
fd7ccb3598
  1. 52
      burnpaste.go
  2. 70
      burnpaste_test.go
  3. 5
      go.mod
  4. 5
      go.sum
  5. 2
      test.sh

52
burnpaste.go

@ -9,18 +9,65 @@ import (
"net/http"
"net/url"
"strings"
"golang.org/x/net/proxy"
)
func isOnion(someURL string) (bool, error) {
parsedURL, err := url.Parse(someURL)
if err != nil {
return true, err
}
urlParts := strings.Split(parsedURL.Host, ".")
tld := urlParts[len(urlParts)-1]
if tld == "onion" {
return true, err
} else {
return false, err
}
}
func Hash(data []byte) string {
hash := sha256.Sum256(data)
return hex.EncodeToString(hash[:])
}
func onionHTTP() (client *http.Client, err error) {
torProxyURL, err := url.Parse("socks5://127.0.0.1:9050")
if err != nil {
return
}
torDialer, err := proxy.FromURL(torProxyURL, proxy.Direct)
if err != nil {
return
}
torTransport := &http.Transport{Dial: torDialer.Dial}
client = &http.Client{Transport: torTransport}
return
}
func clearnetOrOnionHTTP(url string) (client *http.Client, err error) {
// Returns a http.Client using a local Tor SOCKS proxy if .onion,
// plain old http.Client if not.
reallyIsOnion, err := isOnion(url)
if err != nil {
return
}
if reallyIsOnion {
client, err = onionHTTP()
} else {
client = &http.Client{}
}
return
}
func Write(endpoint string, paste []byte) (string, error) {
var burnpasteURL string
var err error
hash := Hash(paste)
response, err := http.PostForm(endpoint+"/write", url.Values{"data": {string(paste)}})
ourURL := endpoint + "write"
ourHTTP, err := clearnetOrOnionHTTP(ourURL)
response, err := ourHTTP.PostForm(ourURL, url.Values{"data": {string(paste)}})
if err != nil {
return burnpasteURL, err
}
@ -39,7 +86,8 @@ func Write(endpoint string, paste []byte) (string, error) {
func Read(burnpasteURL string) ([]byte, error) {
urlParts := strings.Split(burnpasteURL, "/")
urlHash := urlParts[len(urlParts)-1]
response, err := http.Get(burnpasteURL)
ourHTTP, err := clearnetOrOnionHTTP(burnpasteURL)
response, err := ourHTTP.Get(burnpasteURL)
if err != nil {
return []byte(""), err
}

70
burnpaste_test.go

@ -5,7 +5,8 @@ import (
"testing"
)
const endpoint = "http://localhost:2323"
// Endpoint must end with a slash.
const endpoint = "http://localhost:2323/"
func TestHash(t *testing.T) {
hash := Hash([]byte("This is a paste."))
@ -33,3 +34,70 @@ func TestRead(t *testing.T) {
log.Printf("url: %s", url)
}
}
func TestIsOnion(t *testing.T) {
url := "http://google.com"
status, err := isOnion(url)
if err != nil {
t.Errorf("We got error: %s", err.Error())
} else {
log.Printf("url: %s", url)
}
if status == false {
log.Printf("We know %s is not a .onion", url)
} else {
log.Printf("We think this is a .onion but it's not. %s", url)
}
url = "http://localhost"
status, err = isOnion(url)
if err != nil {
t.Errorf("We got error: %s", err.Error())
} else {
log.Printf("url: %s", url)
}
if status == false {
log.Printf("We know %s is not a .onion", url)
} else {
log.Printf("We think this is a .onion but it's not. %s", url)
}
url = "http://127.0.0.1:2323"
status, err = isOnion(url)
if err != nil {
t.Errorf("We got error: %s", err.Error())
} else {
log.Printf("url: %s", url)
}
if status == false {
log.Printf("We know %s is not a .onion", url)
} else {
log.Printf("We think this is a .onion but it's not. %s", url)
}
url = "http://somesite.onion"
status, err = isOnion(url)
if err != nil {
t.Errorf("We got error: %s", err.Error())
} else {
log.Printf("url: %s", url)
}
if status == true {
log.Printf("We know %s is a .onion", url)
} else {
log.Printf("We think this is not a .onion but it is. %s", url)
}
url = "http://somesite.onion/somestuff/thing.txt"
status, err = isOnion(url)
if err != nil {
t.Errorf("We got error: %s", err.Error())
} else {
log.Printf("url: %s", url)
}
if status == true {
log.Printf("We know %s is a .onion", url)
} else {
log.Printf("We think this is not a .onion but it is. %s", url)
}
}

5
go.mod

@ -2,4 +2,7 @@ module github.com/teran-mckinney/burnpaste
go 1.12
require gopkg.in/alexcesaro/statsd.v2 v2.0.0
require (
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80
gopkg.in/alexcesaro/statsd.v2 v2.0.0
)

5
go.sum

@ -1,2 +1,7 @@
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc=
gopkg.in/alexcesaro/statsd.v2 v2.0.0/go.mod h1:i0ubccKGzBVNBpdGV5MocxyA/XlLUJzA7SLonnE4drU=

2
test.sh

@ -39,7 +39,7 @@ cleanup() {
trap cleanup $(seq 1 64)
fail() {
echo "$1"
echo "FAIL: $1"
cleanup
exit 1
}

Loading…
Cancel
Save