2018-10-16 21:23:01 +02:00
package cli
import (
2019-07-18 00:19:32 +02:00
"encoding/json"
2019-04-30 01:09:37 +02:00
"errors"
2018-10-16 21:23:01 +02:00
"fmt"
"io"
"io/ioutil"
"os"
2019-07-17 23:55:43 +02:00
"path"
2018-10-16 21:23:01 +02:00
"path/filepath"
2018-10-23 05:34:04 +02:00
"runtime"
2018-10-16 21:23:01 +02:00
"strings"
"time"
2020-09-17 22:04:33 +02:00
"github.com/schollz/cli/v2"
2021-04-17 19:33:38 +02:00
"github.com/schollz/croc/v9/src/comm"
"github.com/schollz/croc/v9/src/croc"
2021-04-24 01:59:28 +02:00
"github.com/schollz/croc/v9/src/crypt"
2021-04-17 19:33:38 +02:00
"github.com/schollz/croc/v9/src/models"
"github.com/schollz/croc/v9/src/tcp"
"github.com/schollz/croc/v9/src/utils"
2019-07-17 22:33:02 +02:00
log "github.com/schollz/logger"
2021-04-17 18:42:11 +02:00
"github.com/schollz/pake/v3"
2018-10-16 21:23:01 +02:00
)
2019-09-07 18:46:04 +02:00
// Version specifies the version
2018-10-16 21:23:01 +02:00
var Version string
2020-09-23 12:58:00 +02:00
// Run will run the command line program
2019-04-30 01:09:37 +02:00
func Run ( ) ( err error ) {
2019-05-03 22:51:27 +02:00
// use all of the processors
2018-10-23 05:34:04 +02:00
runtime . GOMAXPROCS ( runtime . NumCPU ( ) )
2019-05-02 22:14:09 +02:00
2018-10-16 21:23:01 +02:00
app := cli . NewApp ( )
app . Name = "croc"
if Version == "" {
2021-04-21 00:57:46 +02:00
Version = "v9.1.0-35106d4"
2018-10-16 21:23:01 +02:00
}
app . Version = Version
app . Compiled = time . Now ( )
app . Usage = "easily and securely transfer stuff from one computer to another"
2019-11-17 22:19:27 +01:00
app . UsageText = ` Send a file :
croc send file . txt
Send a file with a custom code :
2020-10-14 00:47:53 +02:00
croc send -- code secret - code file . txt
Receive a file using code :
croc secret - code `
2020-09-09 17:05:57 +02:00
app . Commands = [ ] * cli . Command {
2018-10-16 21:23:01 +02:00
{
Name : "send" ,
2019-11-17 22:19:27 +01:00
Usage : "send a file (see options with croc send -h)" ,
2018-10-16 21:23:01 +02:00
Description : "send a file over the relay" ,
ArgsUsage : "[filename]" ,
Flags : [ ] cli . Flag {
2020-09-09 05:52:42 +02:00
& cli . StringFlag { Name : "code" , Aliases : [ ] string { "c" } , Usage : "codephrase used to connect to relay" } ,
& cli . StringFlag { Name : "text" , Aliases : [ ] string { "t" } , Usage : "send some text" } ,
2020-09-09 17:05:57 +02:00
& cli . BoolFlag { Name : "no-local" , Usage : "disable local relay when sending" } ,
& cli . BoolFlag { Name : "no-multi" , Usage : "disable multiplexing" } ,
& cli . StringFlag { Name : "ports" , Value : "9009,9010,9011,9012,9013" , Usage : "ports of the local relay (optional)" } ,
2018-10-16 21:23:01 +02:00
} ,
HelpName : "croc send" ,
Action : func ( c * cli . Context ) error {
return send ( c )
} ,
} ,
2019-04-30 06:25:30 +02:00
{
Name : "relay" ,
2019-11-17 22:19:27 +01:00
Usage : "start your own relay (optional)" ,
2019-04-30 06:25:30 +02:00
Description : "start relay" ,
HelpName : "croc relay" ,
Action : func ( c * cli . Context ) error {
return relay ( c )
} ,
2019-05-01 21:48:09 +02:00
Flags : [ ] cli . Flag {
2020-09-09 17:05:57 +02:00
& cli . StringFlag { Name : "ports" , Value : "9009,9010,9011,9012,9013" , Usage : "ports of the relay" } ,
2021-04-24 01:59:28 +02:00
& cli . StringFlag { Name : "identity" , Value : "" , Usage : "identity file with credentials" } ,
2019-05-01 21:48:09 +02:00
} ,
2019-04-30 06:25:30 +02:00
} ,
2018-10-16 21:23:01 +02:00
}
app . Flags = [ ] cli . Flag {
2020-09-09 17:05:57 +02:00
& 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" } ,
2020-10-21 19:23:12 +02:00
& cli . BoolFlag { Name : "local" , Usage : "force to use only local connections" } ,
2021-02-01 15:58:27 +01:00
& cli . BoolFlag { Name : "ignore-stdin" , Usage : "ignore piped stdin" } ,
2021-04-17 00:14:21 +02:00
& cli . BoolFlag { Name : "overwrite" , Usage : "do not prompt to overwrite" } ,
2021-04-17 18:01:58 +02:00
& cli . StringFlag { Name : "curve" , Value : "siec" , Usage : "choose an encryption curve (" + strings . Join ( pake . AvailableCurves ( ) , ", " ) + ")" } ,
2020-12-17 16:37:48 +01:00
& cli . StringFlag { Name : "ip" , Value : "" , Usage : "set sender ip if known e.g. 10.0.0.1:9009, [::1]:9009" } ,
2020-09-09 17:25:13 +02:00
& 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" } } ,
2020-09-09 17:05:57 +02:00
& cli . StringFlag { Name : "out" , Value : "." , Usage : "specify an output folder to receive the file" } ,
2021-04-24 01:59:28 +02:00
& 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" } } ,
2020-10-14 00:47:00 +02:00
& cli . StringFlag { Name : "socks5" , Value : "" , Usage : "add a socks5 proxy" , EnvVars : [ ] string { "SOCKS5_PROXY" } } ,
2018-10-16 21:23:01 +02:00
}
app . EnableBashCompletion = true
app . HideHelp = false
app . HideVersion = false
app . Action = func ( c * cli . Context ) error {
2020-09-19 17:52:32 +02:00
allStringsAreFiles := func ( strs [ ] string ) bool {
for _ , str := range strs {
if ! utils . Exists ( str ) {
2020-10-05 17:30:45 +02:00
return false
2020-09-19 17:52:32 +02:00
}
}
2020-10-05 17:30:45 +02:00
return true
2020-09-19 17:52:32 +02:00
}
2018-11-01 15:08:57 +01:00
// if trying to send but forgot send, let the user know
2020-09-19 17:52:32 +02:00
if c . Args ( ) . Present ( ) && allStringsAreFiles ( c . Args ( ) . Slice ( ) ) {
fnames := [ ] string { }
for _ , fpath := range c . Args ( ) . Slice ( ) {
_ , basename := filepath . Split ( fpath )
2020-10-05 17:30:45 +02:00
fnames = append ( fnames , "'" + basename + "'" )
2020-09-19 17:52:32 +02:00
}
yn := utils . GetInput ( fmt . Sprintf ( "Did you mean to send %s? (y/n) " , strings . Join ( fnames , ", " ) ) )
2018-11-01 15:08:57 +01:00
if strings . ToLower ( yn ) == "y" {
return send ( c )
}
}
2018-10-16 21:23:01 +02:00
return receive ( c )
}
2019-04-30 01:09:37 +02:00
return app . Run ( os . Args )
2018-10-16 21:23:01 +02:00
}
2019-07-17 23:55:43 +02:00
func getConfigDir ( ) ( homedir string , err error ) {
homedir , err = os . UserHomeDir ( )
2019-07-17 22:33:02 +02:00
if err != nil {
log . Error ( err )
return
}
2021-04-17 00:14:21 +02:00
2021-03-20 00:50:50 +01:00
if envHomedir , isSet := os . LookupEnv ( "CROC_CONFIG_DIR" ) ; isSet {
homedir = envHomedir
} else if xdgConfigHome , isSet := os . LookupEnv ( "XDG_CONFIG_HOME" ) ; isSet {
2021-03-17 17:45:07 +01:00
homedir = path . Join ( xdgConfigHome , "croc" )
2021-03-20 00:50:50 +01:00
} else {
homedir = path . Join ( homedir , ".config" , "croc" )
2021-03-17 17:45:07 +01:00
}
2021-04-17 00:14:21 +02:00
2019-09-07 18:49:08 +02:00
if _ , err = os . Stat ( homedir ) ; os . IsNotExist ( err ) {
2019-07-17 23:55:43 +02:00
log . Debugf ( "creating home directory %s" , homedir )
err = os . MkdirAll ( homedir , 0700 )
}
2019-07-17 22:33:02 +02:00
return
}
2019-04-30 01:09:37 +02:00
2019-09-20 18:20:50 +02:00
func setDebugLevel ( c * cli . Context ) {
2020-09-09 17:05:57 +02:00
if c . Bool ( "debug" ) {
2019-07-18 00:19:32 +02:00
log . SetLevel ( "debug" )
log . Debug ( "debug mode on" )
2019-07-18 15:17:15 +02:00
} else {
log . SetLevel ( "info" )
2019-07-18 00:19:32 +02:00
}
2019-09-20 18:20:50 +02:00
}
func getConfigFile ( ) string {
2019-07-18 00:19:32 +02:00
configFile , err := getConfigDir ( )
if err != nil {
log . Error ( err )
2019-09-20 18:20:50 +02:00
return ""
2019-07-18 00:19:32 +02:00
}
2019-09-20 18:20:50 +02:00
return path . Join ( configFile , "send.json" )
}
2019-09-20 18:24:10 +02:00
2019-09-20 18:20:50 +02:00
func send ( c * cli . Context ) ( err error ) {
setDebugLevel ( c )
2020-10-05 17:30:45 +02:00
comm . Socks5Proxy = c . String ( "socks5" )
2019-07-18 02:06:52 +02:00
crocOptions := croc . Options {
2019-11-18 16:57:12 +01:00
SharedSecret : c . String ( "code" ) ,
IsSender : true ,
2020-09-09 17:05:57 +02:00
Debug : c . Bool ( "debug" ) ,
NoPrompt : c . Bool ( "yes" ) ,
RelayAddress : c . String ( "relay" ) ,
RelayAddress6 : c . String ( "relay6" ) ,
Stdout : c . Bool ( "stdout" ) ,
2019-11-18 16:57:12 +01:00
DisableLocal : c . Bool ( "no-local" ) ,
2020-10-21 19:23:12 +02:00
OnlyLocal : c . Bool ( "local" ) ,
2021-02-01 15:58:27 +01:00
IgnoreStdin : c . Bool ( "ignore-stdin" ) ,
2019-11-18 16:57:12 +01:00
RelayPorts : strings . Split ( c . String ( "ports" ) , "," ) ,
2020-09-09 17:05:57 +02:00
Ask : c . Bool ( "ask" ) ,
2019-11-18 16:57:12 +01:00
NoMultiplexing : c . Bool ( "no-multi" ) ,
2021-04-24 01:59:28 +02:00
RelayPassword : c . String ( "relay-pass" ) ,
RelayKeyPublic : c . String ( "relay-key" ) ,
2020-09-03 02:24:32 +02:00
SendingText : c . String ( "text" ) != "" ,
2020-09-09 17:05:57 +02:00
NoCompress : c . Bool ( "no-compress" ) ,
2021-04-17 00:14:21 +02:00
Overwrite : c . Bool ( "overwrite" ) ,
2021-04-17 18:01:58 +02:00
Curve : c . String ( "curve" ) ,
2021-04-21 00:32:05 +02:00
HashAlgorithm : "xxhash" ,
2019-07-18 02:06:52 +02:00
}
2020-08-27 18:40:41 +02:00
if crocOptions . RelayAddress != models . DEFAULT_RELAY {
crocOptions . RelayAddress6 = ""
} else if crocOptions . RelayAddress6 != models . DEFAULT_RELAY6 {
crocOptions . RelayAddress = ""
}
2019-09-20 18:20:50 +02:00
b , errOpen := ioutil . ReadFile ( getConfigFile ( ) )
2020-09-09 17:05:57 +02:00
if errOpen == nil && ! c . Bool ( "remember" ) {
2019-07-18 02:06:52 +02:00
var rememberedOptions croc . Options
err = json . Unmarshal ( b , & rememberedOptions )
2019-07-18 01:23:50 +02:00
if err != nil {
log . Error ( err )
return
}
2019-07-18 02:06:52 +02:00
// update anything that isn't explicitly set
2020-09-09 17:05:57 +02:00
if ! c . IsSet ( "relay" ) {
2019-07-18 02:06:52 +02:00
crocOptions . RelayAddress = rememberedOptions . RelayAddress
2019-07-18 01:23:50 +02:00
}
2019-07-18 02:06:52 +02:00
if ! c . IsSet ( "no-local" ) {
crocOptions . DisableLocal = rememberedOptions . DisableLocal
2019-07-18 01:23:50 +02:00
}
2019-07-18 02:06:52 +02:00
if ! c . IsSet ( "ports" ) {
crocOptions . RelayPorts = rememberedOptions . RelayPorts
2019-07-18 01:23:50 +02:00
}
2019-07-18 02:06:52 +02:00
if ! c . IsSet ( "code" ) {
crocOptions . SharedSecret = rememberedOptions . SharedSecret
2019-07-18 01:23:50 +02:00
}
2021-04-24 01:59:28 +02:00
if ! c . IsSet ( "relay-pass" ) {
2019-11-19 20:47:04 +01:00
crocOptions . RelayPassword = rememberedOptions . RelayPassword
}
2021-04-24 01:59:28 +02:00
if ! c . IsSet ( "relay-key" ) {
crocOptions . RelayKeyPublic = rememberedOptions . RelayKeyPublic
}
2019-07-18 01:23:50 +02:00
}
2019-04-30 01:09:37 +02:00
var fnames [ ] string
2018-10-16 21:23:01 +02:00
stat , _ := os . Stdin . Stat ( )
2021-02-01 15:58:27 +01:00
if ( ( stat . Mode ( ) & os . ModeCharDevice ) == 0 ) && ! c . Bool ( "ignore-stdin" ) {
2019-09-20 18:27:59 +02:00
fnames , err = getStdin ( )
2018-10-16 21:23:01 +02:00
if err != nil {
2019-09-20 18:27:59 +02:00
return
2018-10-16 21:23:01 +02:00
}
defer func ( ) {
2021-02-01 10:34:06 +01:00
e := os . Remove ( fnames [ 0 ] )
if e != nil {
log . Error ( e )
2018-10-16 21:23:01 +02:00
}
} ( )
2020-09-03 02:24:32 +02:00
} else if c . String ( "text" ) != "" {
fnames , err = makeTempFileWithString ( c . String ( "text" ) )
if err != nil {
return
}
defer func ( ) {
2021-02-01 10:34:06 +01:00
e := os . Remove ( fnames [ 0 ] )
if e != nil {
log . Error ( e )
2020-09-03 02:24:32 +02:00
}
} ( )
2018-10-16 21:23:01 +02:00
} else {
2020-09-19 21:48:11 +02:00
fnames = c . Args ( ) . Slice ( )
2018-10-16 21:23:01 +02:00
}
2019-04-30 01:09:37 +02:00
if len ( fnames ) == 0 {
2018-10-16 21:23:01 +02:00
return errors . New ( "must specify file: croc send [filename]" )
}
2019-04-30 01:09:37 +02:00
2019-07-18 01:23:50 +02:00
if len ( crocOptions . SharedSecret ) == 0 {
2018-10-16 21:23:01 +02:00
// generate code phrase
2019-07-18 01:23:50 +02:00
crocOptions . SharedSecret = utils . GetRandomName ( )
2018-10-16 21:23:01 +02:00
}
2019-09-20 18:24:10 +02:00
paths , haveFolder , err := getPaths ( fnames )
if err != nil {
return
}
cr , err := croc . New ( crocOptions )
if err != nil {
return
}
// save the config
saveConfig ( c , crocOptions )
err = cr . Send ( croc . TransferOptions {
PathToFiles : paths ,
KeepPathInRemote : haveFolder ,
} )
return
}
2019-09-20 18:27:59 +02:00
func getStdin ( ) ( fnames [ ] string , err error ) {
f , err := ioutil . TempFile ( "." , "croc-stdin-" )
if err != nil {
return
}
_ , err = io . Copy ( f , os . Stdin )
if err != nil {
return
}
err = f . Close ( )
if err != nil {
return
}
fnames = [ ] string { f . Name ( ) }
return
}
2020-09-03 02:24:32 +02:00
func makeTempFileWithString ( s string ) ( fnames [ ] string , err error ) {
f , err := ioutil . TempFile ( "." , "croc-stdin-" )
if err != nil {
return
}
_ , err = f . WriteString ( s )
if err != nil {
return
}
err = f . Close ( )
if err != nil {
return
}
fnames = [ ] string { f . Name ( ) }
return
}
2019-09-20 18:24:10 +02:00
func getPaths ( fnames [ ] string ) ( paths [ ] string , haveFolder bool , err error ) {
haveFolder = false
paths = [ ] string { }
2019-04-30 01:09:37 +02:00
for _ , fname := range fnames {
2021-04-15 17:07:23 +02:00
stat , errStat := os . Lstat ( fname )
2019-09-20 18:24:10 +02:00
if errStat != nil {
err = errStat
return
2018-10-16 21:23:01 +02:00
}
2019-04-30 01:09:37 +02:00
if stat . IsDir ( ) {
haveFolder = true
err = filepath . Walk ( fname ,
func ( pathName string , info os . FileInfo , err error ) error {
if err != nil {
return err
}
if ! info . IsDir ( ) {
paths = append ( paths , filepath . ToSlash ( pathName ) )
}
return nil
} )
if err != nil {
2019-09-20 18:24:10 +02:00
return
2019-04-30 01:09:37 +02:00
}
} else {
paths = append ( paths , filepath . ToSlash ( fname ) )
}
2018-10-16 21:23:01 +02:00
}
2019-09-20 18:20:50 +02:00
return
}
func saveConfig ( c * cli . Context , crocOptions croc . Options ) {
2020-09-09 17:05:57 +02:00
if c . Bool ( "remember" ) {
2019-09-20 18:20:50 +02:00
configFile := getConfigFile ( )
2019-07-18 00:19:32 +02:00
log . Debug ( "saving config file" )
var bConfig [ ] byte
2019-07-18 01:23:50 +02:00
// if the code wasn't set, don't save it
if c . String ( "code" ) == "" {
crocOptions . SharedSecret = ""
}
2019-09-20 18:20:50 +02:00
bConfig , err := json . MarshalIndent ( crocOptions , "" , " " )
2019-07-18 00:19:32 +02:00
if err != nil {
log . Error ( err )
return
}
err = ioutil . WriteFile ( configFile , bConfig , 0644 )
if err != nil {
log . Error ( err )
return
}
log . Debugf ( "wrote %s" , configFile )
}
2018-10-16 21:23:01 +02:00
}
2019-04-30 01:09:37 +02:00
func receive ( c * cli . Context ) ( err error ) {
2020-10-05 17:30:45 +02:00
comm . Socks5Proxy = c . String ( "socks5" )
2019-07-18 02:16:50 +02:00
crocOptions := croc . Options {
2021-04-24 01:59:28 +02:00
SharedSecret : c . String ( "code" ) ,
IsSender : false ,
Debug : c . Bool ( "debug" ) ,
NoPrompt : c . Bool ( "yes" ) ,
RelayAddress : c . String ( "relay" ) ,
RelayAddress6 : c . String ( "relay6" ) ,
Stdout : c . Bool ( "stdout" ) ,
Ask : c . Bool ( "ask" ) ,
RelayPassword : c . String ( "relay-pass" ) ,
RelayKeyPublic : c . String ( "relay-key" ) ,
OnlyLocal : c . Bool ( "local" ) ,
IP : c . String ( "ip" ) ,
Overwrite : c . Bool ( "overwrite" ) ,
Curve : c . String ( "curve" ) ,
HashAlgorithm : "xxhash" ,
2018-10-16 21:23:01 +02:00
}
2020-08-27 18:40:41 +02:00
if crocOptions . RelayAddress != models . DEFAULT_RELAY {
crocOptions . RelayAddress6 = ""
} else if crocOptions . RelayAddress6 != models . DEFAULT_RELAY6 {
crocOptions . RelayAddress = ""
}
2020-02-18 05:26:13 +01:00
2020-09-09 17:05:57 +02:00
switch c . Args ( ) . Len ( ) {
2020-02-18 05:26:13 +01:00
case 1 :
2019-07-18 02:16:50 +02:00
crocOptions . SharedSecret = c . Args ( ) . First ( )
2020-02-18 05:26:13 +01:00
case 3 :
var phrase [ ] string
phrase = append ( phrase , c . Args ( ) . First ( ) )
phrase = append ( phrase , c . Args ( ) . Tail ( ) ... )
crocOptions . SharedSecret = strings . Join ( phrase , "-" )
2019-04-30 01:09:37 +02:00
}
2019-07-18 02:16:50 +02:00
// load options here
2019-09-20 18:20:50 +02:00
setDebugLevel ( c )
2019-07-18 02:16:50 +02:00
configFile , err := getConfigDir ( )
if err != nil {
log . Error ( err )
return
}
configFile = path . Join ( configFile , "receive.json" )
b , errOpen := ioutil . ReadFile ( configFile )
2020-09-09 17:05:57 +02:00
if errOpen == nil && ! c . Bool ( "remember" ) {
2019-07-18 02:16:50 +02:00
var rememberedOptions croc . Options
err = json . Unmarshal ( b , & rememberedOptions )
if err != nil {
log . Error ( err )
return
}
2020-09-09 17:05:57 +02:00
// update anything that isn't expliciGlobalIsSettly set
if ! c . IsSet ( "relay" ) {
2019-07-18 02:16:50 +02:00
crocOptions . RelayAddress = rememberedOptions . RelayAddress
}
2020-09-09 17:05:57 +02:00
if ! c . IsSet ( "yes" ) {
2019-07-18 15:13:11 +02:00
crocOptions . NoPrompt = rememberedOptions . NoPrompt
}
2019-07-18 02:16:50 +02:00
if crocOptions . SharedSecret == "" {
crocOptions . SharedSecret = rememberedOptions . SharedSecret
}
2020-09-09 17:05:57 +02:00
if ! c . IsSet ( "pass" ) {
2019-11-19 21:06:12 +01:00
crocOptions . RelayPassword = rememberedOptions . RelayPassword
}
2019-07-18 02:16:50 +02:00
}
if crocOptions . SharedSecret == "" {
crocOptions . SharedSecret = utils . GetInput ( "Enter receive code: " )
2018-10-16 21:23:01 +02:00
}
2020-09-09 17:05:57 +02:00
if c . String ( "out" ) != "" {
if err = os . Chdir ( c . String ( "out" ) ) ; err != nil {
2020-08-23 01:05:00 +02:00
return err
}
2018-10-22 15:36:36 +02:00
}
2019-04-30 01:09:37 +02:00
2019-07-18 02:16:50 +02:00
cr , err := croc . New ( crocOptions )
2019-04-30 01:09:37 +02:00
if err != nil {
return
2018-10-19 19:18:49 +02:00
}
2019-07-18 15:13:11 +02:00
// save the config
2020-09-09 17:05:57 +02:00
if c . Bool ( "remember" ) {
2019-07-18 15:13:11 +02:00
log . Debug ( "saving config file" )
var bConfig [ ] byte
bConfig , err = json . MarshalIndent ( crocOptions , "" , " " )
if err != nil {
log . Error ( err )
return
}
err = ioutil . WriteFile ( configFile , bConfig , 0644 )
if err != nil {
log . Error ( err )
return
}
log . Debugf ( "wrote %s" , configFile )
}
2019-04-30 01:09:37 +02:00
err = cr . Receive ( )
return
2018-10-16 21:23:01 +02:00
}
2019-04-30 06:25:30 +02:00
func relay ( c * cli . Context ) ( err error ) {
2021-04-24 01:59:28 +02:00
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 )
2019-05-02 21:08:23 +02:00
debugString := "info"
2020-09-09 17:05:57 +02:00
if c . Bool ( "debug" ) {
2019-04-30 06:25:30 +02:00
debugString = "debug"
}
for i , port := range ports {
if i == 0 {
continue
}
go func ( portStr string ) {
2021-04-24 01:59:28 +02:00
err = tcp . Run ( debugString , portStr , password , keyPublic , keyPrivate )
2019-04-30 06:25:30 +02:00
if err != nil {
panic ( err )
}
} ( port )
}
2021-04-24 01:59:28 +02:00
return tcp . Run ( debugString , ports [ 0 ] , password , keyPublic , keyPrivate , tcpPorts )
2019-04-30 06:25:30 +02:00
}