goSam

package module
v0.32.54 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 18, 2022 License: MIT Imports: 19 Imported by: 15

README

goSam

A go library for using the I2P Simple Anonymous Messaging (SAM version 3.0) bridge. It has support for all streaming features SAM version 3.2.

STATUS: This project is maintained. I will respond to issues, pull requests, and feature requests within a few days. I am primarily maintaining functionality. 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

go get github.com/eyedeekay/goSam

Using it for HTTP Transport

Client.Dial implements net.Dial so you can use go's library packages like http.

package main

import (
	"io"
	"log"
	"net/http"
	"os"

	"github.com/cryptix/goSam"
)

func main() {
	// create a default sam client
	sam, err := goSam.NewDefaultClient()
	checkErr(err)

	log.Println("Client Created")

	// create a transport that uses SAM to dial TCP Connections
	tr := &http.Transport{
		Dial: sam.Dial,
	}

	// create  a client using this transport
	client := &http.Client{Transport: tr}

	// send a get request
	resp, err := client.Get("http://stats.i2p/")
	checkErr(err)
	defer resp.Body.Close()

	log.Printf("Get returned %+v\n", resp)

	// create a file for the response
	file, err := os.Create("stats.html")
	checkErr(err)
	defer file.Close()

	// copy the response to the file
	_, err = io.Copy(file, resp.Body)
	checkErr(err)

	log.Println("Done.")
}

func checkErr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

Using SAM by default, as a proxy for all HTTP Clients used by a Go application

This will make the SAM transport dialer the default for all HTTP clients.

package main

import (
	"io"
	"log"
	"net/http"
	"os"

	"github.com/cryptix/goSam"
)

func main() {
	sam, err := goSam.NewDefaultClient()
	checkErr(err)

	log.Println("Client Created")

	// create a transport that uses SAM to dial TCP Connections
	httpClient := &http.Client{
		Transport: &http.Transport{
			Dial: sam.Dial,
		},
	}

	http.DefaultClient = httpClient
	return nil
}

func checkErr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

Using it as a SOCKS proxy

client also implements a resolver compatible with getlantern/go-socks5, making it very easy to implement a SOCKS5 server.

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 is available as a PPA and mirrored via i2p. To build the deb package, from the root of this repository with the build dependencies installed(git, i2p, go, debuild) run the command

    debuild -us -uc

to produce an unsigned deb for personal use only. For packagers,

    debuild -S

will produce a viable source package for use with Launchpad PPA's and other similar systems.

TODO
  • Improve recovery on failed sockets
  • Implement STREAM FORWARD
  • Implement datagrams (Repliable and Anon)

Documentation

Index

Constants

View Source
const (
	ResultOk             = "OK"              //Operation completed successfully
	ResultCantReachPeer  = "CANT_REACH_PEER" //The peer exists, but cannot be reached
	ResultDuplicatedID   = "DUPLICATED_ID"   //If the nickname is already associated with a session :
	ResultDuplicatedDest = "DUPLICATED_DEST" //The specified Destination is already in use
	ResultI2PError       = "I2P_ERROR"       //A generic I2P error (e.g. I2CP disconnection, etc.)
	ResultInvalidKey     = "INVALID_KEY"     //The specified key is not valid (bad format, etc.)
	ResultKeyNotFound    = "KEY_NOT_FOUND"   //The naming system can't resolve the given name
	ResultPeerNotFound   = "PEER_NOT_FOUND"  //The peer cannot be found on the network
	ResultTimeout        = "TIMEOUT"         // Timeout while waiting for an event (e.g. peer answer)
)

The Possible Results send by SAM

Variables

View Source
var SAMsigTypes = []string{
	"SIGNATURE_TYPE=DSA_SHA1",
	"SIGNATURE_TYPE=ECDSA_SHA256_P256",
	"SIGNATURE_TYPE=ECDSA_SHA384_P384",
	"SIGNATURE_TYPE=ECDSA_SHA512_P521",
	"SIGNATURE_TYPE=EdDSA_SHA512_Ed25519",
}

SAMsigTypes is a slice of the available signature types

View Source
var ValidSAMCommands = []string{
	"HELLO",
	"SESSION",
	"STREAM",
}

Functions

func NewID added in v0.32.6

func NewID() int32

func NewReadHexLogger added in v0.32.4

func NewReadHexLogger(prefix string, r io.Reader) io.Reader

NewReadHexLogger returns a reader that behaves like r except that it logs to stderr using ecoding/hex.

func NewReadLogger added in v0.32.4

func NewReadLogger(prefix string, r io.Reader) io.Reader

NewReadLogger returns a reader that behaves like r except that it logs (using log.Print) each read to standard error, printing the prefix and the hexadecimal data written.

func NewWriteLogger added in v0.32.4

func NewWriteLogger(prefix string, w io.Writer) io.Writer

NewWriteLogger returns a writer that behaves like w except that it logs (using log.Printf) each write to standard error, printing the prefix and the hexadecimal data written.

func SetAddr

func SetAddr(s ...string) func(*Client) error

SetAddr sets a clients's address in the form host:port or host, port

func SetAddrMixed

func SetAddrMixed(s string, i int) func(*Client) error

SetAddrMixed sets a clients's address in the form host, port(int)

func SetCloseIdle

func SetCloseIdle(b bool) func(*Client) error

SetCloseIdle sets the tunnels to close after a specific amount of time

func SetCloseIdleTime

func SetCloseIdleTime(u uint) func(*Client) error

SetCloseIdleTime sets the time in milliseconds to wait before closing tunnels

func SetCompression

func SetCompression(b bool) func(*Client) error

SetCompression sets the tunnels to close after a specific amount of time

func SetDebug

func SetDebug(b bool) func(*Client) error

SetDebug enables debugging messages

func SetEncrypt

func SetEncrypt(b bool) func(*Client) error

SetEncrypt tells the router to use an encrypted leaseset

func SetFromPort

func SetFromPort(s string) func(*Client) error

SetFromPort sets the port of the client's SAM bridge using a string

func SetFromPortInt

func SetFromPortInt(i int) func(*Client) error

SetFromPortInt sets the port of the client's SAM bridge using a string

func SetHost

func SetHost(s string) func(*Client) error

SetHost sets the host of the client's SAM bridge

func SetInBackups

func SetInBackups(u uint) func(*Client) error

SetInBackups sets the inbound tunnel backups

func SetInLength

func SetInLength(u uint) func(*Client) error

SetInLength sets the number of hops inbound

func SetInQuantity

func SetInQuantity(u uint) func(*Client) error

SetInQuantity sets the inbound tunnel quantity

func SetInVariance

func SetInVariance(i int) func(*Client) error

SetInVariance sets the variance of a number of hops inbound

func SetLeaseSetEncType added in v0.32.4

func SetLeaseSetEncType(b string) func(*Client) error

SetLeaseSetEncType tells the router to use an encrypted leaseset of a specific type. defaults to 4,0

func SetLocalDestination

func SetLocalDestination(s string) func(*Client) error

SetLocalDestination sets the local destination of the tunnel from a private key

func SetOutBackups

func SetOutBackups(u uint) func(*Client) error

SetOutBackups sets the inbound tunnel backups

func SetOutLength

func SetOutLength(u uint) func(*Client) error

SetOutLength sets the number of hops outbound

func SetOutQuantity

func SetOutQuantity(u uint) func(*Client) error

SetOutQuantity sets the outbound tunnel quantity

func SetOutVariance

func SetOutVariance(i int) func(*Client) error

SetOutVariance sets the variance of a number of hops outbound

func SetPass added in v0.32.6

func SetPass(s string) func(*Client) error

SetUser sets the password for authentication during the SAM HELLO phase

func SetPort

func SetPort(s string) func(*Client) error

SetPort sets the port of the client's SAM bridge using a string

func SetPortInt

func SetPortInt(i int) func(*Client) error

SetPortInt sets the port of the client's SAM bridge using a string

func SetReduceIdle

func SetReduceIdle(b bool) func(*Client) error

SetReduceIdle sets the created tunnels to be reduced during extended idle time to avoid excessive resource usage

func SetReduceIdleQuantity

func SetReduceIdleQuantity(u uint) func(*Client) error

SetReduceIdleQuantity sets number of tunnels to keep alive during an extended idle period

func SetReduceIdleTime

func SetReduceIdleTime(u uint) func(*Client) error

SetReduceIdleTime sets time to wait before the tunnel quantity is reduced

func SetSAMMaxVersion added in v0.32.4

func SetSAMMaxVersion(i int) func(*Client) error

func SetSAMMinVersion added in v0.32.4

func SetSAMMinVersion(i int) func(*Client) error

func SetSignatureType

func SetSignatureType(s string) func(*Client) error

SetSignatureType tells gosam to pass SAM a signature_type parameter with one of the following values:

"SIGNATURE_TYPE=DSA_SHA1",
"SIGNATURE_TYPE=ECDSA_SHA256_P256",
"SIGNATURE_TYPE=ECDSA_SHA384_P384",
"SIGNATURE_TYPE=ECDSA_SHA512_P521",
"SIGNATURE_TYPE=EdDSA_SHA512_Ed25519",

or an empty string

func SetToPort

func SetToPort(s string) func(*Client) error

SetToPort sets the port of the client's SAM bridge using a string

func SetToPortInt

func SetToPortInt(i int) func(*Client) error

SetToPortInt sets the port of the client's SAM bridge using a string

func SetUnpublished

func SetUnpublished(b bool) func(*Client) error

SetUnpublished tells the router to not publish the client leaseset

func SetUser added in v0.32.6

func SetUser(s string) func(*Client) error

SetUser sets the username for authentication during the SAM HELLO phase

func WrapRWC added in v0.32.4

Types

type Client

type Client struct {
	SamConn   net.Conn       // Control socket
	SamDGConn net.PacketConn // Datagram socket
	// contains filtered or unexported fields
}

A Client represents a single Connection to the SAM bridge

func NewClient

func NewClient(addr string) (*Client, error)

NewClient creates a new client, connecting to a specified port

func NewClientFromOptions

func NewClientFromOptions(opts ...func(*Client) error) (*Client, error)

NewClientFromOptions creates a new client, connecting to a specified port

func NewDefaultClient

func NewDefaultClient() (*Client, error)

NewDefaultClient creates a new client, connecting to the default host:port at localhost:7656

func (*Client) Accept

func (c *Client) Accept() (net.Conn, error)

Accept accepts a connection on a listening goSam.Client(Implements net.Listener) or, if the connection isn't listening yet, just calls AcceptI2P for compatibility with older versions.

func (*Client) AcceptI2P

func (c *Client) AcceptI2P() (net.Conn, error)

AcceptI2P creates a new Client and accepts a connection on it

func (*Client) Addr

func (p *Client) Addr() net.Addr

Addr returns the address of the client as a net.Addr

func (*Client) Base32

func (c *Client) Base32() string

Base32 returns the base32 of the local tunnel

func (*Client) Base64

func (c *Client) Base64() string

Base64 returns the base64 of the local tunnel

func (*Client) Close

func (c *Client) Close() error

Close the underlying socket to SAM

func (*Client) CreateDatagramSession added in v0.32.4

func (c *Client) CreateDatagramSession(dest string) (string, error)

CreateDatagramSession creates a new DATAGRAM Session. Returns the Id for the new Client.

func (*Client) CreateRawSession added in v0.32.4

func (c *Client) CreateRawSession(dest string) (string, error)

CreateRawSession creates a new RAW Session. Returns the Id for the new Client.

func (*Client) CreateSession added in v0.32.4

func (c *Client) CreateSession(style, dest string) (string, error)

CreateSession creates a new Session of type style, with an optional destination. an empty destination is interpreted as "TRANSIENT" Returns the destination for the new Client or an error.

func (*Client) CreateStreamSession

func (c *Client) CreateStreamSession(dest string) (string, error)

CreateStreamSession creates a new STREAM Session. Returns the Id for the new Client.

func (*Client) Destination

func (c *Client) Destination() string

Destination returns the full destination of the local tunnel

func (*Client) Dial

func (c *Client) Dial(network, addr string) (net.Conn, error)

func (*Client) DialContext

func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

DialContext implements the net.DialContext function and can be used for http.Transport

func (*Client) DialContextFree added in v0.32.4

func (c *Client) DialContextFree(network, addr string) (net.Conn, error)

DialContextFree implements the net.Dial function and can be used for http.Transport

func (*Client) DialDatagramContextFree added in v0.32.4

func (c *Client) DialDatagramContextFree(addr string) (*DatagramConn, error)

DialDatagramContextFree is a "Dialer" for "Client-Like" Datagram connections. It is also not finished. If you need datagram support right now, use sam3.

func (*Client) DialStreamingContextFree added in v0.32.4

func (c *Client) DialStreamingContextFree(addr string) (net.Conn, error)

DialStreamingContextFree is a "Dialer" for "Client-Like" Streaming connections.

func (*Client) ID

func (p *Client) ID() string

ID returns a the current ID of the client as a string

func (*Client) Listen

func (c *Client) Listen() (net.Listener, error)

Listen creates a new Client and returns a net.listener which *must* be started with Accept

func (*Client) ListenI2P

func (c *Client) ListenI2P(dest string) (net.Listener, error)

ListenI2P creates a new Client and returns a net.listener which *must* be started with Accept

func (*Client) LocalAddr added in v0.32.4

func (p *Client) LocalAddr() net.Addr

func (*Client) Lookup

func (c *Client) Lookup(name string) (string, error)

Lookup askes SAM for the internal i2p address from name

func (*Client) NewClient

func (c *Client) NewClient(id int32) (*Client, error)

NewClient generates an exact copy of the client with the same options, but re-does all the handshaky business so that Dial can pick up right where it left off, should the need arise.

func (*Client) NewDestination added in v0.32.4

func (c *Client) NewDestination(kind ...string) (string, string, error)

Generate a new destination and return the base64 encoded string

func (*Client) NewID

func (c *Client) NewID() int32

NewID generates a random number to use as an tunnel name

func (*Client) Print

func (c *Client) Print() string

Print return all options as string

func (*Client) PrivateAddr added in v0.32.6

func (p *Client) PrivateAddr() i2pkeys.I2PKeys

LocalKeys returns the local keys of the client as a fully-fledged i2pkeys.I2PKeys

func (*Client) RemoveAuthUser added in v0.32.6

func (c *Client) RemoveAuthUser(user string) error

func (*Client) Resolve added in v0.32.4

func (c *Client) Resolve(ctx context.Context, name string) (context.Context, net.IP, error)

func (*Client) SetupAuth added in v0.32.6

func (c *Client) SetupAuth(user, password string) error

SetupAuth sends the AUTH ENABLE command and immediately sets up a new Username and Password from the arguments

func (*Client) StreamAccept

func (c *Client) StreamAccept() (*Reply, error)

StreamAccept asks SAM to accept a TCP-Like connection

func (*Client) StreamConnect

func (c *Client) StreamConnect(dest string) error

StreamConnect asks SAM for a TCP-Like connection to dest, has to be called on a new Client

func (*Client) TeardownAuth added in v0.32.6

func (c *Client) TeardownAuth() error

TeardownAuth sends the AUTH DISABLE command but does not remove the Username and Password from the client PasswordManager

type Conn added in v0.32.2

type Conn struct {
	RWC
	// contains filtered or unexported fields
}

Conn Read data from the connection, writes data to te connection and logs the data in-between.

func WrapConn added in v0.32.2

func WrapConn(c net.Conn) *Conn

WrapConn wraps a net.Conn in a Conn.

func WrapPacketConn added in v0.32.6

func WrapPacketConn(c net.Conn) *Conn

WrapConn wraps a net.PacketConn in a DatagramConn.

func (*Conn) LocalAddr added in v0.32.2

func (c *Conn) LocalAddr() net.Addr

LocalAddr returns the local address of the connection.

func (*Conn) RemoteAddr added in v0.32.2

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr returns the remote address of the connection.

func (*Conn) SetDeadline added in v0.32.2

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline sets the read and write deadlines associated with the connection

func (*Conn) SetReadDeadline added in v0.32.2

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline associated with the connection

func (*Conn) SetWriteDeadline added in v0.32.2

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the write deadline associated with the connection

type DatagramConn added in v0.32.4

type DatagramConn struct {
	RWC

	RAddr net.Addr
	// contains filtered or unexported fields
}

DatagramConn

func (*DatagramConn) Close added in v0.32.4

func (d *DatagramConn) Close() error

func (*DatagramConn) LocalAddr added in v0.32.4

func (d *DatagramConn) LocalAddr() net.Addr

func (*DatagramConn) Read added in v0.32.4

func (d *DatagramConn) Read(b []byte) (n int, err error)

func (*DatagramConn) ReadFrom added in v0.32.4

func (d *DatagramConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)

func (*DatagramConn) RemoteAddr added in v0.32.4

func (d *DatagramConn) RemoteAddr() net.Addr

func (*DatagramConn) SetDeadline added in v0.32.4

func (d *DatagramConn) SetDeadline(t time.Time) error

func (*DatagramConn) SetReadDeadline added in v0.32.4

func (d *DatagramConn) SetReadDeadline(t time.Time) error

func (*DatagramConn) SetWriteDeadline added in v0.32.4

func (d *DatagramConn) SetWriteDeadline(t time.Time) error

func (*DatagramConn) Write added in v0.32.4

func (d *DatagramConn) Write(b []byte) (n int, err error)

func (*DatagramConn) WriteTo added in v0.32.4

func (d *DatagramConn) WriteTo(p []byte, addr net.Addr) (n int, err error)

type Option

type Option func(*Client) error

Option is a client Option

type RWC added in v0.32.4

type RWC struct {
	io.Reader
	io.Writer
	// contains filtered or unexported fields
}

func (*RWC) Close added in v0.32.4

func (c *RWC) Close() error

type Reply

type Reply struct {
	Topic string
	Type  string
	From  string
	To    string

	Pairs map[string]string
}

Reply is the parsed result of a SAM command, containing a map of all the key-value pairs

type ReplyError

type ReplyError struct {
	Result string
	Reply  *Reply
}

A ReplyError is a custom error type, containing the Result and full Reply

func (ReplyError) Error

func (r ReplyError) Error() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL