Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fffdf39bea | ||
|
|
675f896d61 | ||
|
|
496a6d3a05 | ||
|
|
f68e194a4a | ||
|
|
c3c892f95d | ||
|
|
9db87434a7 |
1
go.mod
1
go.mod
|
|
@ -3,6 +3,7 @@ module github.com/schollz/croc/v9
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
filippo.io/age v1.0.0-rc.1
|
||||||
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
||||||
github.com/cespare/xxhash v1.1.0
|
github.com/cespare/xxhash v1.1.0
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||||
|
|
|
||||||
5
go.sum
5
go.sum
|
|
@ -1,3 +1,5 @@
|
||||||
|
filippo.io/age v1.0.0-rc.1 h1:jQ+dz16Xxx3W/WY+YS0J96nVAAidLHO3kfQe0eOmKgI=
|
||||||
|
filippo.io/age v1.0.0-rc.1/go.mod h1:Vvd9IlwNo4Au31iqNZeZVnYtGcOf/wT4mtvZQ2ODlSk=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
|
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
|
||||||
|
|
@ -13,8 +15,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
|
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
|
||||||
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
|
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
|
||||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||||
github.com/kalafut/imohash v1.0.0 h1:LgCJ+p/BwM2HKpOxFopkeddpzVCfm15EtXMroXD1SYE=
|
|
||||||
github.com/kalafut/imohash v1.0.0/go.mod h1:c3RHT80ZAp5C/aYgQI92ZlrOymqkZnRDprU87kg75HI=
|
|
||||||
github.com/kalafut/imohash v1.0.2 h1:j/cUPa15YvXv7abJlM+kdJIycbBMpmO7WqhPl4YB76I=
|
github.com/kalafut/imohash v1.0.2 h1:j/cUPa15YvXv7abJlM+kdJIycbBMpmO7WqhPl4YB76I=
|
||||||
github.com/kalafut/imohash v1.0.2/go.mod h1:PjHBF0vpo1q7zMqiTn0qwSTQU2wDn5QIe8S8sFQuZS8=
|
github.com/kalafut/imohash v1.0.2/go.mod h1:PjHBF0vpo1q7zMqiTn0qwSTQU2wDn5QIe8S8sFQuZS8=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
|
@ -61,6 +61,7 @@ github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094/go.mod h1:KL9+ubr1JZ
|
||||||
github.com/twmb/murmur3 v1.1.5 h1:i9OLS9fkuLzBXjt6dptlAEyk58fJsSTXbRg3SgVyqgk=
|
github.com/twmb/murmur3 v1.1.5 h1:i9OLS9fkuLzBXjt6dptlAEyk58fJsSTXbRg3SgVyqgk=
|
||||||
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=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc h1:+q90ECDSAQirdykUN6sPEiBXBsp8Csjcca8Oy7bgLTA=
|
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc h1:+q90ECDSAQirdykUN6sPEiBXBsp8Csjcca8Oy7bgLTA=
|
||||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/schollz/cli/v2"
|
"github.com/schollz/cli/v2"
|
||||||
"github.com/schollz/croc/v9/src/comm"
|
"github.com/schollz/croc/v9/src/comm"
|
||||||
"github.com/schollz/croc/v9/src/croc"
|
"github.com/schollz/croc/v9/src/croc"
|
||||||
|
"github.com/schollz/croc/v9/src/crypt"
|
||||||
"github.com/schollz/croc/v9/src/models"
|
"github.com/schollz/croc/v9/src/models"
|
||||||
"github.com/schollz/croc/v9/src/tcp"
|
"github.com/schollz/croc/v9/src/tcp"
|
||||||
"github.com/schollz/croc/v9/src/utils"
|
"github.com/schollz/croc/v9/src/utils"
|
||||||
|
|
@ -75,6 +76,7 @@ func Run() (err error) {
|
||||||
},
|
},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the relay"},
|
&cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the relay"},
|
||||||
|
&cli.StringFlag{Name: "identity", Value: "", Usage: "identity file with credentials"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +95,8 @@ func Run() (err error) {
|
||||||
&cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay", EnvVars: []string{"CROC_RELAY"}},
|
&cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay", EnvVars: []string{"CROC_RELAY"}},
|
||||||
&cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"CROC_RELAY6"}},
|
&cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"CROC_RELAY6"}},
|
||||||
&cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
|
&cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
|
||||||
&cli.StringFlag{Name: "pass", Value: models.DEFAULT_PASSPHRASE, Usage: "password for the relay", EnvVars: []string{"CROC_PASS"}},
|
&cli.StringFlag{Name: "relay-pass", Value: models.DEFAULT_RELAY_PASSWORD, Usage: "password for the relay (defaults to public relay)", EnvVars: []string{"CROC_PASS"}},
|
||||||
|
&cli.StringFlag{Name: "relay-key", Value: models.DEFAULT_RELAY_KEYPUBLIC, Usage: "public key for the relay (defaults to public relay)", EnvVars: []string{"CROC_KEY"}},
|
||||||
&cli.StringFlag{Name: "socks5", Value: "", Usage: "add a socks5 proxy", EnvVars: []string{"SOCKS5_PROXY"}},
|
&cli.StringFlag{Name: "socks5", Value: "", Usage: "add a socks5 proxy", EnvVars: []string{"SOCKS5_PROXY"}},
|
||||||
}
|
}
|
||||||
app.EnableBashCompletion = true
|
app.EnableBashCompletion = true
|
||||||
|
|
@ -167,15 +170,6 @@ func getConfigFile() string {
|
||||||
return path.Join(configFile, "send.json")
|
return path.Join(configFile, "send.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func determinePass(c *cli.Context) (pass string) {
|
|
||||||
pass = c.String("pass")
|
|
||||||
b, err := ioutil.ReadFile(pass)
|
|
||||||
if err == nil {
|
|
||||||
pass = strings.TrimSpace(string(b))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func send(c *cli.Context) (err error) {
|
func send(c *cli.Context) (err error) {
|
||||||
setDebugLevel(c)
|
setDebugLevel(c)
|
||||||
comm.Socks5Proxy = c.String("socks5")
|
comm.Socks5Proxy = c.String("socks5")
|
||||||
|
|
@ -193,7 +187,8 @@ func send(c *cli.Context) (err error) {
|
||||||
RelayPorts: strings.Split(c.String("ports"), ","),
|
RelayPorts: strings.Split(c.String("ports"), ","),
|
||||||
Ask: c.Bool("ask"),
|
Ask: c.Bool("ask"),
|
||||||
NoMultiplexing: c.Bool("no-multi"),
|
NoMultiplexing: c.Bool("no-multi"),
|
||||||
RelayPassword: determinePass(c),
|
RelayPassword: c.String("relay-pass"),
|
||||||
|
RelayKeyPublic: c.String("relay-key"),
|
||||||
SendingText: c.String("text") != "",
|
SendingText: c.String("text") != "",
|
||||||
NoCompress: c.Bool("no-compress"),
|
NoCompress: c.Bool("no-compress"),
|
||||||
Overwrite: c.Bool("overwrite"),
|
Overwrite: c.Bool("overwrite"),
|
||||||
|
|
@ -226,9 +221,12 @@ func send(c *cli.Context) (err error) {
|
||||||
if !c.IsSet("code") {
|
if !c.IsSet("code") {
|
||||||
crocOptions.SharedSecret = rememberedOptions.SharedSecret
|
crocOptions.SharedSecret = rememberedOptions.SharedSecret
|
||||||
}
|
}
|
||||||
if !c.IsSet("pass") {
|
if !c.IsSet("relay-pass") {
|
||||||
crocOptions.RelayPassword = rememberedOptions.RelayPassword
|
crocOptions.RelayPassword = rememberedOptions.RelayPassword
|
||||||
}
|
}
|
||||||
|
if !c.IsSet("relay-key") {
|
||||||
|
crocOptions.RelayKeyPublic = rememberedOptions.RelayKeyPublic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fnames []string
|
var fnames []string
|
||||||
|
|
@ -391,7 +389,8 @@ func receive(c *cli.Context) (err error) {
|
||||||
RelayAddress6: c.String("relay6"),
|
RelayAddress6: c.String("relay6"),
|
||||||
Stdout: c.Bool("stdout"),
|
Stdout: c.Bool("stdout"),
|
||||||
Ask: c.Bool("ask"),
|
Ask: c.Bool("ask"),
|
||||||
RelayPassword: determinePass(c),
|
RelayPassword: c.String("relay-pass"),
|
||||||
|
RelayKeyPublic: c.String("relay-key"),
|
||||||
OnlyLocal: c.Bool("local"),
|
OnlyLocal: c.Bool("local"),
|
||||||
IP: c.String("ip"),
|
IP: c.String("ip"),
|
||||||
Overwrite: c.Bool("overwrite"),
|
Overwrite: c.Bool("overwrite"),
|
||||||
|
|
@ -481,23 +480,40 @@ func receive(c *cli.Context) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func relay(c *cli.Context) (err error) {
|
func relay(c *cli.Context) (err error) {
|
||||||
log.Infof("starting croc relay version %v", Version)
|
identityFile := "identity.croc"
|
||||||
|
if c.String("identity") != "" {
|
||||||
|
identityFile = c.String("identity")
|
||||||
|
}
|
||||||
|
if !utils.Exists(identityFile) {
|
||||||
|
err = crypt.GenerateIdentityAndPassword(identityFile)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyPrivate, keyPublic, password, err := crypt.LoadIdentityAndPassword(identityFile)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ports := strings.Split(c.String("ports"), ",")
|
||||||
|
tcpPorts := strings.Join(ports[1:], ",")
|
||||||
|
fmt.Printf("starting croc relay version %v\n", Version)
|
||||||
|
identityFileAbs, _ := filepath.Abs(identityFile)
|
||||||
|
fmt.Printf("identity file = %s\n", identityFileAbs)
|
||||||
|
fmt.Printf("\n\nexample to send files:\n\n croc --relay localhost:%s --relay-pass %s --relay-key %s send file.txt", ports[0], password, keyPublic)
|
||||||
debugString := "info"
|
debugString := "info"
|
||||||
if c.Bool("debug") {
|
if c.Bool("debug") {
|
||||||
debugString = "debug"
|
debugString = "debug"
|
||||||
}
|
}
|
||||||
ports := strings.Split(c.String("ports"), ",")
|
|
||||||
tcpPorts := strings.Join(ports[1:], ",")
|
|
||||||
for i, port := range ports {
|
for i, port := range ports {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go func(portStr string) {
|
go func(portStr string) {
|
||||||
err = tcp.Run(debugString, portStr, determinePass(c))
|
err = tcp.Run(debugString, portStr, password, keyPublic, keyPrivate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}(port)
|
}(port)
|
||||||
}
|
}
|
||||||
return tcp.Run(debugString, ports[0], determinePass(c), tcpPorts)
|
return tcp.Run(debugString, ports[0], password, keyPublic, keyPrivate, tcpPorts)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,11 @@ type Options struct {
|
||||||
RelayAddress6 string
|
RelayAddress6 string
|
||||||
RelayPorts []string
|
RelayPorts []string
|
||||||
RelayPassword string
|
RelayPassword string
|
||||||
|
RelayKeyPrivate string
|
||||||
|
RelayKeyPublic string
|
||||||
|
LocalRelayPassword string
|
||||||
|
LocalRelayKeyPrivate string
|
||||||
|
LocalRelayKeyPublic string
|
||||||
Stdout bool
|
Stdout bool
|
||||||
NoPrompt bool
|
NoPrompt bool
|
||||||
NoMultiplexing bool
|
NoMultiplexing bool
|
||||||
|
|
@ -288,7 +293,7 @@ func (c *Client) setupLocalRelay() {
|
||||||
if c.Options.Debug {
|
if c.Options.Debug {
|
||||||
debugString = "debug"
|
debugString = "debug"
|
||||||
}
|
}
|
||||||
err := tcp.Run(debugString, portStr, c.Options.RelayPassword, strings.Join(c.Options.RelayPorts[1:], ","))
|
err := tcp.Run(debugString, portStr, c.Options.LocalRelayPassword, c.Options.LocalRelayKeyPublic, c.Options.LocalRelayKeyPrivate, strings.Join(c.Options.RelayPorts[1:], ","))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +325,7 @@ func (c *Client) transferOverLocalRelay(options TransferOptions, errchan chan<-
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
log.Debug("establishing connection")
|
log.Debug("establishing connection")
|
||||||
var banner string
|
var banner string
|
||||||
conn, banner, ipaddr, err := tcp.ConnectToTCPServer("localhost:"+c.Options.RelayPorts[0], c.Options.RelayPassword, c.Options.SharedSecret[:3])
|
conn, banner, ipaddr, err := tcp.ConnectToTCPServer("localhost:"+c.Options.RelayPorts[0], c.Options.LocalRelayPassword, c.Options.LocalRelayKeyPublic, c.Options.SharedSecret[:3])
|
||||||
log.Debugf("banner: %s", banner)
|
log.Debugf("banner: %s", banner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("could not connect to localhost:%s: %w", c.Options.RelayPorts[0], err)
|
err = fmt.Errorf("could not connect to localhost:%s: %w", c.Options.RelayPorts[0], err)
|
||||||
|
|
@ -361,8 +366,9 @@ func (c *Client) Send(options TransferOptions) (err error) {
|
||||||
if c.Options.RelayAddress != models.DEFAULT_RELAY {
|
if c.Options.RelayAddress != models.DEFAULT_RELAY {
|
||||||
flags.WriteString("--relay " + c.Options.RelayAddress + " ")
|
flags.WriteString("--relay " + c.Options.RelayAddress + " ")
|
||||||
}
|
}
|
||||||
if c.Options.RelayPassword != models.DEFAULT_PASSPHRASE {
|
if c.Options.RelayPassword != models.DEFAULT_RELAY_PASSWORD || c.Options.RelayKeyPublic != models.DEFAULT_RELAY_KEYPUBLIC {
|
||||||
flags.WriteString("--pass " + c.Options.RelayPassword + " ")
|
flags.WriteString("--relay-pass " + c.Options.RelayPassword + " ")
|
||||||
|
flags.WriteString("--relay-key " + c.Options.RelayKeyPublic + " ")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "Code is: %[1]s\nOn the other computer run\n\ncroc %[2]s%[1]s\n", c.Options.SharedSecret, flags.String())
|
fmt.Fprintf(os.Stderr, "Code is: %[1]s\nOn the other computer run\n\ncroc %[2]s%[1]s\n", c.Options.SharedSecret, flags.String())
|
||||||
if c.Options.Ask {
|
if c.Options.Ask {
|
||||||
|
|
@ -376,6 +382,8 @@ func (c *Client) Send(options TransferOptions) (err error) {
|
||||||
errchan := make(chan error, 1)
|
errchan := make(chan error, 1)
|
||||||
|
|
||||||
if !c.Options.DisableLocal {
|
if !c.Options.DisableLocal {
|
||||||
|
c.Options.LocalRelayKeyPublic, c.Options.LocalRelayKeyPrivate, _ = crypt.NewAge()
|
||||||
|
c.Options.LocalRelayPassword, _ = crypt.GenerateRandomString(6)
|
||||||
// add two things to the error channel
|
// add two things to the error channel
|
||||||
errchan = make(chan error, 2)
|
errchan = make(chan error, 2)
|
||||||
c.setupLocalRelay()
|
c.setupLocalRelay()
|
||||||
|
|
@ -405,7 +413,7 @@ func (c *Client) Send(options TransferOptions) (err error) {
|
||||||
log.Debugf("got host '%v' and port '%v'", host, port)
|
log.Debugf("got host '%v' and port '%v'", host, port)
|
||||||
address = net.JoinHostPort(host, port)
|
address = net.JoinHostPort(host, port)
|
||||||
log.Debugf("trying connection to %s", address)
|
log.Debugf("trying connection to %s", address)
|
||||||
conn, banner, ipaddr, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.SharedSecret[:3], durations[i])
|
conn, banner, ipaddr, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.RelayKeyPublic, c.Options.SharedSecret[:3], durations[i])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Options.RelayAddress = address
|
c.Options.RelayAddress = address
|
||||||
break
|
break
|
||||||
|
|
@ -599,7 +607,7 @@ func (c *Client) Receive() (err error) {
|
||||||
log.Debugf("got host '%v' and port '%v'", host, port)
|
log.Debugf("got host '%v' and port '%v'", host, port)
|
||||||
address = net.JoinHostPort(host, port)
|
address = net.JoinHostPort(host, port)
|
||||||
log.Debugf("trying connection to %s", address)
|
log.Debugf("trying connection to %s", address)
|
||||||
c.conn[0], banner, c.ExternalIP, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.SharedSecret[:3], durations[i])
|
c.conn[0], banner, c.ExternalIP, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.RelayKeyPublic, c.Options.SharedSecret[:3], durations[i])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Options.RelayAddress = address
|
c.Options.RelayAddress = address
|
||||||
break
|
break
|
||||||
|
|
@ -652,7 +660,7 @@ func (c *Client) Receive() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
serverTry := fmt.Sprintf("%s:%s", ip, port)
|
serverTry := fmt.Sprintf("%s:%s", ip, port)
|
||||||
conn, banner2, externalIP, errConn := tcp.ConnectToTCPServer(serverTry, c.Options.RelayPassword, c.Options.SharedSecret[:3], 50*time.Millisecond)
|
conn, banner2, externalIP, errConn := tcp.ConnectToTCPServer(serverTry, c.Options.RelayPassword, c.Options.RelayKeyPublic, c.Options.SharedSecret[:3], 50*time.Millisecond)
|
||||||
if errConn != nil {
|
if errConn != nil {
|
||||||
log.Debugf("could not connect to " + serverTry)
|
log.Debugf("could not connect to " + serverTry)
|
||||||
continue
|
continue
|
||||||
|
|
@ -909,6 +917,7 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
c.conn[j+1], _, _, err = tcp.ConnectToTCPServer(
|
c.conn[j+1], _, _, err = tcp.ConnectToTCPServer(
|
||||||
server,
|
server,
|
||||||
c.Options.RelayPassword,
|
c.Options.RelayPassword,
|
||||||
|
c.Options.RelayKeyPublic,
|
||||||
fmt.Sprintf("%s-%d", utils.SHA256(c.Options.SharedSecret[:5])[:6], j),
|
fmt.Sprintf("%s-%d", utils.SHA256(c.Options.SharedSecret[:5])[:6], j),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
package crypt
|
package crypt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"filippo.io/age"
|
||||||
"golang.org/x/crypto/argon2"
|
"golang.org/x/crypto/argon2"
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
|
|
@ -73,6 +79,118 @@ func Decrypt(encrypted []byte, key []byte) (plaintext []byte, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateIdentityAndPassword will generate a file with a public age identity and password
|
||||||
|
func GenerateIdentityAndPassword(fname string) (err error) {
|
||||||
|
keyPublic, keyPrivate, err := NewAge()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
password, err := GenerateRandomString(6)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(fname, []byte(fmt.Sprintf("%s\n%s\n%s", keyPrivate, keyPublic, password)), 0644)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadIdentityAndPassword will load a file with a public age identity and password
|
||||||
|
func LoadIdentityAndPassword(fname string) (keyPrivate string, keyPublic string, password string, err error) {
|
||||||
|
b, err := ioutil.ReadFile(fname)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
foo := strings.Fields(string(b))
|
||||||
|
if len(foo) < 3 {
|
||||||
|
err = fmt.Errorf("malformed file")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
keyPrivate = foo[0]
|
||||||
|
keyPublic = foo[1]
|
||||||
|
password = foo[2]
|
||||||
|
|
||||||
|
_, err = age.ParseX25519Identity(keyPrivate)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = age.ParseX25519Recipient(keyPublic)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateRandomString returns a securely generated random string.
|
||||||
|
// It will return an error if the system's secure random
|
||||||
|
// number generator fails to function correctly, in which
|
||||||
|
// case the caller should not continue.
|
||||||
|
func GenerateRandomString(n int) (string, error) {
|
||||||
|
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
ret := make([]byte, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
ret[i] = letters[num.Int64()]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(ret), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAge() (pubkey string, privkey string, err error) {
|
||||||
|
identity, err := age.GenerateX25519Identity()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pubkey = identity.Recipient().String()
|
||||||
|
privkey = identity.String()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncryptAge(data []byte, pubkey string) (encrypted []byte, err error) {
|
||||||
|
recipient, err := age.ParseX25519Recipient(pubkey)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out := &bytes.Buffer{}
|
||||||
|
w, err := age.Encrypt(out, recipient)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = w.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = w.Close()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
encrypted = out.Bytes()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecryptAge(encrypted []byte, privkey string) (data []byte, err error) {
|
||||||
|
identity, err := age.ParseX25519Identity(privkey)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := age.Decrypt(bytes.NewReader(encrypted), identity)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out := &bytes.Buffer{}
|
||||||
|
_, err = io.Copy(out, r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data = out.Bytes()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// NewArgon2 generates a new key based on a passphrase and salt
|
// NewArgon2 generates a new key based on a passphrase and salt
|
||||||
// using argon2
|
// using argon2
|
||||||
// https://pkg.go.dev/golang.org/x/crypto/argon2
|
// https://pkg.go.dev/golang.org/x/crypto/argon2
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ package crypt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/schollz/croc/v9/src/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -103,3 +105,31 @@ func TestEncryptionChaCha(t *testing.T) {
|
||||||
_, _, err = NewArgon2([]byte(""), nil)
|
_, _, err = NewArgon2([]byte(""), nil)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncryptionAge(t *testing.T) {
|
||||||
|
pub, priv, err := NewAge()
|
||||||
|
fmt.Printf("key: %s\n", pub)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
msg := []byte("hello, world")
|
||||||
|
enc, err := EncryptAge(msg, pub)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
dec, err := DecryptAge(enc, priv)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, msg, dec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerate(t *testing.T) {
|
||||||
|
err := GenerateIdentityAndPassword("test")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.True(t, utils.Exists("test"))
|
||||||
|
keyPrivate, keyPublic, password, err := LoadIdentityAndPassword("test")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
fmt.Println(keyPrivate)
|
||||||
|
fmt.Println(keyPublic)
|
||||||
|
fmt.Println(password)
|
||||||
|
_, _, _, err = LoadIdentityAndPassword("crypt.go")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
_, _, _, err = LoadIdentityAndPassword("doesntexist")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
os.Remove("test")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,13 @@ import (
|
||||||
// TCP_BUFFER_SIZE is the maximum packet size
|
// TCP_BUFFER_SIZE is the maximum packet size
|
||||||
const TCP_BUFFER_SIZE = 1024 * 64
|
const TCP_BUFFER_SIZE = 1024 * 64
|
||||||
|
|
||||||
// DEFAULT_RELAY is the default relay used (can be set using --relay)
|
// DEFAULT_RELAY is the default relay used (can be set using --relay-pass)
|
||||||
var (
|
var (
|
||||||
DEFAULT_RELAY = "croc.schollz.com"
|
DEFAULT_RELAY = "croc.schollz.com"
|
||||||
DEFAULT_RELAY6 = "croc6.schollz.com"
|
DEFAULT_RELAY6 = "croc6.schollz.com"
|
||||||
DEFAULT_PORT = "9009"
|
DEFAULT_PORT = "9009"
|
||||||
DEFAULT_PASSPHRASE = "pass123"
|
DEFAULT_RELAY_PASSWORD = "ZiNO9Y"
|
||||||
|
DEFAULT_RELAY_KEYPUBLIC = "age10yrxthzjrcr0e59nucg0epgnn0qpjv9rhsxqs90rdn335edgnueqrtdnyh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
||||||
134
src/tcp/tcp.go
134
src/tcp/tcp.go
|
|
@ -8,8 +8,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"filippo.io/age"
|
||||||
log "github.com/schollz/logger"
|
log "github.com/schollz/logger"
|
||||||
"github.com/schollz/pake/v3"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"github.com/schollz/croc/v9/src/comm"
|
"github.com/schollz/croc/v9/src/comm"
|
||||||
"github.com/schollz/croc/v9/src/crypt"
|
"github.com/schollz/croc/v9/src/crypt"
|
||||||
|
|
@ -18,6 +19,8 @@ import (
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
port string
|
port string
|
||||||
|
keyPrivate string
|
||||||
|
keyPublic string
|
||||||
debugLevel string
|
debugLevel string
|
||||||
banner string
|
banner string
|
||||||
password string
|
password string
|
||||||
|
|
@ -40,9 +43,11 @@ var timeToRoomDeletion = 10 * time.Minute
|
||||||
var pingRoom = "pinglkasjdlfjsaldjf"
|
var pingRoom = "pinglkasjdlfjsaldjf"
|
||||||
|
|
||||||
// Run starts a tcp listener, run async
|
// Run starts a tcp listener, run async
|
||||||
func Run(debugLevel, port, password string, banner ...string) (err error) {
|
func Run(debugLevel, port, password string, keyPublic string, keyPrivate string, banner ...string) (err error) {
|
||||||
s := new(server)
|
s := new(server)
|
||||||
s.port = port
|
s.port = port
|
||||||
|
s.keyPrivate = keyPrivate
|
||||||
|
s.keyPublic = keyPublic
|
||||||
s.password = password
|
s.password = password
|
||||||
s.debugLevel = debugLevel
|
s.debugLevel = debugLevel
|
||||||
if len(banner) > 0 {
|
if len(banner) > 0 {
|
||||||
|
|
@ -85,7 +90,7 @@ func (s *server) start() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) run() (err error) {
|
func (s *server) run() (err error) {
|
||||||
log.Infof("starting TCP server on " + s.port)
|
log.Debugf("starting TCP server on " + s.port)
|
||||||
server, err := net.Listen("tcp", ":"+s.port)
|
server, err := net.Listen("tcp", ":"+s.port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error listening on %s: %w", s.port, err)
|
return fmt.Errorf("error listening on %s: %w", s.port, err)
|
||||||
|
|
@ -151,59 +156,34 @@ func (s *server) run() (err error) {
|
||||||
var weakKey = []byte{1, 2, 3}
|
var weakKey = []byte{1, 2, 3}
|
||||||
|
|
||||||
func (s *server) clientCommunication(port string, c *comm.Comm) (room string, err error) {
|
func (s *server) clientCommunication(port string, c *comm.Comm) (room string, err error) {
|
||||||
// establish secure password with PAKE for communication with relay
|
// get public key of the connecting client
|
||||||
B, err := pake.InitCurve(weakKey, 1, "siec")
|
retBytesEnc, err := c.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Abytes, err := c.Receive()
|
if bytes.Equal(retBytesEnc, []byte("ping")) {
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if bytes.Equal(Abytes, []byte("ping")) {
|
|
||||||
room = pingRoom
|
room = pingRoom
|
||||||
c.Send([]byte("pong"))
|
c.Send([]byte("pong"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = B.Update(Abytes)
|
retBytes, err := crypt.DecryptAge(retBytesEnc, s.keyPrivate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = c.Send(B.Bytes())
|
// check whether we have a valid public key from client
|
||||||
if err != nil {
|
foo := bytes.Split(retBytes, []byte("--"))
|
||||||
return
|
keyPublic := string(foo[0])
|
||||||
}
|
hashedPassword := foo[1]
|
||||||
strongKey, err := B.SessionKey()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Debugf("strongkey: %x", strongKey)
|
|
||||||
|
|
||||||
// receive salt
|
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(s.password))
|
||||||
salt, err := c.Receive()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
|
||||||
}
|
|
||||||
strongKeyForEncryption, _, err := crypt.New(strongKey, salt)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("waiting for password")
|
|
||||||
passwordBytesEnc, err := c.Receive()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
passwordBytes, err := crypt.Decrypt(passwordBytesEnc, strongKeyForEncryption)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(string(passwordBytes)) != s.password {
|
|
||||||
err = fmt.Errorf("bad password")
|
err = fmt.Errorf("bad password")
|
||||||
enc, _ := crypt.Decrypt([]byte(err.Error()), strongKeyForEncryption)
|
return
|
||||||
if err := c.Send(enc); err != nil {
|
|
||||||
return "", fmt.Errorf("send error: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = age.ParseX25519Recipient(keyPublic)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("bad public key: %s", keyPublic)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,7 +193,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
banner = "ok"
|
banner = "ok"
|
||||||
}
|
}
|
||||||
log.Debugf("sending '%s'", banner)
|
log.Debugf("sending '%s'", banner)
|
||||||
bSend, err := crypt.Encrypt([]byte(banner+"|||"+c.Connection().RemoteAddr().String()), strongKeyForEncryption)
|
bSend, err := crypt.EncryptAge([]byte(banner+"|||"+c.Connection().RemoteAddr().String()), keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +208,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
roomBytes, err := crypt.Decrypt(enc, strongKeyForEncryption)
|
roomBytes, err := crypt.DecryptAge(enc, s.keyPrivate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -244,7 +224,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
s.rooms.Unlock()
|
s.rooms.Unlock()
|
||||||
// tell the client that they got the room
|
// tell the client that they got the room
|
||||||
|
|
||||||
bSend, err = crypt.Encrypt([]byte("ok"), strongKeyForEncryption)
|
bSend, err = crypt.EncryptAge([]byte("ok"), keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +239,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
}
|
}
|
||||||
if s.rooms.rooms[room].full {
|
if s.rooms.rooms[room].full {
|
||||||
s.rooms.Unlock()
|
s.rooms.Unlock()
|
||||||
bSend, err = crypt.Encrypt([]byte("room full"), strongKeyForEncryption)
|
bSend, err = crypt.EncryptAge([]byte("room full"), keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -293,7 +273,7 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
|
||||||
}(otherConnection, c, &wg)
|
}(otherConnection, c, &wg)
|
||||||
|
|
||||||
// tell the sender everything is ready
|
// tell the sender everything is ready
|
||||||
bSend, err = crypt.Encrypt([]byte("ok"), strongKeyForEncryption)
|
bSend, err = crypt.EncryptAge([]byte("ok"), keyPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -405,7 +385,7 @@ func PingServer(address string) (err error) {
|
||||||
|
|
||||||
// ConnectToTCPServer will initiate a new connection
|
// ConnectToTCPServer will initiate a new connection
|
||||||
// to the specified address, room with optional time limit
|
// to the specified address, room with optional time limit
|
||||||
func ConnectToTCPServer(address, password, room string, timelimit ...time.Duration) (c *comm.Comm, banner string, ipaddr string, err error) {
|
func ConnectToTCPServer(address, password, keyPublicRelay, room string, timelimit ...time.Duration) (c *comm.Comm, banner string, ipaddr string, err error) {
|
||||||
if len(timelimit) > 0 {
|
if len(timelimit) > 0 {
|
||||||
c, err = comm.NewConnection(address, timelimit[0])
|
c, err = comm.NewConnection(address, timelimit[0])
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -415,65 +395,41 @@ func ConnectToTCPServer(address, password, room string, timelimit ...time.Durati
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get PAKE connection with server to establish strong key to transfer info
|
// generate ephermeral key
|
||||||
A, err := pake.InitCurve(weakKey, 0, "siec")
|
keyPublic, keyPrivate, err := crypt.NewAge()
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = c.Send(A.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Bbytes, err := c.Receive()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = A.Update(Bbytes)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongKey, err := A.SessionKey()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Debugf("strong key: %x", strongKey)
|
|
||||||
|
|
||||||
strongKeyForEncryption, salt, err := crypt.New(strongKey, nil)
|
// send epheremal public key + bcrypted password, encrypted using the server's public key
|
||||||
if err != nil {
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 10)
|
||||||
return
|
|
||||||
}
|
|
||||||
// send salt
|
|
||||||
err = c.Send(salt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("sending password")
|
sendBytesEnc, err := crypt.EncryptAge(append([]byte(keyPublic+"--"), hashedPassword...), keyPublicRelay)
|
||||||
bSend, err := crypt.Encrypt([]byte(password), strongKeyForEncryption)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = c.Send(bSend)
|
|
||||||
|
err = c.Send(sendBytesEnc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("waiting for first ok")
|
retBytesEnc, err := c.Receive()
|
||||||
enc, err := c.Receive()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data, err := crypt.Decrypt(enc, strongKeyForEncryption)
|
retBytes, err := crypt.DecryptAge(retBytesEnc, keyPrivate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(string(data), "|||") {
|
if !strings.Contains(string(retBytes), "|||") {
|
||||||
err = fmt.Errorf("bad response: %s", string(data))
|
err = fmt.Errorf("bad response: %s", string(retBytes))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
banner = strings.Split(string(data), "|||")[0]
|
banner = strings.Split(string(retBytes), "|||")[0]
|
||||||
ipaddr = strings.Split(string(data), "|||")[1]
|
ipaddr = strings.Split(string(retBytes), "|||")[1]
|
||||||
|
|
||||||
log.Debug("sending room")
|
log.Debug("sending room")
|
||||||
bSend, err = crypt.Encrypt([]byte(room), strongKeyForEncryption)
|
bSend, err := crypt.EncryptAge([]byte(room), keyPublicRelay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -482,11 +438,11 @@ func ConnectToTCPServer(address, password, room string, timelimit ...time.Durati
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("waiting for room confirmation")
|
log.Debug("waiting for room confirmation")
|
||||||
enc, err = c.Receive()
|
enc, err := c.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data, err = crypt.Decrypt(enc, strongKeyForEncryption)
|
data, err := crypt.DecryptAge(enc, keyPrivate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,44 +2,52 @@ package tcp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/schollz/croc/v9/src/crypt"
|
||||||
log "github.com/schollz/logger"
|
log "github.com/schollz/logger"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkConnection(b *testing.B) {
|
// func BenchmarkConnection(b *testing.B) {
|
||||||
log.SetLevel("trace")
|
// log.SetLevel("trace")
|
||||||
go Run("debug", "8283", "pass123", "8284")
|
// go Run("debug", "8283", "pass123", "8284")
|
||||||
time.Sleep(100 * time.Millisecond)
|
// time.Sleep(100 * time.Millisecond)
|
||||||
b.ResetTimer()
|
// b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
c, _, _, _ := ConnectToTCPServer("localhost:8283", "pass123", fmt.Sprintf("testroom%d", i), 1*time.Minute)
|
// c, _, _, _ := ConnectToTCPServer("localhost:8283", "pass123", fmt.Sprintf("testroom%d", i), 1*time.Minute)
|
||||||
c.Close()
|
// c.Close()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func TestTCP(t *testing.T) {
|
func TestTCP(t *testing.T) {
|
||||||
log.SetLevel("error")
|
log.SetLevel("error")
|
||||||
timeToRoomDeletion = 100 * time.Millisecond
|
timeToRoomDeletion = 100 * time.Millisecond
|
||||||
go Run("debug", "8281", "pass123", "8282")
|
keyPublic, keyPrivate, err := crypt.NewAge()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
go Run("debug", "8281", "pass123", keyPublic, keyPrivate, "8282")
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
err := PingServer("localhost:8281")
|
err = PingServer("localhost:8281")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
err = PingServer("localhost:8333")
|
err = PingServer("localhost:8333")
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
c1, banner, _, err := ConnectToTCPServer("localhost:8281", "pass123", "testRoom", 1*time.Minute)
|
c1, banner, _, err := ConnectToTCPServer("localhost:8281", "pass123", keyPublic, "testRoom", 1*time.Minute)
|
||||||
assert.Equal(t, banner, "8282")
|
assert.Equal(t, banner, "8282")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
c2, _, _, err := ConnectToTCPServer("localhost:8281", "pass123", "testRoom")
|
c2, _, _, err := ConnectToTCPServer("localhost:8281", "pass123", keyPublic, "testRoom")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass123", "testRoom")
|
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass123", keyPublic, "testRoom")
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass123", "testRoom", 1*time.Nanosecond)
|
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass123", keyPublic, "testRoom", 1*time.Nanosecond)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass123", keyPublic+"askldjfklsajdf", "testRoom2")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass125", keyPublic, "testRoom3")
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
// try sending data
|
// try sending data
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue