Remove all schollz/* dependencies: fork pake, replicate logger and CLI
- src/pake: trimmed fork of schollz/pake/v3, P256-only (stdlib crypto/elliptic), dropping the tscholl2/siec and filippo.io/edwards25519 transitive deps along with it. - src/logger: minimal in-repo replacement for schollz/logger with the same leveled-logging call surface. - src/cli: replaced schollz/cli (urfave/cli fork) with a small flag-package-based parser for the send/relay/receive commands actually in use; subcommand keyword can appear before or after its flags. - Dropped schollz/progressbar entirely (its show-progress code paths were already unreachable dead code since no CLI flag wired them up). go.mod/go.sum no longer reference any schollz/* module.
This commit is contained in:
@@ -7,23 +7,11 @@ require (
|
|||||||
github.com/kalafut/imohash v1.1.1
|
github.com/kalafut/imohash v1.1.1
|
||||||
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b
|
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b
|
||||||
github.com/minio/highwayhash v1.0.4
|
github.com/minio/highwayhash v1.0.4
|
||||||
github.com/schollz/cli/v2 v2.2.1
|
|
||||||
github.com/schollz/logger v1.2.0
|
|
||||||
github.com/schollz/pake/v3 v3.1.1
|
|
||||||
github.com/schollz/progressbar/v3 v3.19.1
|
|
||||||
golang.org/x/crypto v0.53.0
|
golang.org/x/crypto v0.53.0
|
||||||
golang.org/x/net v0.56.0
|
golang.org/x/net v0.56.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.2.0 // indirect
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
|
||||||
github.com/stretchr/testify v1.11.1 // indirect
|
|
||||||
github.com/tscholl2/siec v0.0.0-20240310163802-c2c6f6198406 // indirect
|
|
||||||
github.com/twmb/murmur3 v1.1.8 // indirect
|
github.com/twmb/murmur3 v1.1.8 // indirect
|
||||||
golang.org/x/sys v0.46.0 // indirect
|
golang.org/x/sys v0.46.0 // indirect
|
||||||
golang.org/x/term v0.44.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,45 +1,11 @@
|
|||||||
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
|
|
||||||
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
|
|
||||||
github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/kalafut/imohash v1.1.1 h1:G/HYtKgteQSVU96LidSJEbUGoZOMiBcuXYxbeb2W9e4=
|
github.com/kalafut/imohash v1.1.1 h1:G/HYtKgteQSVU96LidSJEbUGoZOMiBcuXYxbeb2W9e4=
|
||||||
github.com/kalafut/imohash v1.1.1/go.mod h1:6cn9lU0Sj8M4eu9UaQm1kR/5y3k/ayB68yntRhGloL4=
|
github.com/kalafut/imohash v1.1.1/go.mod h1:6cn9lU0Sj8M4eu9UaQm1kR/5y3k/ayB68yntRhGloL4=
|
||||||
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b h1:xZ59n7Frzh8CwyfAapUZLSg+gXH5m63YEaFCMpDHhpI=
|
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b h1:xZ59n7Frzh8CwyfAapUZLSg+gXH5m63YEaFCMpDHhpI=
|
||||||
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b/go.mod h1:uDd4sYVYsqcxAB8j+Q7uhL6IJCs/r1kxib1HV4bgOMg=
|
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b/go.mod h1:uDd4sYVYsqcxAB8j+Q7uhL6IJCs/r1kxib1HV4bgOMg=
|
||||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
|
||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
|
||||||
github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clgl4=
|
github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clgl4=
|
||||||
github.com/minio/highwayhash v1.0.4/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
|
github.com/minio/highwayhash v1.0.4/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/schollz/cli/v2 v2.2.1 h1:ou22Mj7ZPjrKz+8k2iDTWaHskEEV5NiAxGrdsCL36VU=
|
|
||||||
github.com/schollz/cli/v2 v2.2.1/go.mod h1:My6bfphRLZUhZdlFUK8scAxMWHydE7k4s2ed2Dtnn+s=
|
|
||||||
github.com/schollz/logger v1.2.0 h1:5WXfINRs3lEUTCZ7YXhj0uN+qukjizvITLm3Ca2m0Ho=
|
|
||||||
github.com/schollz/logger v1.2.0/go.mod h1:P6F4/dGMGcx8wh+kG1zrNEd4vnNpEBY/mwEMd/vn6AM=
|
|
||||||
github.com/schollz/pake/v3 v3.1.1 h1:lyoU5uNQ3thfjEzrahgxWWBm6+pbI1F2KAZ3gs6LIV8=
|
|
||||||
github.com/schollz/pake/v3 v3.1.1/go.mod h1:420+m3AakXcS0n7Uwc7eRs2CosQ2YfE/vKcIkilvqZc=
|
|
||||||
github.com/schollz/progressbar/v3 v3.19.1 h1:iv8BgwOvdML/S3p84uBpy/IMigv4U9594vPZYa2EdrU=
|
|
||||||
github.com/schollz/progressbar/v3 v3.19.1/go.mod h1:LFL7jqimKxfhero4K1eCkUr/6R39AgQeiPCJtlTWIW8=
|
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
|
||||||
github.com/tscholl2/siec v0.0.0-20240310163802-c2c6f6198406 h1:sDWDZkwYqX0jvLWstKzFwh+pYhQNaVg65BgSkCP/f7U=
|
|
||||||
github.com/tscholl2/siec v0.0.0-20240310163802-c2c6f6198406/go.mod h1:KL9+ubr1JZdaKjgAaHr+tCytEncXBa1pR6FjbTsOJnw=
|
|
||||||
github.com/twmb/murmur3 v1.1.5/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
github.com/twmb/murmur3 v1.1.5/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
||||||
github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg=
|
github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg=
|
||||||
github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
||||||
@@ -50,9 +16,3 @@ golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
|||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
|
||||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
|
|||||||
+133
-106
@@ -1,33 +1,24 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"strconv"
|
||||||
|
|
||||||
"github.com/schollz/cli/v2"
|
log "github.com/tzgyn/share/src/logger"
|
||||||
"github.com/tzgyn/share/src/models"
|
"github.com/tzgyn/share/src/models"
|
||||||
"github.com/tzgyn/share/src/swarm"
|
"github.com/tzgyn/share/src/swarm"
|
||||||
"github.com/tzgyn/share/src/tcp"
|
"github.com/tzgyn/share/src/tcp"
|
||||||
"github.com/tzgyn/share/src/utils"
|
"github.com/tzgyn/share/src/utils"
|
||||||
log "github.com/schollz/logger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version string
|
var Version string
|
||||||
|
|
||||||
func Run() (err error) {
|
const usage = `share [GLOBAL OPTIONS] [COMMAND] [COMMAND OPTIONS] [filename(s)]
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
|
||||||
|
|
||||||
app := cli.NewApp()
|
a torrent-like swarm: everyone who joins a room can send and receive
|
||||||
app.Name = "share"
|
|
||||||
if Version == "" {
|
|
||||||
Version = "v0.1.0"
|
|
||||||
}
|
|
||||||
app.Version = Version
|
|
||||||
app.Compiled = time.Now()
|
|
||||||
app.Usage = "a torrent-like swarm: everyone who joins a room can send and receive"
|
|
||||||
app.UsageText = `share [GLOBAL OPTIONS] [COMMAND] [COMMAND OPTIONS] [filename(s)]
|
|
||||||
|
|
||||||
USAGE EXAMPLES:
|
USAGE EXAMPLES:
|
||||||
Seed a file into a new room (prints a code):
|
Seed a file into a new room (prints a code):
|
||||||
@@ -37,129 +28,165 @@ func Run() (err error) {
|
|||||||
share send --code secret-code file1.txt file2.txt
|
share send --code secret-code file1.txt file2.txt
|
||||||
|
|
||||||
Join a room to receive whatever's shared there (and help re-share it):
|
Join a room to receive whatever's shared there (and help re-share it):
|
||||||
share secret-code`
|
share secret-code
|
||||||
app.Commands = []*cli.Command{
|
|
||||||
{
|
COMMANDS:
|
||||||
Name: "send",
|
send seed file(s) into a room (see options with: share send -h)
|
||||||
Usage: "seed file(s) into a room (see options with share send -h)",
|
relay start your own relay (optional; see options with: share relay -h)
|
||||||
Description: "seed file(s) into a swarm room so others can join and receive them",
|
|
||||||
ArgsUsage: "[filename(s)]",
|
Run "share [command] -h" for the options of a given command.
|
||||||
Flags: []cli.Flag{
|
`
|
||||||
&cli.StringFlag{Name: "code", Aliases: []string{"c"}, Usage: "room codephrase (generated if not given)"},
|
|
||||||
},
|
// Run parses os.Args and dispatches to the send, relay, or default
|
||||||
HelpName: "share send",
|
// (receive) command. The subcommand keyword ("send"/"relay") is found
|
||||||
Action: send,
|
// wherever it appears, not just as the very first argument, so flags can
|
||||||
},
|
// come before or after it (e.g. both "share --relay X send file" and
|
||||||
{
|
// "share send --code X file" work).
|
||||||
Name: "relay",
|
func Run() error {
|
||||||
Usage: "start your own relay (optional)",
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
Description: "start relay",
|
if Version == "" {
|
||||||
HelpName: "share relay",
|
Version = "v0.1.0"
|
||||||
Action: relay,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
&cli.StringFlag{Name: "host", Usage: "host of the relay"},
|
|
||||||
&cli.IntFlag{Name: "port", Value: 9009, Usage: "port of the relay", EnvVars: []string{"SHARE_PORT"}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
app.Flags = []cli.Flag{
|
|
||||||
&cli.BoolFlag{Name: "internal-dns", Usage: "use a built-in DNS stub resolver rather than the host operating system"},
|
|
||||||
&cli.BoolFlag{Name: "classic", Usage: "toggle between the classic mode (insecure due to local attack vector) and new mode (secure)"},
|
|
||||||
&cli.BoolFlag{Name: "remember", Usage: "save these settings to reuse next time"},
|
|
||||||
&cli.BoolFlag{Name: "debug", Usage: "toggle debug mode"},
|
|
||||||
&cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"},
|
|
||||||
&cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"},
|
|
||||||
&cli.BoolFlag{Name: "no-compress", Usage: "disable compression"},
|
|
||||||
&cli.BoolFlag{Name: "ask", Usage: "make sure sender and recipient are prompted"},
|
|
||||||
&cli.BoolFlag{Name: "local", Usage: "force to use only local connections"},
|
|
||||||
&cli.BoolFlag{Name: "ignore-stdin", Usage: "ignore piped stdin"},
|
|
||||||
&cli.BoolFlag{Name: "overwrite", Usage: "do not prompt to overwrite or resume"},
|
|
||||||
&cli.BoolFlag{Name: "testing", Usage: "flag for testing purposes"},
|
|
||||||
&cli.BoolFlag{Name: "quiet", Usage: "disable all output"},
|
|
||||||
&cli.BoolFlag{Name: "disable-clipboard", Usage: "disable copy to clipboard"},
|
|
||||||
&cli.BoolFlag{Name: "extended-clipboard", Usage: "copy full command with secret as env variable to clipboard"},
|
|
||||||
&cli.StringFlag{Name: "multicast", Value: "239.255.255.250", Usage: "multicast address to use for local discovery"},
|
|
||||||
&cli.StringFlag{Name: "curve", Value: "p256", Usage: "choose an encryption curve"},
|
|
||||||
&cli.StringFlag{Name: "ip", Value: "", Usage: "set sender ip if known e.g. 10.0.0.1:9009, [::1]:9009"},
|
|
||||||
&cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay", EnvVars: []string{"SHARE_RELAY"}},
|
|
||||||
&cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"SHARE_RELAY6"}},
|
|
||||||
&cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
|
|
||||||
&cli.BoolFlag{Name: "one-time", Usage: "exit once everything currently in the room is downloaded, instead of staying to help reseed it"},
|
|
||||||
&cli.StringFlag{Name: "socks5", Value: "", Usage: "add a socks5 proxy", EnvVars: []string{"SOCKS5_PROXY"}},
|
|
||||||
&cli.StringFlag{Name: "connect", Value: "", Usage: "add a http proxy", EnvVars: []string{"HTTP_PROXY"}},
|
|
||||||
&cli.StringFlag{Name: "throttleUpload", Value: "", Usage: "throttle the upload speed e.g. 500k"},
|
|
||||||
}
|
|
||||||
app.EnableBashCompletion = true
|
|
||||||
app.HideHelp = false
|
|
||||||
app.HideVersion = false
|
|
||||||
app.Action = func(c *cli.Context) error {
|
|
||||||
return receive(c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return app.Run(os.Args)
|
args := os.Args[1:]
|
||||||
|
if len(args) > 0 {
|
||||||
|
switch args[0] {
|
||||||
|
case "-h", "--help", "help":
|
||||||
|
fmt.Print(usage)
|
||||||
|
return nil
|
||||||
|
case "-v", "--version":
|
||||||
|
fmt.Println(Version)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDebugLevel(c *cli.Context) {
|
for i, a := range args {
|
||||||
if c.Bool("quiet") {
|
switch a {
|
||||||
|
case "send":
|
||||||
|
return runSend(splice(args, i))
|
||||||
|
case "relay":
|
||||||
|
return runRelay(splice(args, i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return runReceive(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// splice removes the subcommand keyword at index i, leaving flags that
|
||||||
|
// appeared before and after it in one list for that subcommand's own
|
||||||
|
// flag.FlagSet to parse.
|
||||||
|
func splice(args []string, i int) []string {
|
||||||
|
out := make([]string, 0, len(args)-1)
|
||||||
|
out = append(out, args[:i]...)
|
||||||
|
out = append(out, args[i+1:]...)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDebugLevel(quiet, debug bool) {
|
||||||
|
switch {
|
||||||
|
case quiet:
|
||||||
log.SetLevel("error")
|
log.SetLevel("error")
|
||||||
} else if c.Bool("debug") {
|
case debug:
|
||||||
log.SetLevel("debug")
|
log.SetLevel("debug")
|
||||||
log.Debug("debug mode on")
|
log.Debug("debug mode on")
|
||||||
} else {
|
default:
|
||||||
log.SetLevel("info")
|
log.SetLevel("info")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func send(c *cli.Context) (err error) {
|
func defaultRelay() string {
|
||||||
setDebugLevel(c)
|
if v := os.Getenv("SHARE_RELAY"); v != "" {
|
||||||
files := c.Args().Slice()
|
return v
|
||||||
|
}
|
||||||
|
return models.DEFAULT_RELAY
|
||||||
|
}
|
||||||
|
|
||||||
|
func runSend(args []string) error {
|
||||||
|
fs := flag.NewFlagSet("send", flag.ExitOnError)
|
||||||
|
fs.Usage = func() {
|
||||||
|
fmt.Fprintln(os.Stderr, "share send [options] file1 [file2 ...]")
|
||||||
|
fs.PrintDefaults()
|
||||||
|
}
|
||||||
|
code := fs.String("code", "", "room codephrase (generated if not given)")
|
||||||
|
relay := fs.String("relay", defaultRelay(), "address of the relay")
|
||||||
|
debug := fs.Bool("debug", false, "toggle debug mode")
|
||||||
|
quiet := fs.Bool("quiet", false, "disable all output")
|
||||||
|
if err := fs.Parse(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
setDebugLevel(*quiet, *debug)
|
||||||
|
|
||||||
|
files := fs.Args()
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
return fmt.Errorf("no files specified; usage: share send file1 [file2 ...]")
|
return fmt.Errorf("no files specified; usage: share send file1 [file2 ...]")
|
||||||
}
|
}
|
||||||
code := c.String("code")
|
roomCode := *code
|
||||||
if code == "" {
|
if roomCode == "" {
|
||||||
code = utils.GetRandomName()
|
roomCode = utils.GetRandomName()
|
||||||
}
|
}
|
||||||
fmt.Printf("Code is: %s\n", code)
|
fmt.Printf("Code is: %s\n", roomCode)
|
||||||
fmt.Println("On the other computer, run:")
|
fmt.Println("On the other computer, run:")
|
||||||
fmt.Printf("\tshare %s\n", code)
|
fmt.Printf("\tshare %s\n", roomCode)
|
||||||
|
|
||||||
return swarm.Run(swarm.Options{
|
return swarm.Run(swarm.Options{
|
||||||
RelayAddress: c.String("relay"),
|
RelayAddress: *relay,
|
||||||
Code: code,
|
Code: roomCode,
|
||||||
Files: files,
|
Files: files,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func receive(c *cli.Context) (err error) {
|
func runReceive(args []string) error {
|
||||||
setDebugLevel(c)
|
fs := flag.NewFlagSet("share", flag.ExitOnError)
|
||||||
code := c.Args().First()
|
fs.Usage = func() {
|
||||||
if code == "" {
|
fmt.Print(usage)
|
||||||
return cli.ShowAppHelp(c)
|
fs.PrintDefaults()
|
||||||
}
|
}
|
||||||
outDir := c.String("out")
|
relay := fs.String("relay", defaultRelay(), "address of the relay")
|
||||||
if outDir == "" {
|
out := fs.String("out", ".", "specify an output folder to receive the file")
|
||||||
outDir = "."
|
oneTime := fs.Bool("one-time", false, "exit once everything currently in the room is downloaded, instead of staying to help reseed it")
|
||||||
|
debug := fs.Bool("debug", false, "toggle debug mode")
|
||||||
|
quiet := fs.Bool("quiet", false, "disable all output")
|
||||||
|
if err := fs.Parse(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
setDebugLevel(*quiet, *debug)
|
||||||
|
|
||||||
|
code := fs.Arg(0)
|
||||||
|
if code == "" {
|
||||||
|
fs.Usage()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return swarm.Run(swarm.Options{
|
return swarm.Run(swarm.Options{
|
||||||
RelayAddress: c.String("relay"),
|
RelayAddress: *relay,
|
||||||
Code: code,
|
Code: code,
|
||||||
OutDir: outDir,
|
OutDir: *out,
|
||||||
OneTime: c.Bool("one-time"),
|
OneTime: *oneTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func relay(c *cli.Context) (err error) {
|
func runRelay(args []string) error {
|
||||||
log.Infof("starting share relay version %v", Version)
|
fs := flag.NewFlagSet("relay", flag.ExitOnError)
|
||||||
|
fs.Usage = func() {
|
||||||
|
fmt.Fprintln(os.Stderr, "share relay [options]")
|
||||||
|
fs.PrintDefaults()
|
||||||
|
}
|
||||||
|
defaultPort := 9009
|
||||||
|
if v := os.Getenv("SHARE_PORT"); v != "" {
|
||||||
|
if p, err := strconv.Atoi(v); err == nil {
|
||||||
|
defaultPort = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
host := fs.String("host", "", "host of the relay")
|
||||||
|
port := fs.Int("port", defaultPort, "port of the relay")
|
||||||
|
debug := fs.Bool("debug", false, "toggle debug mode")
|
||||||
|
if err := fs.Parse(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
debugString := "info"
|
debugString := "info"
|
||||||
if c.Bool("debug") {
|
if *debug {
|
||||||
debugString = "debug"
|
debugString = "debug"
|
||||||
}
|
}
|
||||||
host := c.String("host")
|
log.Infof("starting share relay version %v", Version)
|
||||||
port := c.Int("port")
|
return tcp.Run(debugString, *host, strconv.Itoa(*port))
|
||||||
if port == 0 {
|
|
||||||
port = 9009
|
|
||||||
}
|
|
||||||
return tcp.Run(debugString, host, fmt.Sprintf("%d", port))
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/magisterquis/connectproxy"
|
"github.com/magisterquis/connectproxy"
|
||||||
"github.com/tzgyn/share/src/utils"
|
"github.com/tzgyn/share/src/utils"
|
||||||
log "github.com/schollz/logger"
|
log "github.com/tzgyn/share/src/logger"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// Package logger is a minimal leveled logger, replacing the schollz/logger
|
||||||
|
// dependency with an in-repo equivalent covering the same call surface
|
||||||
|
// (SetLevel/SetOutput and Trace/Debug/Info/Warn/Error, each with an -f
|
||||||
|
// variant) used throughout this project.
|
||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type level int
|
||||||
|
|
||||||
|
const (
|
||||||
|
levelTrace level = iota
|
||||||
|
levelDebug
|
||||||
|
levelInfo
|
||||||
|
levelWarn
|
||||||
|
levelError
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
current level = levelInfo
|
||||||
|
loggers = map[level]*log.Logger{
|
||||||
|
levelTrace: log.New(os.Stdout, "[trace]\t", log.Ltime|log.Lmicroseconds|log.Lshortfile),
|
||||||
|
levelDebug: log.New(os.Stdout, "[debug]\t", log.Ltime|log.Lshortfile),
|
||||||
|
levelInfo: log.New(os.Stdout, "[info]\t", log.Ldate|log.Ltime),
|
||||||
|
levelWarn: log.New(os.Stdout, "[warn]\t", log.Ldate|log.Ltime),
|
||||||
|
levelError: log.New(os.Stdout, "[error]\t", log.Ldate|log.Ltime|log.Lshortfile),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetOutput redirects all log levels to w.
|
||||||
|
func SetOutput(w io.Writer) {
|
||||||
|
for _, l := range loggers {
|
||||||
|
l.SetOutput(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLevel sets the minimum level that will be printed: one of
|
||||||
|
// "trace", "debug", "info", "warn", "error". Unrecognized values are
|
||||||
|
// treated as "trace" (print everything), matching the previous dependency's
|
||||||
|
// behavior.
|
||||||
|
func SetLevel(s string) {
|
||||||
|
switch s {
|
||||||
|
case "debug":
|
||||||
|
current = levelDebug
|
||||||
|
case "info":
|
||||||
|
current = levelInfo
|
||||||
|
case "warn":
|
||||||
|
current = levelWarn
|
||||||
|
case "error":
|
||||||
|
current = levelError
|
||||||
|
default:
|
||||||
|
current = levelTrace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func output(lvl level, s string) {
|
||||||
|
if lvl < current {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loggers[lvl].Output(3, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Tracef(format string, v ...interface{}) { output(levelTrace, fmt.Sprintf(format, v...)) }
|
||||||
|
func Debugf(format string, v ...interface{}) { output(levelDebug, fmt.Sprintf(format, v...)) }
|
||||||
|
func Infof(format string, v ...interface{}) { output(levelInfo, fmt.Sprintf(format, v...)) }
|
||||||
|
func Warnf(format string, v ...interface{}) { output(levelWarn, fmt.Sprintf(format, v...)) }
|
||||||
|
func Errorf(format string, v ...interface{}) { output(levelError, fmt.Sprintf(format, v...)) }
|
||||||
|
|
||||||
|
func Trace(v ...interface{}) { output(levelTrace, fmt.Sprint(v...)) }
|
||||||
|
func Debug(v ...interface{}) { output(levelDebug, fmt.Sprint(v...)) }
|
||||||
|
func Info(v ...interface{}) { output(levelInfo, fmt.Sprint(v...)) }
|
||||||
|
func Warn(v ...interface{}) { output(levelWarn, fmt.Sprint(v...)) }
|
||||||
|
func Error(v ...interface{}) { output(levelError, fmt.Sprint(v...)) }
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tzgyn/share/src/utils"
|
"github.com/tzgyn/share/src/utils"
|
||||||
log "github.com/schollz/logger"
|
log "github.com/tzgyn/share/src/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TCP_BUFFER_SIZE is the maximum packet size
|
// TCP_BUFFER_SIZE is the maximum packet size
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Zack
|
||||||
|
|
||||||
|
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.
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
// Package pake implements a password-authenticated key exchange (a
|
||||||
|
// SPAKE2-style protocol) over the NIST P256 curve from Go's standard
|
||||||
|
// library. It's a trimmed fork of github.com/schollz/pake/v3, kept only
|
||||||
|
// for the P256 case this project actually uses, so no external module
|
||||||
|
// dependency (and no extra elliptic-curve implementations) are needed for
|
||||||
|
// it. See LICENSE for the original project's MIT license.
|
||||||
|
package pake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
// curve is fixed at P256; every peer link in this project uses the same
|
||||||
|
// curve, so there's no need for the multi-curve selection the original
|
||||||
|
// library offered.
|
||||||
|
var curve = elliptic.P256()
|
||||||
|
|
||||||
|
// generator points U and V, fixed and known to both sides ahead of time
|
||||||
|
// (not sent over the wire). Same values as upstream pake's "p256" curve,
|
||||||
|
// verified below at init to still be valid P256 points.
|
||||||
|
var (
|
||||||
|
Uᵤ, _ = new(big.Int).SetString("793136080485469241208656611513609866400481671852", 10)
|
||||||
|
Uᵥ, _ = new(big.Int).SetString("59748757929350367369315811184980635230185250460108398961713395032485227207304", 10)
|
||||||
|
Vᵤ, _ = new(big.Int).SetString("1086685267857089638167386722555472967068468061489", 10)
|
||||||
|
Vᵥ, _ = new(big.Int).SetString("9157340230202296554417312816309453883742349874205386245733062928888341584123", 10)
|
||||||
|
P = elliptic.P256().Params().P
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if !curve.IsOnCurve(Uᵤ, Uᵥ) {
|
||||||
|
panic("pake: U is not on curve")
|
||||||
|
}
|
||||||
|
if !curve.IsOnCurve(Vᵤ, Vᵥ) {
|
||||||
|
panic("pake: V is not on curve")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pake keeps public and private variables by only transmitting between
|
||||||
|
// parties after marshaling.
|
||||||
|
//
|
||||||
|
// This method follows
|
||||||
|
// https://crypto.stanford.edu/~dabo/cryptobook/BonehShoup_0_4.pdf
|
||||||
|
// Figure 21/15
|
||||||
|
// http://www.lothar.com/~warner/MagicWormhole-PyCon2016.pdf
|
||||||
|
// Slide 11
|
||||||
|
type Pake struct {
|
||||||
|
// Public variables
|
||||||
|
Role int
|
||||||
|
Xᵤ, Xᵥ *big.Int
|
||||||
|
Yᵤ, Yᵥ *big.Int
|
||||||
|
|
||||||
|
// Private variables
|
||||||
|
Pw []byte
|
||||||
|
Vpwᵤ, Vpwᵥ *big.Int
|
||||||
|
Upwᵤ, Upwᵥ *big.Int
|
||||||
|
Aα []byte
|
||||||
|
Aαᵤ, Aαᵥ *big.Int
|
||||||
|
Zᵤ, Zᵥ *big.Int
|
||||||
|
K []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public returns the public variables of Pake, safe to marshal and send.
|
||||||
|
func (p *Pake) Public() *Pake {
|
||||||
|
return &Pake{
|
||||||
|
Role: p.Role,
|
||||||
|
Xᵤ: p.Xᵤ,
|
||||||
|
Xᵥ: p.Xᵥ,
|
||||||
|
Yᵤ: p.Yᵤ,
|
||||||
|
Yᵥ: p.Yᵥ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitCurve takes the shared weak passphrase (pw) to initialize the points
|
||||||
|
// on the curve. role is 0 for the side that goes first (e.g. the dialer)
|
||||||
|
// and 1 for the other side.
|
||||||
|
func InitCurve(pw []byte, role int) (p *Pake, err error) {
|
||||||
|
p = new(Pake)
|
||||||
|
p.Pw = pw
|
||||||
|
if role == 1 {
|
||||||
|
p.Role = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.Role = 0
|
||||||
|
|
||||||
|
// STEP: A computes X
|
||||||
|
p.Vpwᵤ, p.Vpwᵥ = curve.ScalarMult(Vᵤ, Vᵥ, p.Pw)
|
||||||
|
p.Upwᵤ, p.Upwᵥ = curve.ScalarMult(Uᵤ, Uᵥ, p.Pw)
|
||||||
|
p.Aα = make([]byte, 32) // randomly generated secret
|
||||||
|
if _, err = rand.Read(p.Aα); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.Aαᵤ, p.Aαᵥ = curve.ScalarBaseMult(p.Aα)
|
||||||
|
p.Xᵤ, p.Xᵥ = curve.Add(p.Upwᵤ, p.Upwᵥ, p.Aαᵤ, p.Aαᵥ) // "X"
|
||||||
|
// now X should be sent to B
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes marshals the Pake structure so that private variables are hidden.
|
||||||
|
func (p *Pake) Bytes() (b []byte) {
|
||||||
|
if p == nil {
|
||||||
|
panic("pake is not initialized")
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(p.Public())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates itself with the other party's marshaled Pake and
|
||||||
|
// automatically determines what stage it's at and what to generate next.
|
||||||
|
func (p *Pake) Update(qBytes []byte) (err error) {
|
||||||
|
if p == nil {
|
||||||
|
return fmt.Errorf("pake is not initialized")
|
||||||
|
}
|
||||||
|
var q *Pake
|
||||||
|
if err = json.Unmarshal(qBytes, &q); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if p.Role == q.Role {
|
||||||
|
return errors.New("can't have its own role")
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Role == 1 {
|
||||||
|
// copy over public variables
|
||||||
|
p.Xᵤ, p.Xᵥ = q.Xᵤ, q.Xᵥ
|
||||||
|
if !curve.IsOnCurve(p.Xᵤ, p.Xᵥ) {
|
||||||
|
return errors.New("X values not on curve")
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP: B computes Y
|
||||||
|
p.Vpwᵤ, p.Vpwᵥ = curve.ScalarMult(Vᵤ, Vᵥ, p.Pw)
|
||||||
|
p.Upwᵤ, p.Upwᵥ = curve.ScalarMult(Uᵤ, Uᵥ, p.Pw)
|
||||||
|
p.Aα = make([]byte, 32) // randomly generated secret
|
||||||
|
if _, err = rand.Read(p.Aα); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.Aαᵤ, p.Aαᵥ = curve.ScalarBaseMult(p.Aα)
|
||||||
|
p.Yᵤ, p.Yᵥ = curve.Add(p.Vpwᵤ, p.Vpwᵥ, p.Aαᵤ, p.Aαᵥ) // "Y"
|
||||||
|
|
||||||
|
// STEP: B computes Z
|
||||||
|
v := new(big.Int).Neg(p.Upwᵥ)
|
||||||
|
v.Mod(v, P)
|
||||||
|
p.Zᵤ, p.Zᵥ = curve.Add(p.Xᵤ, p.Xᵥ, p.Upwᵤ, v)
|
||||||
|
p.Zᵤ, p.Zᵥ = curve.ScalarMult(p.Zᵤ, p.Zᵥ, p.Aα)
|
||||||
|
|
||||||
|
// STEP: B computes k
|
||||||
|
// H(pw,id_P,id_Q,X,Y,Z)
|
||||||
|
p.K = sessionKey(p.Pw, p.Xᵤ, p.Xᵥ, p.Yᵤ, p.Yᵥ, p.Zᵤ, p.Zᵥ)
|
||||||
|
} else {
|
||||||
|
p.Yᵤ, p.Yᵥ = q.Yᵤ, q.Yᵥ
|
||||||
|
if !curve.IsOnCurve(p.Yᵤ, p.Yᵥ) {
|
||||||
|
return errors.New("Y values not on curve")
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP: A computes Z
|
||||||
|
v := new(big.Int).Neg(p.Vpwᵥ)
|
||||||
|
v.Mod(v, P)
|
||||||
|
p.Zᵤ, p.Zᵥ = curve.Add(p.Yᵤ, p.Yᵥ, p.Vpwᵤ, v)
|
||||||
|
p.Zᵤ, p.Zᵥ = curve.ScalarMult(p.Zᵤ, p.Zᵥ, p.Aα)
|
||||||
|
|
||||||
|
// STEP: A computes k
|
||||||
|
// H(pw,id_P,id_Q,X,Y,Z)
|
||||||
|
p.K = sessionKey(p.Pw, p.Xᵤ, p.Xᵥ, p.Yᵤ, p.Yᵥ, p.Zᵤ, p.Zᵥ)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func sessionKey(pw []byte, xu, xv, yu, yv, zu, zv *big.Int) []byte {
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write(pw)
|
||||||
|
h.Write(xu.Bytes())
|
||||||
|
h.Write(xv.Bytes())
|
||||||
|
h.Write(yu.Bytes())
|
||||||
|
h.Write(yv.Bytes())
|
||||||
|
h.Write(zu.Bytes())
|
||||||
|
h.Write(zv.Bytes())
|
||||||
|
return h.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionKey returns the derived session key, or an error if one hasn't
|
||||||
|
// been generated yet (i.e. Update hasn't completed the exchange).
|
||||||
|
func (p *Pake) SessionKey() ([]byte, error) {
|
||||||
|
if p == nil {
|
||||||
|
return nil, fmt.Errorf("pake is not initialized")
|
||||||
|
}
|
||||||
|
if p.K == nil {
|
||||||
|
return nil, errors.New("session key not generated")
|
||||||
|
}
|
||||||
|
return p.K, nil
|
||||||
|
}
|
||||||
+1
-1
@@ -11,7 +11,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/schollz/logger"
|
log "github.com/tzgyn/share/src/logger"
|
||||||
|
|
||||||
"github.com/tzgyn/share/src/comm"
|
"github.com/tzgyn/share/src/comm"
|
||||||
"github.com/tzgyn/share/src/tcp"
|
"github.com/tzgyn/share/src/tcp"
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package swarm
|
package swarm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/schollz/pake/v3"
|
|
||||||
|
|
||||||
"github.com/tzgyn/share/src/comm"
|
"github.com/tzgyn/share/src/comm"
|
||||||
|
"github.com/tzgyn/share/src/pake"
|
||||||
)
|
)
|
||||||
|
|
||||||
// handshake runs a PAKE key exchange over c using the room's codephrase as
|
// handshake runs a PAKE key exchange over c using the room's codephrase as
|
||||||
@@ -16,7 +15,7 @@ func handshake(c *comm.Comm, codephrase string, initiator bool) (key []byte, err
|
|||||||
if initiator {
|
if initiator {
|
||||||
role = 0
|
role = 0
|
||||||
}
|
}
|
||||||
p, err := pake.InitCurve([]byte(codephrase), role, "siec")
|
p, err := pake.InitCurve([]byte(codephrase), role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
log "github.com/schollz/logger"
|
log "github.com/tzgyn/share/src/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stop struct {
|
type stop struct {
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/schollz/logger"
|
log "github.com/tzgyn/share/src/logger"
|
||||||
|
|
||||||
"github.com/tzgyn/share/src/comm"
|
"github.com/tzgyn/share/src/comm"
|
||||||
)
|
)
|
||||||
|
|||||||
+8
-90
@@ -26,8 +26,7 @@ import (
|
|||||||
"github.com/kalafut/imohash"
|
"github.com/kalafut/imohash"
|
||||||
"github.com/minio/highwayhash"
|
"github.com/minio/highwayhash"
|
||||||
"github.com/tzgyn/share/src/mnemonicode"
|
"github.com/tzgyn/share/src/mnemonicode"
|
||||||
log "github.com/schollz/logger"
|
log "github.com/tzgyn/share/src/logger"
|
||||||
"github.com/schollz/progressbar/v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const NbPinNumbers = 4
|
const NbPinNumbers = 4
|
||||||
@@ -74,11 +73,7 @@ func GetInput(prompt string) string {
|
|||||||
return strings.TrimSpace(text)
|
return strings.TrimSpace(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HashFile(fname string, algorithm string, showProgress ...bool) (hash256 []byte, err error) {
|
func HashFile(fname string, algorithm string) (hash256 []byte, err error) {
|
||||||
doShowProgress := false
|
|
||||||
if len(showProgress) > 0 {
|
|
||||||
doShowProgress = showProgress[0]
|
|
||||||
}
|
|
||||||
var fstats os.FileInfo
|
var fstats os.FileInfo
|
||||||
fstats, err = os.Lstat(fname)
|
fstats, err = os.Lstat(fname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,17 +91,17 @@ func HashFile(fname string, algorithm string, showProgress ...bool) (hash256 []b
|
|||||||
case "imohash":
|
case "imohash":
|
||||||
return IMOHashFile(fname)
|
return IMOHashFile(fname)
|
||||||
case "md5":
|
case "md5":
|
||||||
return MD5HashFile(fname, doShowProgress)
|
return MD5HashFile(fname)
|
||||||
case "xxhash":
|
case "xxhash":
|
||||||
return XXHashFile(fname, doShowProgress)
|
return XXHashFile(fname)
|
||||||
case "highway":
|
case "highway":
|
||||||
return HighwayHashFile(fname, doShowProgress)
|
return HighwayHashFile(fname)
|
||||||
}
|
}
|
||||||
err = fmt.Errorf("unspecified algorithm")
|
err = fmt.Errorf("unspecified algorithm")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func HighwayHashFile(fname string, doShowProgress bool) (hashHighway []byte, err error) {
|
func HighwayHashFile(fname string) (hashHighway []byte, err error) {
|
||||||
f, err := os.Open(fname)
|
f, err := os.Open(fname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -121,33 +116,15 @@ func HighwayHashFile(fname string, doShowProgress bool) (hashHighway []byte, err
|
|||||||
err = fmt.Errorf("could not create highwayhash: %s", err.Error())
|
err = fmt.Errorf("could not create highwayhash: %s", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if doShowProgress {
|
|
||||||
stat, _ := f.Stat()
|
|
||||||
fnameShort := path.Base(fname)
|
|
||||||
if len(fnameShort) > 20 {
|
|
||||||
fnameShort = fnameShort[:20] + "..."
|
|
||||||
}
|
|
||||||
bar := progressbar.NewOptions64(stat.Size(),
|
|
||||||
progressbar.OptionSetWriter(os.Stderr),
|
|
||||||
progressbar.OptionShowBytes(true),
|
|
||||||
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
|
|
||||||
progressbar.OptionClearOnFinish(),
|
|
||||||
progressbar.OptionFullWidth(),
|
|
||||||
)
|
|
||||||
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err = io.Copy(h, f); err != nil {
|
if _, err = io.Copy(h, f); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hashHighway = h.Sum(nil)
|
hashHighway = h.Sum(nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func MD5HashFile(fname string, doShowProgress bool) (hash256 []byte, err error) {
|
func MD5HashFile(fname string) (hash256 []byte, err error) {
|
||||||
f, err := os.Open(fname)
|
f, err := os.Open(fname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -155,27 +132,9 @@ func MD5HashFile(fname string, doShowProgress bool) (hash256 []byte, err error)
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
if doShowProgress {
|
|
||||||
stat, _ := f.Stat()
|
|
||||||
fnameShort := path.Base(fname)
|
|
||||||
if len(fnameShort) > 20 {
|
|
||||||
fnameShort = fnameShort[:20] + "..."
|
|
||||||
}
|
|
||||||
bar := progressbar.NewOptions64(stat.Size(),
|
|
||||||
progressbar.OptionSetWriter(os.Stderr),
|
|
||||||
progressbar.OptionShowBytes(true),
|
|
||||||
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
|
|
||||||
progressbar.OptionClearOnFinish(),
|
|
||||||
progressbar.OptionFullWidth(),
|
|
||||||
)
|
|
||||||
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err = io.Copy(h, f); err != nil {
|
if _, err = io.Copy(h, f); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hash256 = h.Sum(nil)
|
hash256 = h.Sum(nil)
|
||||||
return
|
return
|
||||||
@@ -196,7 +155,7 @@ func IMOHashFileFull(fname string) (hash []byte, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func XXHashFile(fname string, doShowProgress bool) (hash256 []byte, err error) {
|
func XXHashFile(fname string) (hash256 []byte, err error) {
|
||||||
f, err := os.Open(fname)
|
f, err := os.Open(fname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -204,27 +163,9 @@ func XXHashFile(fname string, doShowProgress bool) (hash256 []byte, err error) {
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
h := xxhash.New()
|
h := xxhash.New()
|
||||||
if doShowProgress {
|
|
||||||
stat, _ := f.Stat()
|
|
||||||
fnameShort := path.Base(fname)
|
|
||||||
if len(fnameShort) > 20 {
|
|
||||||
fnameShort = fnameShort[:20] + "..."
|
|
||||||
}
|
|
||||||
bar := progressbar.NewOptions64(stat.Size(),
|
|
||||||
progressbar.OptionSetWriter(os.Stderr),
|
|
||||||
progressbar.OptionShowBytes(true),
|
|
||||||
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
|
|
||||||
progressbar.OptionClearOnFinish(),
|
|
||||||
progressbar.OptionFullWidth(),
|
|
||||||
)
|
|
||||||
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err = io.Copy(h, f); err != nil {
|
if _, err = io.Copy(h, f); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hash256 = h.Sum(nil)
|
hash256 = h.Sum(nil)
|
||||||
return
|
return
|
||||||
@@ -310,23 +251,6 @@ func MissingChunks(fname string, fsize int64, chunkSize int) (chunkRanges []int6
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var bar *progressbar.ProgressBar
|
|
||||||
showProgress := fsize > 10*1024*1024
|
|
||||||
if showProgress {
|
|
||||||
fnameShort := path.Base(fname)
|
|
||||||
if len(fnameShort) > 20 {
|
|
||||||
fnameShort = fnameShort[:20] + "..."
|
|
||||||
}
|
|
||||||
bar = progressbar.NewOptions64(fsize,
|
|
||||||
progressbar.OptionSetWriter(os.Stderr),
|
|
||||||
progressbar.OptionShowBytes(true),
|
|
||||||
progressbar.OptionSetDescription(fmt.Sprintf("Checking %s", fnameShort)),
|
|
||||||
progressbar.OptionClearOnFinish(),
|
|
||||||
progressbar.OptionFullWidth(),
|
|
||||||
progressbar.OptionThrottle(100*time.Millisecond),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
emptyBuffer := make([]byte, chunkSize)
|
emptyBuffer := make([]byte, chunkSize)
|
||||||
chunkNum := 0
|
chunkNum := 0
|
||||||
chunks := make([]int64, int64(math.Ceil(float64(fsize)/float64(chunkSize))))
|
chunks := make([]int64, int64(math.Ceil(float64(fsize)/float64(chunkSize))))
|
||||||
@@ -342,12 +266,6 @@ func MissingChunks(fname string, fsize int64, chunkSize int) (chunkRanges []int6
|
|||||||
chunkNum++
|
chunkNum++
|
||||||
}
|
}
|
||||||
currentLocation += int64(bytesread)
|
currentLocation += int64(bytesread)
|
||||||
if showProgress && bar != nil {
|
|
||||||
bar.Add(bytesread)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if showProgress && bar != nil {
|
|
||||||
bar.Finish()
|
|
||||||
}
|
}
|
||||||
if chunkNum == 0 {
|
if chunkNum == 0 {
|
||||||
chunkRanges = []int64{}
|
chunkRanges = []int64{}
|
||||||
|
|||||||
Reference in New Issue
Block a user