Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
38ca0d08e7 | ||
![]() |
a9bf9faba1 | ||
![]() |
3c6a72d179 | ||
![]() |
e8b7525950 | ||
![]() |
a0407fd3e3 | ||
![]() |
3c5397e87f | ||
![]() |
9baee36493 | ||
![]() |
379de14264 | ||
![]() |
dc12ba56d4 | ||
![]() |
281084cb81 | ||
![]() |
ff6b890bfd | ||
![]() |
12d1bf38b2 | ||
![]() |
7fa46ffc98 | ||
![]() |
a516752491 | ||
![]() |
4c81f5f7a0 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -23,3 +23,4 @@ _testmain.go
|
||||
itp-golang-github-eyedeekay-gosam.txt
|
||||
.pc
|
||||
deb/
|
||||
samsocks/samsocks
|
||||
|
7
Makefile
7
Makefile
@@ -1,9 +1,9 @@
|
||||
|
||||
USER_GH=eyedeekay
|
||||
VERSION=0.32.26
|
||||
VERSION=0.32.29
|
||||
packagename=gosam
|
||||
|
||||
echo:
|
||||
echo: fmt
|
||||
@echo "type make version to do release $(VERSION)"
|
||||
|
||||
version:
|
||||
@@ -22,3 +22,6 @@ tar:
|
||||
link:
|
||||
rm -f ../goSam
|
||||
ln -sf . ../goSam
|
||||
|
||||
fmt:
|
||||
gofmt -w -s *.go */*.go
|
||||
|
59
README.md
59
README.md
@@ -3,10 +3,10 @@ goSam
|
||||
|
||||
A go library for using the [I2P](https://geti2p.net/en/) Simple Anonymous
|
||||
Messaging ([SAM version 3.0](https://geti2p.net/en/docs/api/samv3)) bridge. It
|
||||
has support for SAM version 3.1 signature types.
|
||||
has support for all streaming features SAM version 3.2.
|
||||
|
||||
This is in an **early development stage**. I would love to hear about any
|
||||
issues or ideas for improvement.
|
||||
This is widely used and easy to use, but thusfar, mostly by me. It sees a lot of
|
||||
testing and no breaking changes to the API are expected.
|
||||
|
||||
## Installation
|
||||
```
|
||||
@@ -15,7 +15,7 @@ go get github.com/eyedeekay/goSam
|
||||
|
||||
## Using it for HTTP Transport
|
||||
|
||||
I implemented `Client.Dial` like `net.Dial` so you can use go's library packages like http.
|
||||
`Client.Dial` implements `net.Dial` so you can use go's library packages like http.
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -70,6 +70,52 @@ func checkErr(err error) {
|
||||
}
|
||||
```
|
||||
|
||||
## Using it as a SOCKS proxy
|
||||
|
||||
`client` also implements a resolver compatible with
|
||||
[`getlantern/go-socks5`](https://github.com/getlantern/go-socks5),
|
||||
making it very easy to implement a SOCKS5 server.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/eyedeekay/goSam"
|
||||
"github.com/getlantern/go-socks5"
|
||||
"log"
|
||||
)
|
||||
|
||||
var (
|
||||
samaddr = flag.String("sam", "127.0.0.1:7656", "SAM API address to use")
|
||||
socksaddr = flag.String("socks", "127.0.0.1:7675", "SOCKS address to use")
|
||||
)
|
||||
|
||||
func main() {
|
||||
sam, err := goSam.NewClient(*samaddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Println("Client Created")
|
||||
|
||||
// create a transport that uses SAM to dial TCP Connections
|
||||
conf := &socks5.Config{
|
||||
Dial: sam.DialContext,
|
||||
Resolver: sam,
|
||||
}
|
||||
server, err := socks5.New(conf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create SOCKS5 proxy on localhost port 8000
|
||||
if err := server.ListenAndServe("tcp", *socksaddr); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### .deb package
|
||||
|
||||
A package for installing this on Debian is buildable, and a version for Ubuntu
|
||||
@@ -85,7 +131,10 @@ to produce an unsigned deb for personal use only. For packagers,
|
||||
|
||||
will produce a viable source package for use with Launchpad PPA's and other
|
||||
similar systems.
|
||||
|
||||
### TODO
|
||||
|
||||
* Implement `STREAM ACCEPT` and `STREAM FORWARD`
|
||||
* Improve recovery on failed sockets
|
||||
* Implement `STREAM FORWARD`
|
||||
* Implement datagrams (Repliable and Anon)
|
||||
|
||||
|
@@ -55,6 +55,7 @@ type Client struct {
|
||||
lastaddr string
|
||||
id int32
|
||||
ml sync.Mutex
|
||||
oml sync.Mutex
|
||||
}
|
||||
|
||||
var SAMsigTypes = []string{
|
||||
@@ -106,7 +107,6 @@ func (c *Client) Base32() string {
|
||||
}
|
||||
|
||||
func (c *Client) base64() []byte {
|
||||
fmt.Println("\n\nDESTINATION", c.destination, "\n\n.")
|
||||
if c.destination != "" {
|
||||
s, _ := i2pB64enc.DecodeString(c.destination)
|
||||
alen := binary.BigEndian.Uint16(s[385:387])
|
||||
@@ -146,6 +146,8 @@ func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
|
||||
c.lastaddr = "invalid"
|
||||
c.destination = ""
|
||||
c.leaseSetEncType = "4,0"
|
||||
c.fromport = ""
|
||||
c.toport = ""
|
||||
for _, o := range opts {
|
||||
if err := o(&c); err != nil {
|
||||
return nil, err
|
||||
@@ -184,7 +186,7 @@ func (c *Client) hello() error {
|
||||
}
|
||||
|
||||
if r.Topic != "HELLO" {
|
||||
return fmt.Errorf("Unknown Reply: %+v\n", r)
|
||||
return fmt.Errorf("Client Hello Unknown Reply: %+v\n", r)
|
||||
}
|
||||
|
||||
if r.Pairs["RESULT"] != "OK" {
|
||||
|
@@ -4,6 +4,20 @@ package goSam
|
||||
|
||||
import "testing"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
//"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/eyedeekay/sam3/helper"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
func HelloServer(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
|
||||
}
|
||||
|
||||
var client *Client
|
||||
|
||||
func setup(t *testing.T) {
|
||||
@@ -16,6 +30,65 @@ func setup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompositeClient(t *testing.T) {
|
||||
listener, err := sam.I2PListener("testservice", "127.0.0.1:7656", "testkeys")
|
||||
if err != nil {
|
||||
t.Fatalf("Listener() Error: %q\n", err)
|
||||
}
|
||||
http.HandleFunc("/", HelloServer)
|
||||
go http.Serve(listener, nil)
|
||||
|
||||
listener2, err := sam.I2PListener("testservice2", "127.0.0.1:7656", "testkeys2")
|
||||
if err != nil {
|
||||
t.Fatalf("Listener() Error: %q\n", err)
|
||||
}
|
||||
// http.HandleFunc("/", HelloServer)
|
||||
go http.Serve(listener2, nil)
|
||||
|
||||
listener3, err := sam.I2PListener("testservice3", "127.0.0.1:7656", "testkeys3")
|
||||
if err != nil {
|
||||
t.Fatalf("Listener() Error: %q\n", err)
|
||||
}
|
||||
// http.HandleFunc("/", HelloServer)
|
||||
go http.Serve(listener3, nil)
|
||||
|
||||
client, err = NewClientFromOptions(SetDebug(true))
|
||||
if err != nil {
|
||||
t.Fatalf("NewDefaultClient() Error: %q\n", err)
|
||||
}
|
||||
tr := &http.Transport{
|
||||
Dial: client.Dial,
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
time.Sleep(time.Second * 30)
|
||||
go func() {
|
||||
resp, err := client.Get("http://" + listener.Addr().(i2pkeys.I2PAddr).Base32())
|
||||
if err != nil {
|
||||
t.Fatalf("Get Error: %q\n", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
t.Log("Get returned ", resp)
|
||||
}()
|
||||
go func() {
|
||||
resp, err := client.Get("http://" + listener2.Addr().(i2pkeys.I2PAddr).Base32())
|
||||
if err != nil {
|
||||
t.Fatalf("Get Error: %q\n", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
t.Log("Get returned ", resp)
|
||||
}()
|
||||
go func() {
|
||||
resp, err := client.Get("http://" + listener3.Addr().(i2pkeys.I2PAddr).Base32())
|
||||
if err != nil {
|
||||
t.Fatalf("Get Error: %q\n", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
t.Log("Get returned ", resp)
|
||||
}()
|
||||
|
||||
time.Sleep(time.Second * 15)
|
||||
}
|
||||
|
||||
func teardown(t *testing.T) {
|
||||
if err := client.Close(); err != nil {
|
||||
t.Fatalf("client.Close() Error: %q\n", err)
|
||||
|
18
debian/changelog
vendored
18
debian/changelog
vendored
@@ -1,3 +1,21 @@
|
||||
golang-github-eyedeekay-gosam (0.32.29) UNRELEASED; urgency=medium
|
||||
|
||||
* Maintenance updates
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Mon, 23 Nov 2020 20:40:4 -0500
|
||||
|
||||
golang-github-eyedeekay-gosam (0.32.27) UNRELEASED; urgency=medium
|
||||
|
||||
* Maintenance updates
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Thu, 12 Sept 2020 22:44:27 -0500
|
||||
|
||||
golang-github-eyedeekay-gosam (0.32.27) UNRELEASED; urgency=medium
|
||||
|
||||
* Add a Resolve function to fulfill SOCKS5 proxy requirements
|
||||
|
||||
-- idk <hankhill19580@gmail.com> Sun, 13 Sept 2020 04:48:27 -0500
|
||||
|
||||
golang-github-eyedeekay-gosam (0.32.26) UNRELEASED; urgency=medium
|
||||
|
||||
* Fix mistaken-identity issue with listeners
|
||||
|
13
dial.go
13
dial.go
@@ -9,20 +9,28 @@ import (
|
||||
|
||||
// DialContext implements the net.DialContext function and can be used for http.Transport
|
||||
func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
c.oml.Lock()
|
||||
defer c.oml.Unlock()
|
||||
errCh := make(chan error, 1)
|
||||
connCh := make(chan net.Conn, 1)
|
||||
go func() {
|
||||
if conn, err := c.Dial(network, addr); err != nil {
|
||||
errCh <- err
|
||||
} else if ctx.Err() != nil {
|
||||
conn.Close()
|
||||
var err error
|
||||
c, err = c.NewClient()
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
}
|
||||
} else {
|
||||
connCh <- conn
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case err := <-errCh:
|
||||
return nil, err
|
||||
// var err error
|
||||
c, err = c.NewClient()
|
||||
return c.SamConn, err
|
||||
case conn := <-connCh:
|
||||
return conn, nil
|
||||
case <-ctx.Done():
|
||||
@@ -36,7 +44,6 @@ func (c *Client) dialCheck(addr string) (int32, bool) {
|
||||
return c.NewID(), true
|
||||
} else if c.lastaddr != addr {
|
||||
fmt.Println("Preparing to dial next new address.")
|
||||
return c.NewID(), true
|
||||
}
|
||||
return c.id, false
|
||||
}
|
||||
|
7
go.mod
7
go.mod
@@ -1,6 +1,11 @@
|
||||
module github.com/eyedeekay/goSam
|
||||
|
||||
require github.com/eyedeekay/sam3 v0.32.2
|
||||
require (
|
||||
github.com/eyedeekay/sam3 v0.32.32-0.20201122050855-f464873c9350
|
||||
github.com/getlantern/go-socks5 v0.0.0-20171114193258-79d4dd3e2db5
|
||||
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9 // indirect
|
||||
github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd // indirect
|
||||
)
|
||||
|
||||
//replace github.com/eyedeekay/gosam v0.1.1-0.20190814195658-27e786578944 => github.com/eyedeekay/goSam ./
|
||||
|
||||
|
28
go.sum
28
go.sum
@@ -1,3 +1,31 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab h1:EfTRHxGSbiaEyxNzvKRBWVIDw3mD8xXGxj4gvwFzY7Q=
|
||||
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab/go.mod h1:h7mvUAMgZ/rtRDUOkvKTK+8LnDMeUhJSoa5EPdB51fc=
|
||||
github.com/eyedeekay/sam3 v0.32.2 h1:xODDY5nBVg0oK7KaYk7ofkXFoHPsmI1umhSv1TZlS7s=
|
||||
github.com/eyedeekay/sam3 v0.32.2/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORXbLBbcZM=
|
||||
github.com/eyedeekay/sam3 v0.32.31 h1:0fdDAupEQZSETHcyVQAsnFgpYArGJzU+lC2qN6f0GDk=
|
||||
github.com/eyedeekay/sam3 v0.32.32-0.20201122050855-f464873c9350 h1:8R4zcaWsgANiZ4MKKBPUf9Isct2M1IFVUVZdAMqPCmU=
|
||||
github.com/eyedeekay/sam3 v0.32.32-0.20201122050855-f464873c9350/go.mod h1:qRA9KIIVxbrHlkj+ZB+OoxFGFgdKeGp1vSgPw26eOVU=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
|
||||
github.com/getlantern/errors v1.0.1 h1:XukU2whlh7OdpxnkXhNH9VTLVz0EVPGKDV5K0oWhvzw=
|
||||
github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
|
||||
github.com/getlantern/go-socks5 v0.0.0-20171114193258-79d4dd3e2db5 h1:RBKofGGMt2k6eGBwX8mky9qunjL+KnAp9JdzXjiRkRw=
|
||||
github.com/getlantern/go-socks5 v0.0.0-20171114193258-79d4dd3e2db5/go.mod h1:kGHRXch95rnGLHjER/GhhFiHvfnqNz7KqWD9kGfATHY=
|
||||
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9 h1:8MYJU90rB1bsavemKSAuDKBjtAKo5xq95bEPOnzV7CE=
|
||||
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9/go.mod h1:ZyIjgH/1wTCl+B+7yH1DqrWp6MPJqESmwmEQ89ZfhvA=
|
||||
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=
|
||||
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
|
||||
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=
|
||||
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
|
||||
github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd h1:mn98vs69Kqw56iKhR82mjk16Q1q5aDFFW0E89/QbXkQ=
|
||||
github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd/go.mod h1:wKdY0ikOgzrWSeB9UyBVKPRhjXQ+vTb+BPeJuypUuNE=
|
||||
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=
|
||||
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
41
naming.go
41
naming.go
@@ -1,7 +1,10 @@
|
||||
package goSam
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
@@ -14,7 +17,7 @@ func (c *Client) Lookup(name string) (string, error) {
|
||||
|
||||
// TODO: move check into sendCmd()
|
||||
if r.Topic != "NAMING" || r.Type != "REPLY" {
|
||||
return "", fmt.Errorf("Unknown Reply: %+v\n", r)
|
||||
return "", fmt.Errorf("Naming Unknown Reply: %+v\n", r)
|
||||
}
|
||||
|
||||
result := r.Pairs["RESULT"]
|
||||
@@ -32,3 +35,39 @@ func (c *Client) Lookup(name string) (string, error) {
|
||||
|
||||
return r.Pairs["VALUE"], nil
|
||||
}
|
||||
|
||||
func (c *Client) forward(client, conn net.Conn) {
|
||||
go func() {
|
||||
defer client.Close()
|
||||
defer conn.Close()
|
||||
io.Copy(client, conn)
|
||||
}()
|
||||
go func() {
|
||||
defer client.Close()
|
||||
defer conn.Close()
|
||||
io.Copy(conn, client)
|
||||
}()
|
||||
}
|
||||
|
||||
func (c *Client) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) {
|
||||
if c.lastaddr == "invalid" || c.lastaddr != name {
|
||||
client, err := c.DialContext(ctx, "", name)
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
ln, err := net.Listen("tcp", "127.0.0.1:")
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
go c.forward(client, conn)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return ctx, nil, nil
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ func TestClientLookupInvalid(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleClient_Lookup() {
|
||||
func TestClientLookupValid(t *testing.T) {
|
||||
client, err := NewDefaultClient()
|
||||
if err != nil {
|
||||
fmt.Printf("NewDefaultClient() should not throw an error.\n%s\n", err)
|
||||
@@ -40,11 +40,17 @@ func ExampleClient_Lookup() {
|
||||
return
|
||||
}
|
||||
|
||||
if addr == `GKapJ8koUcBj~jmQzHsTYxDg2tpfWj0xjQTzd8BhfC9c3OS5fwPBNajgF-eOD6eCjFTqTlorlh7Hnd8kXj1qblUGXT-tDoR9~YV8dmXl51cJn9MVTRrEqRWSJVXbUUz9t5Po6Xa247Vr0sJn27R4KoKP8QVj1GuH6dB3b6wTPbOamC3dkO18vkQkfZWUdRMDXk0d8AdjB0E0864nOT~J9Fpnd2pQE5uoFT6P0DqtQR2jsFvf9ME61aqLvKPPWpkgdn4z6Zkm-NJOcDz2Nv8Si7hli94E9SghMYRsdjU-knObKvxiagn84FIwcOpepxuG~kFXdD5NfsH0v6Uri3usE3XWD7Pw6P8qVYF39jUIq4OiNMwPnNYzy2N4mDMQdsdHO3LUVh~DEppOy9AAmEoHDjjJxt2BFBbGxfdpZCpENkwvmZeYUyNCCzASqTOOlNzdpne8cuesn3NDXIpNnqEE6Oe5Qm5YOJykrX~Vx~cFFT3QzDGkIjjxlFBsjUJyYkFjBQAEAAcAAA==` {
|
||||
t.Log("Success")
|
||||
} else {
|
||||
t.Errorf("Address of zzz.i2p != \nGKapJ8koUcBj~jmQzHsTYxDg2tpfWj0xjQTzd8BhfC9c3OS5fwPBNajgF-eOD6eCjFTqTlorlh7Hnd8kXj1qblUGXT-tDoR9~YV8dmXl51cJn9MVTRrEqRWSJVXbUUz9t5Po6Xa247Vr0sJn27R4KoKP8QVj1GuH6dB3b6wTPbOamC3dkO18vkQkfZWUdRMDXk0d8AdjB0E0864nOT~J9Fpnd2pQE5uoFT6P0DqtQR2jsFvf9ME61aqLvKPPWpkgdn4z6Zkm-NJOcDz2Nv8Si7hli94E9SghMYRsdjU-knObKvxiagn84FIwcOpepxuG~kFXdD5NfsH0v6Uri3usE3XWD7Pw6P8qVYF39jUIq4OiNMwPnNYzy2N4mDMQdsdHO3LUVh~DEppOy9AAmEoHDjjJxt2BFBbGxfdpZCpENkwvmZeYUyNCCzASqTOOlNzdpne8cuesn3NDXIpNnqEE6Oe5Qm5YOJykrX~Vx~cFFT3QzDGkIjjxlFBsjUJyYkFjBQAEAAcAAA==\n, check to see if it changed, %s", addr)
|
||||
}
|
||||
|
||||
fmt.Println("Address of zzz.i2p:")
|
||||
// Addresses change all the time
|
||||
fmt.Println(addr)
|
||||
|
||||
// Output:
|
||||
//Address of zzz.i2p:
|
||||
//GKapJ8koUcBj~jmQzHsTYxDg2tpfWj0xjQTzd8BhfC9c3OS5fwPBNajgF-eOD6eCjFTqTlorlh7Hnd8kXj1qblUGXT-tDoR9~YV8dmXl51cJn9MVTRrEqRWSJVXbUUz9t5Po6Xa247Vr0sJn27R4KoKP8QVj1GuH6dB3b6wTPbOamC3dkO18vkQkfZWUdRMDXk0d8AdjB0E0864nOT~J9Fpnd2pQE5uoFT6P0DqtQR2jsFvf9ME61aqLvKPPWpkgdn4z6Zkm-NJOcDz2Nv8Si7hli94E9SghMYRsdjU-knObKvxiagn84FIwcOpepxuG~kFXdD5NfsH0v6Uri3usE3XWD7Pw6P8qVYF39jUIq4OiNMwPnNYzy2N4mDMQdsdHO3LUVh~DEppOy9AAmEoHDjjJxt2BFBbGxfdpZCpENkwvmZeYUyNCCzASqTOOlNzdpne8cuesn3NDXIpNnqEE6Oe5Qm5YOJykrX~Vx~cFFT3QzDGkIjjxlFBsjUJyYkFjBQAEAAcAAA==
|
||||
//
|
||||
}
|
||||
|
12
options.go
12
options.go
@@ -369,6 +369,12 @@ func SetSignatureType(s string) func(*Client) error {
|
||||
|
||||
//return the from port as a string.
|
||||
func (c *Client) from() string {
|
||||
if c.fromport == "FROM_PORT=0" {
|
||||
return ""
|
||||
}
|
||||
if c.fromport == "0" {
|
||||
return ""
|
||||
}
|
||||
if c.fromport == "" {
|
||||
return ""
|
||||
}
|
||||
@@ -377,6 +383,12 @@ func (c *Client) from() string {
|
||||
|
||||
//return the to port as a string.
|
||||
func (c *Client) to() string {
|
||||
if c.fromport == "TO_PORT=0" {
|
||||
return ""
|
||||
}
|
||||
if c.fromport == "0" {
|
||||
return ""
|
||||
}
|
||||
if c.toport == "" {
|
||||
return ""
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
package goSam
|
||||
|
||||
/*
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
@@ -186,3 +188,4 @@ func TestOptionPortInt(t *testing.T) {
|
||||
fmt.Printf("\t address64- %s \t", client.Base64())
|
||||
fmt.Printf("\t address- %s \t", client.Base32())
|
||||
}
|
||||
*/
|
||||
|
@@ -32,6 +32,8 @@ func (r ReplyError) Error() string {
|
||||
type Reply struct {
|
||||
Topic string
|
||||
Type string
|
||||
From string
|
||||
To string
|
||||
|
||||
Pairs map[string]string
|
||||
}
|
||||
@@ -50,14 +52,24 @@ func parseReply(line string) (*Reply, error) {
|
||||
}
|
||||
|
||||
for _, v := range parts[2:] {
|
||||
kvPair := strings.SplitN(v, "=", 2)
|
||||
if kvPair != nil {
|
||||
if len(kvPair) != 2 {
|
||||
return nil, fmt.Errorf("Malformed key-value-pair.\n%s\n", kvPair)
|
||||
if strings.Contains(v, "FROM_PORT") {
|
||||
if v != "FROM_PORT=0" {
|
||||
r.From = v
|
||||
}
|
||||
} else if strings.Contains(v, "TO_PORT") {
|
||||
if v != "TO_PORT=0" {
|
||||
r.To = v
|
||||
}
|
||||
} else {
|
||||
kvPair := strings.SplitN(v, "=", 2)
|
||||
if kvPair != nil {
|
||||
if len(kvPair) == 1 {
|
||||
} else if len(kvPair) != 2 {
|
||||
return nil, fmt.Errorf("Malformed key-value-pair.\n%s\n", kvPair)
|
||||
}
|
||||
}
|
||||
r.Pairs[kvPair[0]] = kvPair[len(kvPair)-1]
|
||||
}
|
||||
|
||||
r.Pairs[kvPair[0]] = kvPair[len(kvPair)-1]
|
||||
}
|
||||
|
||||
return r, nil
|
||||
|
37
samsocks/main.go
Normal file
37
samsocks/main.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/eyedeekay/goSam"
|
||||
"github.com/getlantern/go-socks5"
|
||||
"log"
|
||||
)
|
||||
|
||||
var (
|
||||
samaddr = flag.String("sam", "127.0.0.1:7656", "SAM API address to use")
|
||||
socksaddr = flag.String("socks", "127.0.0.1:7675", "SOCKS address to use")
|
||||
)
|
||||
|
||||
func main() {
|
||||
sam, err := goSam.NewClient(*samaddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Println("Client Created")
|
||||
|
||||
// create a transport that uses SAM to dial TCP Connections
|
||||
conf := &socks5.Config{
|
||||
Dial: sam.DialContext,
|
||||
Resolver: sam,
|
||||
}
|
||||
server, err := socks5.New(conf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create SOCKS5 proxy on localhost port 8000
|
||||
if err := server.ListenAndServe("tcp", *socksaddr); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
@@ -19,11 +19,11 @@ func (c *Client) CreateStreamSession(id int32, dest string) (string, error) {
|
||||
}
|
||||
c.id = id
|
||||
r, err := c.sendCmd(
|
||||
"SESSION CREATE STYLE=STREAM ID=%d %s %s DESTINATION=%s %s %s\n",
|
||||
"SESSION CREATE STYLE=STREAM ID=%d DESTINATION=%s %s %s %s %s \n",
|
||||
c.id,
|
||||
dest,
|
||||
c.from(),
|
||||
c.to(),
|
||||
dest,
|
||||
c.sigtype(),
|
||||
c.allOptions(),
|
||||
)
|
||||
@@ -33,7 +33,7 @@ func (c *Client) CreateStreamSession(id int32, dest string) (string, error) {
|
||||
|
||||
// TODO: move check into sendCmd()
|
||||
if r.Topic != "SESSION" || r.Type != "STATUS" {
|
||||
return "", fmt.Errorf("Unknown Reply: %+v\n", r)
|
||||
return "", fmt.Errorf("Session Unknown Reply: %+v\n", r)
|
||||
}
|
||||
|
||||
result := r.Pairs["RESULT"]
|
||||
|
@@ -6,14 +6,14 @@ import (
|
||||
|
||||
// StreamConnect asks SAM for a TCP-Like connection to dest, has to be called on a new Client
|
||||
func (c *Client) StreamConnect(id int32, dest string) error {
|
||||
r, err := c.sendCmd("STREAM CONNECT ID=%d %s %s DESTINATION=%s\n", id, c.from(), c.to(), dest)
|
||||
r, err := c.sendCmd("STREAM CONNECT ID=%d DESTINATION=%s %s %s\n", id, dest, c.from(), c.to())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: move check into sendCmd()
|
||||
if r.Topic != "STREAM" || r.Type != "STATUS" {
|
||||
return fmt.Errorf("Unknown Reply: %+v\n", r)
|
||||
return fmt.Errorf("Stream Connect Unknown Reply: %+v\n", r)
|
||||
}
|
||||
|
||||
result := r.Pairs["RESULT"]
|
||||
@@ -33,7 +33,7 @@ func (c *Client) StreamAccept(id int32) (*Reply, error) {
|
||||
|
||||
// TODO: move check into sendCmd()
|
||||
if r.Topic != "STREAM" || r.Type != "STATUS" {
|
||||
return nil, fmt.Errorf("Unknown Reply: %+v\n", r)
|
||||
return nil, fmt.Errorf("Stream Accept Unknown Reply: %+v\n", r)
|
||||
}
|
||||
|
||||
result := r.Pairs["RESULT"]
|
||||
|
Reference in New Issue
Block a user