From 5aced460203e9c5f7c7db42548e5f0d6df4e62a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2020 06:12:04 +0000 Subject: [PATCH 1/5] Bump lodash from 4.17.15 to 4.17.19 in /client Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] --- client/yarn.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/yarn.lock b/client/yarn.lock index e4c05046..ef760499 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -6489,8 +6489,9 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" From b92a9d2e5b0c0c818774df62089ee4df08ec95b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ken-H=C3=A5vard=20Lieng?= Date: Thu, 30 Jul 2020 09:29:50 +0200 Subject: [PATCH 2/5] Update vendor --- go.mod | 1 - go.sum | 1 - vendor/github.com/eyedeekay/goSam/.gitignore | 24 + .../eyedeekay/goSam/CONTRIBUTING.md | 195 +++++++ vendor/github.com/eyedeekay/goSam/LICENSE | 22 + vendor/github.com/eyedeekay/goSam/Makefile | 24 + vendor/github.com/eyedeekay/goSam/README.md | 91 ++++ vendor/github.com/eyedeekay/goSam/accept.go | 63 +++ vendor/github.com/eyedeekay/goSam/client.go | 233 ++++++++ vendor/github.com/eyedeekay/goSam/conn.go | 68 +++ vendor/github.com/eyedeekay/goSam/dial.go | 73 +++ vendor/github.com/eyedeekay/goSam/go.mod | 11 + vendor/github.com/eyedeekay/goSam/go.sum | 3 + vendor/github.com/eyedeekay/goSam/naming.go | 34 ++ vendor/github.com/eyedeekay/goSam/options.go | 507 ++++++++++++++++++ .../github.com/eyedeekay/goSam/replyParser.go | 64 +++ vendor/github.com/eyedeekay/goSam/rw.go | 101 ++++ vendor/github.com/eyedeekay/goSam/rwc.go | 80 +++ vendor/github.com/eyedeekay/goSam/sessions.go | 45 ++ vendor/github.com/eyedeekay/goSam/stream.go | 45 ++ vendor/modules.txt | 2 - 21 files changed, 1683 insertions(+), 4 deletions(-) create mode 100644 vendor/github.com/eyedeekay/goSam/.gitignore create mode 100644 vendor/github.com/eyedeekay/goSam/CONTRIBUTING.md create mode 100644 vendor/github.com/eyedeekay/goSam/LICENSE create mode 100644 vendor/github.com/eyedeekay/goSam/Makefile create mode 100644 vendor/github.com/eyedeekay/goSam/README.md create mode 100644 vendor/github.com/eyedeekay/goSam/accept.go create mode 100644 vendor/github.com/eyedeekay/goSam/client.go create mode 100644 vendor/github.com/eyedeekay/goSam/conn.go create mode 100644 vendor/github.com/eyedeekay/goSam/dial.go create mode 100644 vendor/github.com/eyedeekay/goSam/go.mod create mode 100644 vendor/github.com/eyedeekay/goSam/go.sum create mode 100644 vendor/github.com/eyedeekay/goSam/naming.go create mode 100644 vendor/github.com/eyedeekay/goSam/options.go create mode 100644 vendor/github.com/eyedeekay/goSam/replyParser.go create mode 100644 vendor/github.com/eyedeekay/goSam/rw.go create mode 100644 vendor/github.com/eyedeekay/goSam/rwc.go create mode 100644 vendor/github.com/eyedeekay/goSam/sessions.go create mode 100644 vendor/github.com/eyedeekay/goSam/stream.go diff --git a/go.mod b/go.mod index 98ddbd15..949c2667 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,6 @@ require ( github.com/cznic/strutil v0.0.0-20181122101858-275e90344537 // indirect github.com/dsnet/compress v0.0.1 github.com/eyedeekay/goSam v0.32.22 - github.com/eyedeekay/sam3 v0.32.3 // indirect github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect diff --git a/go.sum b/go.sum index 6add93a1..c63e79cd 100644 --- a/go.sum +++ b/go.sum @@ -142,7 +142,6 @@ github.com/eyedeekay/goSam v0.32.22 h1:SD0GEQ8MGJ1wZ4MepSa0mpZjiZAGMSTUhSwAZVrm2 github.com/eyedeekay/goSam v0.32.22/go.mod h1:YIklxqKiJ3I5JNRgb5pM7VCQOSNDGnVulHnrKBbbECM= github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab/go.mod h1:h7mvUAMgZ/rtRDUOkvKTK+8LnDMeUhJSoa5EPdB51fc= github.com/eyedeekay/sam3 v0.32.2/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORXbLBbcZM= -github.com/eyedeekay/sam3 v0.32.3/go.mod h1:qRA9KIIVxbrHlkj+ZB+OoxFGFgdKeGp1vSgPw26eOVU= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= diff --git a/vendor/github.com/eyedeekay/goSam/.gitignore b/vendor/github.com/eyedeekay/goSam/.gitignore new file mode 100644 index 00000000..d3bdc127 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +itp-golang-github-eyedeekay-gosam.txt +.pc diff --git a/vendor/github.com/eyedeekay/goSam/CONTRIBUTING.md b/vendor/github.com/eyedeekay/goSam/CONTRIBUTING.md new file mode 100644 index 00000000..6df463c6 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/CONTRIBUTING.md @@ -0,0 +1,195 @@ +How to make contributions to goSam +================================== + +Welcome to goSam, the easy-to-use http client for i2p. We're glad you're here +and interested in contributing. Here's some help getting started. + +Table of Contents +----------------- + + * (1) Environment + * (2) Testing + * (3) Filing Issues/Reporting Bugs/Making Suggestions + * (4) Contributing Code/Style Guide + - (a) Adding i2cp and tunnel Options + - (b) Writing Tests + - (c) Style + - (d) Other kinds of modification? + * (5) Conduct + +### (1) Environment + +goSam is a simple go library. You are free to use an IDE if you wish, but all +that is required to build and test the library are a go compiler and the gofmt +tool. Git is the version control system. All the files in the library are in a +single root directory. Invoking go build from this directory not generate any +files. + +### (2) Testing + +Tests are implemented using the standard go "testing" library in files named +"file\_test.go," so tests of the client go in client\_test.go, name lookups +in naming\_test.go, et cetera. Everything that can be tested, should be tested. + +Testing is done by running + + go test + +More information about designing tests is below in the +**Contributing Code/Style Guide** section below. + +### (3) Filing issues/Reporting bugs/Making suggestions + +If you discover the library doing something you don't think is right, please let +us know! Just filing an issue here is OK. + +If you need to suggest a feature, we're happy to hear from you too. Filing an +issue will give us a place to discuss how it's implemented openly and publicly. + +Please file an issue for your new code contributions in order to provide us with +a place to discuss them for inclusion. + +### (4) Contributing Code/Style Guide + +Welcome new coders. We have good news for you, this library is really easy to +contribute to. The easiest contributions take the form of i2cp and tunnel +options. + +#### (a) Adding i2cp and tunnel Options + +First, add a variable to store the state of your new option. For example, the +existing variables are in the Client class [here:](https://github.com/cryptix/goSam/blob/701d7fcf03ddb354262fe213163dcf6f202a24f1/client.go#L29) + +i2cp and tunnel options are added in a highly uniform process of basically three +steps. First, you create a functional argument in the options.go file, in the +form: + +``` Go + // SetOPTION sets $OPTION + func SetOPTION(arg type) func(*Client) error { // arg type + return func(c *Client) error { // pass a client to the inner function and declare error return function + if arg == valid { // validate the argument + c.option = s // set the variable to the argument value + return nil // if option is set successfully return nil error + } + return fmt.Errorf("Invalid argument:" arg) // return a descriptive error if arg is invalid + } + } +``` + +[example](https://github.com/cryptix/goSam/blob/701d7fcf03ddb354262fe213163dcf6f202a24f1/options.go#L187) + +Next, you create a getter which prepares the option. Regardless of the type of +option that is set, these must return strings representing valid i2cp options. + +``` Go + //return the OPTION as a string. + func (c *Client) option() string { + return fmt.Sprintf("i2cp.option=%d", c.option) + } +``` + +[example](https://github.com/cryptix/goSam/blob/701d7fcf03ddb354262fe213163dcf6f202a24f1/options.go#L299) + +Lastly, you'll need to add it to the allOptions function and the +Client.NewClient() function. To add it to allOptions, it looks like this: + +``` Go + //return all options as string ready for passing to sendcmd + func (c *Client) allOptions() string { + return c.inlength() + " " + + c.outlength() + " " + + ... //other options removed from example for brevity + c.option() + } +``` + +``` Go + //return all options as string ready for passing to sendcmd + func (c *Client) NewClient() (*Client, error) { + return NewClientFromOptions( + SetHost(c.host), + SetPort(c.port), + ... //other options removed from example for brevity + SetCompression(c.compression), + setlastaddr(c.lastaddr), + setid(c.id), + ) + } +``` + +[example](https://github.com/cryptix/goSam/blob/701d7fcf03ddb354262fe213163dcf6f202a24f1/options.go#L333) + +#### (b) Writing Tests + +Before the feature can be added, you'll need to add a test for it to +options_test.go. To do this, just add your new option to the long TestOptions +functions in options_test.go. + +``` Go + func TestOptionHost(t *testing.T) { + client, err := NewClientFromOptions( + SetHost("127.0.0.1"), + SetPort("7656"), + ... //other options removed from example for brevity + SetCloseIdleTime(300001), + ) + if err != nil { + t.Fatalf("NewClientFromOptions() Error: %q\n", err) + } + if result, err := client.validCreate(); err != nil { + t.Fatalf(err.Error()) + } else { + t.Log(result) + } + client.CreateStreamSession("") + if err := client.Close(); err != nil { + t.Fatalf("client.Close() Error: %q\n", err) + } + } + + func TestOptionPortInt(t *testing.T) { + client, err := NewClientFromOptions( + SetHost("127.0.0.1"), + SetPortInt(7656), + ... //other options removed from example for brevity + SetUnpublished(true), + ) + if err != nil { + t.Fatalf("NewClientFromOptions() Error: %q\n", err) + } + if result, err := client.validCreate(); err != nil { + t.Fatalf(err.Error()) + } else { + t.Log(result) + } + client.CreateStreamSession("") + if err := client.Close(); err != nil { + t.Fatalf("client.Close() Error: %q\n", err) + } + } + +``` + +If any of these tasks fail, then the test should fail. + +#### (c) Style + +It's pretty simple to make sure the code style is right, just run gofmt over it +to adjust the indentation, and golint over it to ensure that your comments are +of the correct form for the documentation generator. + +#### (d) Other kinds of modification? + +It may be useful to extend goSam in other ways. Since there's not a +one-size-fits-all uniform way of dealing with these kinds of changes, open an +issue for discussion and + +### (5) Conduct + +This is a small-ish, straightforward library intended to enable a clear +technical task. We should be able to be civil with eachother, and give and +accept criticism contructively and respectfully. + +This document was drawn from the examples given by Mozilla +[here](mozillascience.github.io/working-open-workshop/contributing/) diff --git a/vendor/github.com/eyedeekay/goSam/LICENSE b/vendor/github.com/eyedeekay/goSam/LICENSE new file mode 100644 index 00000000..e870cb4c --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Henry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/eyedeekay/goSam/Makefile b/vendor/github.com/eyedeekay/goSam/Makefile new file mode 100644 index 00000000..3da96d0a --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/Makefile @@ -0,0 +1,24 @@ + +USER_GH=eyedeekay +VERSION=0.32.22 +packagename=gosam + +echo: + @echo "type make version to do release $(VERSION)" + +version: + gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(packagename) -t v$(VERSION) -d "version $(VERSION)" + +del: + gothub delete -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(packagename) -t v$(VERSION) + +tar: + tar --exclude .git \ + --exclude .go \ + --exclude bin \ + --exclude examples \ + -cJvf ../$(packagename)_$(VERSION).orig.tar.xz . + +link: + rm -f ../goSam + ln -sf . ../goSam diff --git a/vendor/github.com/eyedeekay/goSam/README.md b/vendor/github.com/eyedeekay/goSam/README.md new file mode 100644 index 00000000..1ec32ff7 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/README.md @@ -0,0 +1,91 @@ +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. + +This is in an **early development stage**. I would love to hear about any +issues or ideas for improvement. + +## Installation +``` +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. + +```go +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) + } +} +``` + +### .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 + +* Implement `STREAM ACCEPT` and `STREAM FORWARD` +* Implement datagrams (Repliable and Anon) diff --git a/vendor/github.com/eyedeekay/goSam/accept.go b/vendor/github.com/eyedeekay/goSam/accept.go new file mode 100644 index 00000000..95310400 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/accept.go @@ -0,0 +1,63 @@ +package goSam + +import ( + "fmt" + "net" +) + +// AcceptI2P creates a new Client and accepts a connection on it +func (c *Client) AcceptI2P() (net.Conn, error) { + listener, err := c.Listen() + if err != nil { + return nil, err + } + return listener.Accept() +} + +// Listen creates a new Client and returns a net.listener which *must* be started +// with Accept +func (c *Client) Listen() (net.Listener, error) { + return c.ListenI2P(c.destination) +} + +// ListenI2P creates a new Client and returns a net.listener which *must* be started +// with Accept +func (c *Client) ListenI2P(dest string) (net.Listener, error) { + var err error + var id int32 + c.id = c.NewID() + c.destination, err = c.CreateStreamSession(id, dest) + if err != nil { + return nil, err + } + + fmt.Println("destination:", c.destination) + + c, err = c.NewClient() + if err != nil { + return nil, err + } + + if c.debug { + c.SamConn = WrapConn(c.SamConn) + } + + return c, nil +} + +// 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 (c *Client) Accept() (net.Conn, error) { + if c.id == 0 { + return c.AcceptI2P() + } + resp, err := c.StreamAccept(c.id) + if err != nil { + return nil, err + } + + fmt.Println("Accept Resp:", resp) + + return c.SamConn, nil +} diff --git a/vendor/github.com/eyedeekay/goSam/client.go b/vendor/github.com/eyedeekay/goSam/client.go new file mode 100644 index 00000000..d97ac36f --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/client.go @@ -0,0 +1,233 @@ +package goSam + +import ( + "bufio" + "crypto/sha256" + "encoding/base32" + "encoding/base64" + "encoding/binary" + "fmt" + "math" + "math/rand" + "net" + "strings" +) + +// A Client represents a single Connection to the SAM bridge +type Client struct { + host string + port string + fromport string + toport string + + SamConn net.Conn + rd *bufio.Reader + + sigType string + destination string + + inLength uint + inVariance int + inQuantity uint + inBackups uint + + outLength uint + outVariance int + outQuantity uint + outBackups uint + + dontPublishLease bool + encryptLease bool + + reduceIdle bool + reduceIdleTime uint + reduceIdleQuantity uint + + closeIdle bool + closeIdleTime uint + + compression bool + + debug bool + //NEVER, EVER modify lastaddr or id yourself. They are used internally only. + lastaddr string + id int32 +} + +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", +} + +var ( + i2pB64enc *base64.Encoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~") + i2pB32enc *base32.Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567") +) + +// NewDefaultClient creates a new client, connecting to the default host:port at localhost:7656 +func NewDefaultClient() (*Client, error) { + return NewClient("localhost:7656") +} + +// NewClient creates a new client, connecting to a specified port +func NewClient(addr string) (*Client, error) { + return NewClientFromOptions(SetAddr(addr)) +} + +// NewID generates a random number to use as an tunnel name +func (c *Client) NewID() int32 { + return rand.Int31n(math.MaxInt32) +} + +// Destination returns the full destination of the local tunnel +func (c *Client) Destination() string { + return c.destination +} + +// Base32 returns the base32 of the local tunnel +func (c *Client) Base32() string { + hash := sha256.New() + b64, err := i2pB64enc.DecodeString(c.Base64()) + if err != nil { + return "" + } + hash.Write([]byte(b64)) + return strings.ToLower(strings.Replace(i2pB32enc.EncodeToString(hash.Sum(nil)), "=", "", -1)) +} + +func (c *Client) base64() []byte { + if c.destination != "" { + s, _ := i2pB64enc.DecodeString(c.destination) + alen := binary.BigEndian.Uint16(s[385:387]) + return s[:387+alen] + } + return []byte("") +} + +// Base64 returns the base64 of the local tunnel +func (c *Client) Base64() string { + return i2pB64enc.EncodeToString(c.base64()) +} + +// NewClientFromOptions creates a new client, connecting to a specified port +func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) { + var c Client + c.host = "127.0.0.1" + c.port = "7656" + c.inLength = 3 + c.inVariance = 0 + c.inQuantity = 1 + c.inBackups = 1 + c.outLength = 3 + c.outVariance = 0 + c.outQuantity = 1 + c.outBackups = 1 + c.dontPublishLease = true + c.encryptLease = false + c.reduceIdle = false + c.reduceIdleTime = 300000 + c.reduceIdleQuantity = 1 + c.closeIdle = true + c.closeIdleTime = 600000 + c.debug = true + c.sigType = SAMsigTypes[4] + c.id = 0 + c.lastaddr = "invalid" + c.destination = "" + for _, o := range opts { + if err := o(&c); err != nil { + return nil, err + } + } + conn, err := net.Dial("tcp", c.samaddr()) + if err != nil { + return nil, err + } + if c.debug { + conn = WrapConn(conn) + } + c.SamConn = conn + c.rd = bufio.NewReader(conn) + return &c, c.hello() +} + +func (p *Client) ID() string { + return fmt.Sprintf("%d", p.id) +} + +func (p *Client) Addr() net.Addr { + return nil +} + +//return the combined host:port of the SAM bridge +func (c *Client) samaddr() string { + return fmt.Sprintf("%s:%s", c.host, c.port) +} + +// send the initial handshake command and check that the reply is ok +func (c *Client) hello() error { + r, err := c.sendCmd("HELLO VERSION MIN=3.0 MAX=3.2\n") + if err != nil { + return err + } + + if r.Topic != "HELLO" { + return fmt.Errorf("Unknown Reply: %+v\n", r) + } + + if r.Pairs["RESULT"] != "OK" { + return fmt.Errorf("Handshake did not succeed\nReply:%+v\n", r) + } + + return nil +} + +// helper to send one command and parse the reply by sam +func (c *Client) sendCmd(str string, args ...interface{}) (*Reply, error) { + if _, err := fmt.Fprintf(c.SamConn, str, args...); err != nil { + return nil, err + } + + line, err := c.rd.ReadString('\n') + if err != nil { + return nil, err + } + + return parseReply(line) +} + +// Close the underlying socket to SAM +func (c *Client) Close() error { + c.rd = nil + return c.SamConn.Close() +} + +// NewClient generates an exact copy of the client with the same options +func (c *Client) NewClient() (*Client, error) { + return NewClientFromOptions( + SetHost(c.host), + SetPort(c.port), + SetDebug(c.debug), + SetInLength(c.inLength), + SetOutLength(c.outLength), + SetInVariance(c.inVariance), + SetOutVariance(c.outVariance), + SetInQuantity(c.inQuantity), + SetOutQuantity(c.outQuantity), + SetInBackups(c.inBackups), + SetOutBackups(c.outBackups), + SetUnpublished(c.dontPublishLease), + SetEncrypt(c.encryptLease), + SetReduceIdle(c.reduceIdle), + SetReduceIdleTime(c.reduceIdleTime), + SetReduceIdleQuantity(c.reduceIdleQuantity), + SetCloseIdle(c.closeIdle), + SetCloseIdleTime(c.closeIdleTime), + SetCompression(c.compression), + setlastaddr(c.lastaddr), + setid(c.id), + ) +} diff --git a/vendor/github.com/eyedeekay/goSam/conn.go b/vendor/github.com/eyedeekay/goSam/conn.go new file mode 100644 index 00000000..798bb953 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/conn.go @@ -0,0 +1,68 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Henry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package goSam + +import ( + "log" + "net" + "time" +) + +type Conn struct { + RWC + conn net.Conn +} + +func WrapConn(c net.Conn) *Conn { + wrap := Conn{ + conn: c, + } + wrap.Reader = NewReadLogger("<", c) + wrap.Writer = NewWriteLogger(">", c) + wrap.RWC.c = c + return &wrap +} + +func (c *Conn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +func (c *Conn) RemoteAddr() net.Addr { + return c.conn.RemoteAddr() +} + +func (c *Conn) SetDeadline(t time.Time) error { + log.Println("WARNING: SetDeadline() not sure this works") + return c.conn.SetDeadline(t) +} + +func (c *Conn) SetReadDeadline(t time.Time) error { + log.Println("WARNING: SetReadDeadline() not sure this works") + return c.conn.SetReadDeadline(t) +} +func (c *Conn) SetWriteDeadline(t time.Time) error { + log.Println("WARNING: SetWriteDeadline() not sure this works") + return c.conn.SetWriteDeadline(t) +} diff --git a/vendor/github.com/eyedeekay/goSam/dial.go b/vendor/github.com/eyedeekay/goSam/dial.go new file mode 100644 index 00000000..2e11829a --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/dial.go @@ -0,0 +1,73 @@ +package goSam + +import ( + "context" + "fmt" + "net" + "strings" +) + +// 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) { + 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() + } else { + connCh <- conn + } + }() + select { + case err := <-errCh: + return nil, err + case conn := <-connCh: + return conn, nil + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +func (c Client) dialCheck(addr string) (int32, bool) { + if c.lastaddr == "invalid" { + fmt.Println("Preparing to dial new address.") + 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 +} + +// Dial implements the net.Dial function and can be used for http.Transport +func (c *Client) Dial(network, addr string) (net.Conn, error) { + portIdx := strings.Index(addr, ":") + if portIdx >= 0 { + addr = addr[:portIdx] + } + addr, err := c.Lookup(addr) + if err != nil { + return nil, err + } + + var test bool + if c.id, test = c.dialCheck(addr); test == true { + c.destination, err = c.CreateStreamSession(c.id, c.destination) + if err != nil { + return nil, err + } + c.lastaddr = addr + } + c, err = c.NewClient() + if err != nil { + return nil, err + } + + err = c.StreamConnect(c.id, addr) + if err != nil { + return nil, err + } + return c.SamConn, nil +} diff --git a/vendor/github.com/eyedeekay/goSam/go.mod b/vendor/github.com/eyedeekay/goSam/go.mod new file mode 100644 index 00000000..159bc0aa --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/go.mod @@ -0,0 +1,11 @@ +module github.com/eyedeekay/goSam + +require github.com/eyedeekay/sam3 v0.32.2 + +//replace github.com/eyedeekay/gosam v0.1.1-0.20190814195658-27e786578944 => github.com/eyedeekay/goSam ./ + +replace github.com/eyedeekay/gosam v0.32.1 => ./ + +replace github.com/eyedeekay/goSam v0.32.1 => ./ + +go 1.13 diff --git a/vendor/github.com/eyedeekay/goSam/go.sum b/vendor/github.com/eyedeekay/goSam/go.sum new file mode 100644 index 00000000..6f9cf05b --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/go.sum @@ -0,0 +1,3 @@ +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= diff --git a/vendor/github.com/eyedeekay/goSam/naming.go b/vendor/github.com/eyedeekay/goSam/naming.go new file mode 100644 index 00000000..b47f7908 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/naming.go @@ -0,0 +1,34 @@ +package goSam + +import ( + "fmt" + "os" +) + +// Lookup askes SAM for the internal i2p address from name +func (c *Client) Lookup(name string) (string, error) { + r, err := c.sendCmd("NAMING LOOKUP NAME=%s\n", name) + if err != nil { + return "", nil + } + + // TODO: move check into sendCmd() + if r.Topic != "NAMING" || r.Type != "REPLY" { + return "", fmt.Errorf("Unknown Reply: %+v\n", r) + } + + result := r.Pairs["RESULT"] + if result != "OK" { + return "", ReplyError{result, r} + } + + if r.Pairs["NAME"] != name { + // somehow different on i2pd + if r.Pairs["NAME"] != "ME" { + return "", fmt.Errorf("Lookup() Replyed to another name.\nWanted:%s\nGot: %+v\n", name, r) + } + fmt.Fprintln(os.Stderr, "WARNING: Lookup() Replyed to another name. assuming i2pd c++ fluke") + } + + return r.Pairs["VALUE"], nil +} diff --git a/vendor/github.com/eyedeekay/goSam/options.go b/vendor/github.com/eyedeekay/goSam/options.go new file mode 100644 index 00000000..ba2af83e --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/options.go @@ -0,0 +1,507 @@ +package goSam + +import ( + "fmt" + "strconv" + "strings" +) + +//Option is a client Option +type Option func(*Client) error + +//SetAddr sets a clients's address in the form host:port or host, port +func SetAddr(s ...string) func(*Client) error { + return func(c *Client) error { + if len(s) == 1 { + split := strings.SplitN(s[0], ":", 2) + if len(split) == 2 { + if i, err := strconv.Atoi(split[1]); err == nil { + if i < 65536 { + c.host = split[0] + c.port = split[1] + return nil + } + return fmt.Errorf("Invalid port") + } + return fmt.Errorf("Invalid port; non-number") + } + return fmt.Errorf("Invalid address; use host:port %s", split) + } else if len(s) == 2 { + if i, err := strconv.Atoi(s[1]); err == nil { + if i < 65536 { + c.host = s[0] + c.port = s[1] + return nil + } + return fmt.Errorf("Invalid port") + } + return fmt.Errorf("Invalid port; non-number") + } else { + return fmt.Errorf("Invalid address") + } + } +} + +//SetAddrMixed sets a clients's address in the form host, port(int) +func SetAddrMixed(s string, i int) func(*Client) error { + return func(c *Client) error { + if i < 65536 && i > 0 { + c.host = s + c.port = strconv.Itoa(i) + return nil + } + return fmt.Errorf("Invalid port") + } +} + +//SetHost sets the host of the client's SAM bridge +func SetHost(s string) func(*Client) error { + return func(c *Client) error { + c.host = s + return nil + } +} + +//SetLocalDestination sets the local destination of the tunnel from a private +//key +func SetLocalDestination(s string) func(*Client) error { + return func(c *Client) error { + c.destination = s + return nil + } +} + +func setlastaddr(s string) func(*Client) error { + return func(c *Client) error { + c.lastaddr = s + return nil + } +} + +func setid(s int32) func(*Client) error { + return func(c *Client) error { + c.id = s + return nil + } +} + +//SetPort sets the port of the client's SAM bridge using a string +func SetPort(s string) func(*Client) error { + return func(c *Client) error { + port, err := strconv.Atoi(s) + if err != nil { + return fmt.Errorf("Invalid port; non-number") + } + if port < 65536 && port > -1 { + c.port = s + return nil + } + return fmt.Errorf("Invalid port") + } +} + +//SetPortInt sets the port of the client's SAM bridge using a string +func SetPortInt(i int) func(*Client) error { + return func(c *Client) error { + if i < 65536 && i > -1 { + c.port = strconv.Itoa(i) + return nil + } + return fmt.Errorf("Invalid port") + } +} + +//SetFromPort sets the port of the client's SAM bridge using a string +func SetFromPort(s string) func(*Client) error { + return func(c *Client) error { + port, err := strconv.Atoi(s) + if err != nil { + return fmt.Errorf("Invalid port; non-number") + } + if port < 65536 && port > -1 { + c.fromport = s + return nil + } + return fmt.Errorf("Invalid port") + } +} + +//SetFromPortInt sets the port of the client's SAM bridge using a string +func SetFromPortInt(i int) func(*Client) error { + return func(c *Client) error { + if i < 65536 && i > -1 { + c.fromport = strconv.Itoa(i) + return nil + } + return fmt.Errorf("Invalid port") + } +} + +//SetToPort sets the port of the client's SAM bridge using a string +func SetToPort(s string) func(*Client) error { + return func(c *Client) error { + port, err := strconv.Atoi(s) + if err != nil { + return fmt.Errorf("Invalid port; non-number") + } + if port < 65536 && port > -1 { + c.toport = s + return nil + } + return fmt.Errorf("Invalid port") + } +} + +//SetToPortInt sets the port of the client's SAM bridge using a string +func SetToPortInt(i int) func(*Client) error { + return func(c *Client) error { + if i < 65536 && i > -1 { + c.fromport = strconv.Itoa(i) + return nil + } + return fmt.Errorf("Invalid port") + } +} + +//SetDebug enables debugging messages +func SetDebug(b bool) func(*Client) error { + return func(c *Client) error { + c.debug = b + return nil + } +} + +//SetInLength sets the number of hops inbound +func SetInLength(u uint) func(*Client) error { + return func(c *Client) error { + if u < 7 { + c.inLength = u + return nil + } + return fmt.Errorf("Invalid inbound tunnel length") + } +} + +//SetOutLength sets the number of hops outbound +func SetOutLength(u uint) func(*Client) error { + return func(c *Client) error { + if u < 7 { + c.outLength = u + return nil + } + return fmt.Errorf("Invalid outbound tunnel length") + } +} + +//SetInVariance sets the variance of a number of hops inbound +func SetInVariance(i int) func(*Client) error { + return func(c *Client) error { + if i < 7 && i > -7 { + c.inVariance = i + return nil + } + return fmt.Errorf("Invalid inbound tunnel length") + } +} + +//SetOutVariance sets the variance of a number of hops outbound +func SetOutVariance(i int) func(*Client) error { + return func(c *Client) error { + if i < 7 && i > -7 { + c.outVariance = i + return nil + } + return fmt.Errorf("Invalid outbound tunnel variance") + } +} + +//SetInQuantity sets the inbound tunnel quantity +func SetInQuantity(u uint) func(*Client) error { + return func(c *Client) error { + if u <= 16 { + c.inQuantity = u + return nil + } + return fmt.Errorf("Invalid inbound tunnel quantity") + } +} + +//SetOutQuantity sets the outbound tunnel quantity +func SetOutQuantity(u uint) func(*Client) error { + return func(c *Client) error { + if u <= 16 { + c.outQuantity = u + return nil + } + return fmt.Errorf("Invalid outbound tunnel quantity") + } +} + +//SetInBackups sets the inbound tunnel backups +func SetInBackups(u uint) func(*Client) error { + return func(c *Client) error { + if u < 6 { + c.inBackups = u + return nil + } + return fmt.Errorf("Invalid inbound tunnel backup quantity") + } +} + +//SetOutBackups sets the inbound tunnel backups +func SetOutBackups(u uint) func(*Client) error { + return func(c *Client) error { + if u < 6 { + c.outBackups = u + return nil + } + return fmt.Errorf("Invalid outbound tunnel backup quantity") + } +} + +//SetUnpublished tells the router to not publish the client leaseset +func SetUnpublished(b bool) func(*Client) error { + return func(c *Client) error { + c.dontPublishLease = b + return nil + } +} + +//SetEncrypt tells the router to use an encrypted leaseset +func SetEncrypt(b bool) func(*Client) error { + return func(c *Client) error { + c.encryptLease = b + return nil + } +} + +//SetReduceIdle sets the created tunnels to be reduced during extended idle time to avoid excessive resource usage +func SetReduceIdle(b bool) func(*Client) error { + return func(c *Client) error { + c.reduceIdle = b + return nil + } +} + +//SetReduceIdleTime sets time to wait before the tunnel quantity is reduced +func SetReduceIdleTime(u uint) func(*Client) error { + return func(c *Client) error { + if u > 299999 { + c.reduceIdleTime = u + return nil + } + return fmt.Errorf("Invalid reduce idle time %v", u) + } +} + +//SetReduceIdleQuantity sets number of tunnels to keep alive during an extended idle period +func SetReduceIdleQuantity(u uint) func(*Client) error { + return func(c *Client) error { + if u < 5 { + c.reduceIdleQuantity = u + return nil + } + return fmt.Errorf("Invalid reduced tunnel quantity %v", u) + } +} + +//SetCloseIdle sets the tunnels to close after a specific amount of time +func SetCloseIdle(b bool) func(*Client) error { + return func(c *Client) error { + c.closeIdle = b + return nil + } +} + +//SetCloseIdleTime sets the time in milliseconds to wait before closing tunnels +func SetCloseIdleTime(u uint) func(*Client) error { + return func(c *Client) error { + if u > 299999 { + c.closeIdleTime = u + return nil + } + return fmt.Errorf("Invalid close idle time %v", u) + } +} + +//SetCompression sets the tunnels to close after a specific amount of time +func SetCompression(b bool) func(*Client) error { + return func(c *Client) error { + c.compression = b + return nil + } +} + +/* SAM v 3.1 Options*/ + +//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 SetSignatureType(s string) func(*Client) error { + return func(c *Client) error { + if s == "" { + c.sigType = "" + return nil + } + for _, valid := range SAMsigTypes { + if s == valid { + c.sigType = valid + return nil + } + } + return fmt.Errorf("Invalid signature type specified at construction time") + } +} + +//return the from port as a string. +func (c *Client) from() string { + if c.fromport == "" { + return "" + } + return fmt.Sprintf(" FROM_PORT=%v ", c.fromport) +} + +//return the to port as a string. +func (c *Client) to() string { + if c.toport == "" { + return "" + } + return fmt.Sprintf(" TO_PORT=%v ", c.toport) +} + +//return the signature type as a string. +func (c *Client) sigtype() string { + return fmt.Sprintf(" %s ", c.sigType) +} + +//return the inbound length as a string. +func (c *Client) inlength() string { + return fmt.Sprintf(" inbound.length=%d ", c.inLength) +} + +//return the outbound length as a string. +func (c *Client) outlength() string { + return fmt.Sprintf(" outbound.length=%d ", c.outLength) +} + +//return the inbound length variance as a string. +func (c *Client) invariance() string { + return fmt.Sprintf(" inbound.lengthVariance=%d ", c.inVariance) +} + +//return the outbound length variance as a string. +func (c *Client) outvariance() string { + return fmt.Sprintf(" outbound.lengthVariance=%d ", c.outVariance) +} + +//return the inbound tunnel quantity as a string. +func (c *Client) inquantity() string { + return fmt.Sprintf(" inbound.quantity=%d ", c.inQuantity) +} + +//return the outbound tunnel quantity as a string. +func (c *Client) outquantity() string { + return fmt.Sprintf(" outbound.quantity=%d ", c.outQuantity) +} + +//return the inbound tunnel quantity as a string. +func (c *Client) inbackups() string { + return fmt.Sprintf(" inbound.backupQuantity=%d ", c.inQuantity) +} + +//return the outbound tunnel quantity as a string. +func (c *Client) outbackups() string { + return fmt.Sprintf(" outbound.backupQuantity=%d ", c.outQuantity) +} + +func (c *Client) encryptlease() string { + if c.encryptLease { + return " i2cp.encryptLeaseSet=true " + } + return " i2cp.encryptLeaseSet=false " +} + +func (c *Client) dontpublishlease() string { + if c.dontPublishLease { + return " i2cp.dontPublishLeaseSet=true " + } + return " i2cp.dontPublishLeaseSet=false " +} + +func (c *Client) closeonidle() string { + if c.closeIdle { + return " i2cp.closeOnIdle=true " + } + return " i2cp.closeOnIdle=false " +} + +func (c *Client) closeidletime() string { + return fmt.Sprintf(" i2cp.closeIdleTime=%d ", c.closeIdleTime) +} + +func (c *Client) reduceonidle() string { + if c.reduceIdle { + return " i2cp.reduceOnIdle=true " + } + return " i2cp.reduceOnIdle=false " +} + +func (c *Client) reduceidletime() string { + return fmt.Sprintf(" i2cp.reduceIdleTime=%d ", c.reduceIdleTime) +} + +func (c *Client) reduceidlecount() string { + return fmt.Sprintf(" i2cp.reduceIdleQuantity=%d ", c.reduceIdleQuantity) +} + +func (c *Client) compresion() string { + if c.compression { + return " i2cp.gzip=true " + } + return " i2cp.gzip=false " +} + +//return all options as string ready for passing to sendcmd +func (c *Client) allOptions() string { + return c.inlength() + + c.outlength() + + c.invariance() + + c.outvariance() + + c.inquantity() + + c.outquantity() + + c.inbackups() + + c.outbackups() + + c.dontpublishlease() + + c.encryptlease() + + c.reduceonidle() + + c.reduceidletime() + + c.reduceidlecount() + + c.closeonidle() + + c.closeidletime() + + c.compresion() +} + +//Print return all options as string +func (c *Client) Print() string { + return c.inlength() + + c.outlength() + + c.invariance() + + c.outvariance() + + c.inquantity() + + c.outquantity() + + c.inbackups() + + c.outbackups() + + c.dontpublishlease() + + c.encryptlease() + + c.reduceonidle() + + c.reduceidletime() + + c.reduceidlecount() + + c.closeonidle() + + c.closeidletime() + + c.compresion() +} diff --git a/vendor/github.com/eyedeekay/goSam/replyParser.go b/vendor/github.com/eyedeekay/goSam/replyParser.go new file mode 100644 index 00000000..70afc9a6 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/replyParser.go @@ -0,0 +1,64 @@ +package goSam + +import ( + "fmt" + "strings" +) + +// The Possible Results send by SAM +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) +) + +// A ReplyError is a custom error type, containing the Result and full Reply +type ReplyError struct { + Result string + Reply *Reply +} + +func (r ReplyError) Error() string { + return fmt.Sprintf("ReplyError: Result:%s - Reply:%+v", r.Result, r.Reply) +} + +// Reply is the parsed result of a SAM command, containing a map of all the key-value pairs +type Reply struct { + Topic string + Type string + + Pairs map[string]string +} + +func parseReply(line string) (*Reply, error) { + line = strings.TrimSpace(line) + parts := strings.Split(line, " ") + if len(parts) < 3 { + return nil, fmt.Errorf("Malformed Reply.\n%s\n", line) + } + + r := &Reply{ + Topic: parts[0], + Type: parts[1], + Pairs: make(map[string]string, len(parts)-2), + } + + 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) + } + } + + r.Pairs[kvPair[0]] = kvPair[len(kvPair)-1] + } + + return r, nil +} diff --git a/vendor/github.com/eyedeekay/goSam/rw.go b/vendor/github.com/eyedeekay/goSam/rw.go new file mode 100644 index 00000000..18d54609 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/rw.go @@ -0,0 +1,101 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Henry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package goSam + +import ( + "encoding/hex" + "io" + "log" +) + +/* +Copy of testing/iotest Read- and WriteLogger, but using %q instead of %x for printing +*/ + +type writeLogger struct { + prefix string + w io.Writer +} + +func (l *writeLogger) Write(p []byte) (n int, err error) { + n, err = l.w.Write(p) + if err != nil { + log.Printf("%s %q: %v", l.prefix, string(p[0:n]), err) + } else { + log.Printf("%s %q", l.prefix, string(p[0:n])) + } + return +} + +// 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 NewWriteLogger(prefix string, w io.Writer) io.Writer { + return &writeLogger{prefix, w} +} + +type readLogger struct { + prefix string + r io.Reader +} + +func (l *readLogger) Read(p []byte) (n int, err error) { + n, err = l.r.Read(p) + if err != nil { + log.Printf("%s %q: %v", l.prefix, string(p[0:n]), err) + } else { + log.Printf("%s %q", l.prefix, string(p[0:n])) + } + return +} + +// 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 NewReadLogger(prefix string, r io.Reader) io.Reader { + return &readLogger{prefix, r} +} + +type readHexLogger struct { + prefix string + r io.Reader +} + +func (l *readHexLogger) Read(p []byte) (n int, err error) { + n, err = l.r.Read(p) + if err != nil { + log.Printf("%s (%d bytes) Error: %v", l.prefix, n, err) + } else { + log.Printf("%s (%d bytes)", l.prefix, n) + } + log.Print("\n" + hex.Dump(p[:n])) + return +} + +// NewReadHexLogger returns a reader that behaves like r except +// that it logs to stderr using ecoding/hex. +func NewReadHexLogger(prefix string, r io.Reader) io.Reader { + return &readHexLogger{prefix, r} +} diff --git a/vendor/github.com/eyedeekay/goSam/rwc.go b/vendor/github.com/eyedeekay/goSam/rwc.go new file mode 100644 index 00000000..4327a0db --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/rwc.go @@ -0,0 +1,80 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Henry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package goSam + +import ( + "io" + //"github.com/miolini/datacounter" +) + +type RWC struct { + io.Reader + io.Writer + c io.Closer +} + +func WrapRWC(c io.ReadWriteCloser) io.ReadWriteCloser { + rl := NewReadLogger("<", c) + wl := NewWriteLogger(">", c) + + return &RWC{ + Reader: rl, + Writer: wl, + c: c, + } +} + +func (c *RWC) Close() error { + return c.c.Close() +} + +/* +type Counter struct { + io.Reader + io.Writer + c io.Closer + + Cr *datacounter.ReaderCounter + Cw *datacounter.WriterCounter +} + +func WrapCounter(c io.ReadWriteCloser) *Counter { + rc := datacounter.NewReaderCounter(c) + wc := datacounter.NewWriterCounter(c) + + return &Counter{ + Reader: rc, + Writer: wc, + c: c, + + Cr: rc, + Cw: wc, + } +} + +func (c *Counter) Close() error { + return c.c.Close() +} +*/ diff --git a/vendor/github.com/eyedeekay/goSam/sessions.go b/vendor/github.com/eyedeekay/goSam/sessions.go new file mode 100644 index 00000000..f5aece4c --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/sessions.go @@ -0,0 +1,45 @@ +package goSam + +import ( + "fmt" + // "math" + "math/rand" + "time" +) + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// CreateStreamSession creates a new STREAM Session. +// Returns the Id for the new Client. +func (c *Client) CreateStreamSession(id int32, dest string) (string, error) { + if dest == "" { + dest = "TRANSIENT" + } + c.id = id + r, err := c.sendCmd( + "SESSION CREATE STYLE=STREAM ID=%d %s %s DESTINATION=%s %s %s\n", + c.id, + c.from(), + c.to(), + dest, + c.sigtype(), + c.allOptions(), + ) + if err != nil { + return "", err + } + + // TODO: move check into sendCmd() + if r.Topic != "SESSION" || r.Type != "STATUS" { + return "", fmt.Errorf("Unknown Reply: %+v\n", r) + } + + result := r.Pairs["RESULT"] + if result != "OK" { + return "", ReplyError{ResultKeyNotFound, r} + } + c.destination = r.Pairs["DESTINATION"] + return c.destination, nil +} diff --git a/vendor/github.com/eyedeekay/goSam/stream.go b/vendor/github.com/eyedeekay/goSam/stream.go new file mode 100644 index 00000000..3663a825 --- /dev/null +++ b/vendor/github.com/eyedeekay/goSam/stream.go @@ -0,0 +1,45 @@ +package goSam + +import ( + "fmt" +) + +// 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) + 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) + } + + result := r.Pairs["RESULT"] + if result != "OK" { + return ReplyError{result, r} + } + + return nil +} + +// StreamAccept asks SAM to accept a TCP-Like connection +func (c *Client) StreamAccept(id int32) (*Reply, error) { + r, err := c.sendCmd("STREAM ACCEPT ID=%d SILENT=false\n", id) + if err != nil { + return nil, err + } + + // TODO: move check into sendCmd() + if r.Topic != "STREAM" || r.Type != "STATUS" { + return nil, fmt.Errorf("Unknown Reply: %+v\n", r) + } + + result := r.Pairs["RESULT"] + if result != "OK" { + return nil, ReplyError{result, r} + } + + return r, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index c76e9208..6f9a5737 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -84,8 +84,6 @@ github.com/dsnet/compress/internal/errors # github.com/eyedeekay/goSam v0.32.22 ## explicit github.com/eyedeekay/goSam -# github.com/eyedeekay/sam3 v0.32.3 -## explicit # github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 ## explicit # github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 From 64aebe35052815fc934965666898883c9f528f4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2020 17:42:14 +0000 Subject: [PATCH 3/5] Bump elliptic from 6.5.2 to 6.5.3 in /client Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.3. - [Release notes](https://github.com/indutny/elliptic/releases) - [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3) Signed-off-by: dependabot[bot] --- client/yarn.lock | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/client/yarn.lock b/client/yarn.lock index ef760499..cdeeec03 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -2649,8 +2649,9 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== bn.js@^5.1.1: version "5.1.1" @@ -2707,6 +2708,7 @@ braces@^3.0.1: brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= brotli@^1.3.1: version "1.3.2" @@ -3874,8 +3876,9 @@ electron-to-chromium@^1.3.413: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.430.tgz#33914f7c2db771bdcf30977bd4fd6258ee8a2f37" elliptic@^6.0.0, elliptic@^6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -5123,6 +5126,7 @@ hash-base@^3.0.0: hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.1" @@ -5141,6 +5145,7 @@ history@^5.0.0-beta.8: hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: hash.js "^1.0.3" minimalistic-assert "^1.0.0" @@ -6692,10 +6697,12 @@ mini-css-extract-plugin@^0.9.0: minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= minimatch@^3.0.4: version "3.0.4" From f0f394e5cc0f2ad3bfae5d8ab3559a49751e89ae Mon Sep 17 00:00:00 2001 From: Andreas Wunderlich Date: Wed, 9 Sep 2020 01:25:36 +0200 Subject: [PATCH 4/5] client: Downgraded @sindresorhus/fnv1a to v1.2.0 to fix #66 --- client/package.json | 2 +- client/yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/client/package.json b/client/package.json index 201dc722..8457a7f8 100644 --- a/client/package.json +++ b/client/package.json @@ -62,7 +62,7 @@ "workbox-webpack-plugin": "^5.1.3" }, "dependencies": { - "@sindresorhus/fnv1a": "^2.0.1", + "@sindresorhus/fnv1a": "^1.2.0", "autolinker": "^3.14.1", "backo": "^1.1.0", "classnames": "^2.2.6", diff --git a/client/yarn.lock b/client/yarn.lock index cdeeec03..3d8b13e3 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1804,9 +1804,10 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@sindresorhus/fnv1a@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@sindresorhus/fnv1a/-/fnv1a-2.0.1.tgz#2aefdfa7eb5b7f29a7936978218e986c70c603fc" +"@sindresorhus/fnv1a@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/fnv1a/-/fnv1a-1.2.0.tgz#d554da64c406f3b62ad06dfce9efd537a4a55de4" + integrity sha512-5ezb/dBSTWtKQ4sLQwMgOJyREXJcZZkTMbendMwKrXTghUhWjZhstzkkmt4/WkFy/GSTSGzfJOKU7dEXv3C/XQ== "@sinonjs/commons@^1.7.0": version "1.7.2" From c75eb4abd521284d5c8ad6cd79b70ab675d01a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ken-H=C3=A5vard=20Lieng?= Date: Thu, 10 Sep 2020 00:27:40 +0200 Subject: [PATCH 5/5] Update travis badge URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4161357d..71c04351 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# dispatch [![Build Status](https://travis-ci.org/khlieng/dispatch.svg?branch=master)](https://travis-ci.org/khlieng/dispatch) +# dispatch [![Build Status](https://travis-ci.com/khlieng/dispatch.svg?branch=master)](https://travis-ci.com/khlieng/dispatch) #### [Try it!](https://dispatch.khlieng.com)