From 533def6748744789ccd49c36e6cf6c924944c9c4 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Fri, 4 Mar 2022 11:55:08 -0500 Subject: obfsvpn: initial draft library API Signed-off-by: Sam Whited --- listener.go | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 listener.go (limited to 'listener.go') diff --git a/listener.go b/listener.go new file mode 100644 index 0000000..ae81b19 --- /dev/null +++ b/listener.go @@ -0,0 +1,82 @@ +package obfsvpn + +import ( + "bytes" + "context" + "crypto/rand" + "encoding/hex" + "net" + + pt "git.torproject.org/pluggable-transports/goptlib.git" + "gitlab.com/yawning/obfs4.git/common/ntor" + "gitlab.com/yawning/obfs4.git/transports/base" + "gitlab.com/yawning/obfs4.git/transports/obfs4" +) + +// ListenConfig contains options for listening to an address. +// If Seed is not set it defaults to a randomized value. +// If StateDir is not set the current working directory is used. +type ListenConfig struct { + ListenConfig net.ListenConfig + + NodeID *ntor.NodeID + PrivateKey *ntor.PrivateKey + Seed [ntor.KeySeedLength]byte + StateDir string +} + +// Listen announces on the local network address. +// +// See func net.Dial for a description of the network and address parameters. +func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (*Listener, error) { + ln, err := lc.ListenConfig.Listen(ctx, network, address) + if err != nil { + return nil, err + } + args := make(pt.Args) + args.Add("node-id", lc.NodeID.Hex()) + args.Add("private-key", lc.PrivateKey.Hex()) + seed := ntor.KeySeed{} + if bytes.Equal(lc.Seed[:], seed[:]) { + _, err = rand.Read(seed[:]) + if err != nil { + return nil, err + } + } else { + seed = lc.Seed + } + args.Add("drbg-seed", hex.EncodeToString(seed[:])) + sf, err := (&obfs4.Transport{}).ServerFactory(lc.StateDir, &args) + if err != nil { + return nil, err + } + return &Listener{sf: sf, ln: ln}, nil +} + +// Listener is a network listener that accepts obfuscated connections and +// performs the ntor handshake on them. +type Listener struct { + sf base.ServerFactory + ln net.Listener +} + +// Accept waits for and returns the next connection to the listener. +func (l *Listener) Accept() (net.Conn, error) { + conn, err := l.ln.Accept() + if err != nil { + return nil, err + } + conn, err = l.sf.WrapConn(conn) + return conn, err +} + +// Close closes the listener. +// Any blcked Accept operations will be unblocked and return errors. +func (l *Listener) Close() error { + return l.ln.Close() +} + +// Addr returns the listener's network address. +func (l *Listener) Addr() net.Addr { + return l.ln.Addr() +} -- cgit v1.2.3