mirror of https://gogs.blitter.com/RLabs/xs
Fixed misuse of iota in xsnet/consts.go that broke channel status opcodes
Cleaned up var declarations and added some greppable comments to show xs setup & flow
This commit is contained in:
parent
1b01ed14f2
commit
eb373ff37b
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION := 0.8.23
|
||||
VERSION := 0.8.24
|
||||
.PHONY: lint vis clean common client server passwd subpkgs install uninstall reinstall
|
||||
|
||||
## Tag version of binaries with build info wrt.
|
||||
|
|
93
xs/xs.go
93
xs/xs.go
|
@ -678,31 +678,35 @@ func sendSessionParams(conn io.Writer /* *xsnet.Conn*/, rec *xs.Session) (e erro
|
|||
|
||||
// TODO: reduce gocyclo
|
||||
func main() {
|
||||
var vopt bool
|
||||
var gopt bool //login via password, asking server to generate authToken
|
||||
var dbg bool
|
||||
var shellMode bool // if true act as shell, else file copier
|
||||
var cipherAlg string //cipher alg
|
||||
var hmacAlg string //hmac alg
|
||||
var kexAlg string //KEX/KEM alg
|
||||
var server string
|
||||
var port uint
|
||||
var cmdStr string
|
||||
var tunSpecStr string // lport1:rport1[,lport2:rport2,...]
|
||||
var (
|
||||
isInteractive bool
|
||||
vopt bool
|
||||
gopt bool //login via password, asking server to generate authToken
|
||||
dbg bool
|
||||
shellMode bool // if true act as shell, else file copier
|
||||
cipherAlg string //cipher alg
|
||||
hmacAlg string //hmac alg
|
||||
kexAlg string //KEX/KEM alg
|
||||
server string
|
||||
port uint
|
||||
cmdStr string
|
||||
tunSpecStr string // lport1:rport1[,lport2:rport2,...]
|
||||
|
||||
var copySrc []byte
|
||||
var copyDst string
|
||||
var copyQuiet bool
|
||||
var copyLimitBPS uint
|
||||
copySrc []byte
|
||||
copyDst string
|
||||
copyQuiet bool
|
||||
copyLimitBPS uint
|
||||
|
||||
var authCookie string
|
||||
var chaffEnabled bool
|
||||
var chaffFreqMin uint
|
||||
var chaffFreqMax uint
|
||||
var chaffBytesMax uint
|
||||
authCookie string
|
||||
chaffEnabled bool
|
||||
chaffFreqMin uint
|
||||
chaffFreqMax uint
|
||||
chaffBytesMax uint
|
||||
|
||||
var op []byte
|
||||
isInteractive := false
|
||||
op []byte
|
||||
)
|
||||
|
||||
//=== Common (xs and xc) option parsing
|
||||
|
||||
flag.BoolVar(&vopt, "v", false, "show version")
|
||||
flag.BoolVar(&dbg, "d", false, "debug logging")
|
||||
|
@ -720,6 +724,8 @@ func main() {
|
|||
flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to <`file`>")
|
||||
flag.StringVar(&memprofile, "memprofile", "", "write memory profile to <`file`>")
|
||||
|
||||
//=== xc vs. xs option parsing
|
||||
|
||||
// Find out what program we are (shell or copier)
|
||||
myPath := strings.Split(os.Args[0], string(os.PathSeparator))
|
||||
if myPath[len(myPath)-1] != "xc" &&
|
||||
|
@ -745,6 +751,8 @@ func main() {
|
|||
exitWithStatus(0)
|
||||
}
|
||||
|
||||
//=== Profiling instrumentation
|
||||
|
||||
if cpuprofile != "" {
|
||||
f, err := os.Create(cpuprofile)
|
||||
if err != nil {
|
||||
|
@ -761,6 +769,8 @@ func main() {
|
|||
go func() { http.ListenAndServe("localhost:6060", nil) }()
|
||||
}
|
||||
|
||||
//=== User, host, port and path args for file operations, if applicable
|
||||
|
||||
remoteUser, remoteHost, tmpPath, pathIsDest, otherArgs :=
|
||||
parseNonSwitchArgs(flag.Args())
|
||||
//fmt.Println("otherArgs:", otherArgs)
|
||||
|
@ -781,6 +791,8 @@ func main() {
|
|||
tmpPath = "."
|
||||
}
|
||||
|
||||
//=== Copy mode arg and copy src/dest setup
|
||||
|
||||
var fileArgs string
|
||||
if !shellMode /*&& tmpPath != ""*/ {
|
||||
// -if pathIsSrc && len(otherArgs) > 1 ERROR
|
||||
|
@ -812,7 +824,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
// Do some more option consistency checks
|
||||
//=== Do some final option consistency checks
|
||||
|
||||
//fmt.Println("server finally is:", server)
|
||||
if flag.NFlag() == 0 && server == "" {
|
||||
|
@ -824,7 +836,6 @@ func main() {
|
|||
log.Fatal("incompatible options -- either cmd (-x) or copy ops but not both")
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Here we have parsed all options and can now carry out
|
||||
// either the shell session or copy operation.
|
||||
_ = shellMode
|
||||
|
@ -837,6 +848,8 @@ func main() {
|
|||
log.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
//=== Auth token fetch for login
|
||||
|
||||
if !gopt {
|
||||
// See if we can log in via an auth token
|
||||
u, _ := user.Current() // nolint: gosec
|
||||
|
@ -858,7 +871,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
// Enforce some sane min/max vals on chaff flags
|
||||
//=== Enforce some sane min/max vals on chaff flags
|
||||
if chaffFreqMin < 2 {
|
||||
chaffFreqMin = 2
|
||||
}
|
||||
|
@ -869,6 +882,8 @@ func main() {
|
|||
chaffBytesMax = 64
|
||||
}
|
||||
|
||||
//=== Shell vs. Copy mode chaff and cmd setup
|
||||
|
||||
if shellMode {
|
||||
// We must make the decision about interactivity before Dial()
|
||||
// as it affects chaffing behaviour. 20180805
|
||||
|
@ -909,6 +924,8 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
//=== TCP / KCP Dial setup
|
||||
|
||||
proto := "tcp"
|
||||
if kcpMode != "unused" {
|
||||
proto = "kcp"
|
||||
|
@ -919,13 +936,15 @@ func main() {
|
|||
exitWithStatus(3)
|
||||
}
|
||||
|
||||
//=== Shell terminal mode (Shell vs. Copy) setup
|
||||
|
||||
// Set stdin in raw mode if it's an interactive session
|
||||
// TODO: send flag to server side indicating this
|
||||
// affects shell command used
|
||||
var oldState *xs.State
|
||||
defer conn.Close() // nolint: errcheck
|
||||
|
||||
// From this point on, conn is a secure encrypted channel
|
||||
//=== From this point on, conn is a secure encrypted channel
|
||||
|
||||
if shellMode {
|
||||
if isatty.IsTerminal(os.Stdin.Fd()) {
|
||||
|
@ -941,6 +960,8 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
//=== Login phase
|
||||
|
||||
// Start login timeout here and disconnect if user/pass phase stalls
|
||||
//iloginImpatience := time.AfterFunc(20*time.Second, func() {
|
||||
//i fmt.Printf(" .. [you still there? Waiting for a password.]")
|
||||
|
@ -961,12 +982,14 @@ func main() {
|
|||
}
|
||||
authCookie = string(ab)
|
||||
}
|
||||
|
||||
|
||||
//i_ = loginImpatience.Stop()
|
||||
_ = loginTimeout.Stop()
|
||||
// Security scrub
|
||||
runtime.GC()
|
||||
|
||||
//=== Session param and TERM setup
|
||||
|
||||
// Set up session params and send over to server
|
||||
rec := xs.NewSession(op, []byte(uname), []byte(remoteHost), []byte(os.Getenv("TERM")), []byte(cmdStr), []byte(authCookie), 0)
|
||||
sendErr := sendSessionParams(&conn, rec)
|
||||
|
@ -982,17 +1005,21 @@ func main() {
|
|||
authCookie = "" // nolint: ineffassign
|
||||
runtime.GC()
|
||||
|
||||
// Read auth reply from server
|
||||
//=== Login Auth
|
||||
|
||||
//=== Read auth reply from server
|
||||
authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass
|
||||
_, err = conn.Read(authReply)
|
||||
if err != nil {
|
||||
//=== Exit if auth reply not received
|
||||
fmt.Fprintln(os.Stderr, "Error reading auth reply") // nolint: errcheck
|
||||
rec.SetStatus(255)
|
||||
} else if authReply[0] == 0 {
|
||||
//=== .. or if auth failed
|
||||
fmt.Fprintln(os.Stderr, rejectUserMsg()) // nolint: errcheck
|
||||
rec.SetStatus(255)
|
||||
} else {
|
||||
// Set up chaffing to server
|
||||
//=== Set up chaffing to server
|
||||
conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing
|
||||
if chaffEnabled {
|
||||
// #gv:s/label=\"main\$2\"/label=\"deferCloseChaff\"/
|
||||
|
@ -1002,7 +1029,7 @@ func main() {
|
|||
defer conn.ShutdownChaff()
|
||||
}
|
||||
|
||||
// Keepalive for any tunnels that may exist
|
||||
//=== (goroutine) Start keepAliveWorker for tunnels
|
||||
// #gv:s/label=\"main\$1\"/label=\"tunKeepAlive\"/
|
||||
// TODO:.gv:main:1:tunKeepAlive
|
||||
//[1]: better to always send tunnel keepAlives even if client didn't specify
|
||||
|
@ -1021,10 +1048,13 @@ func main() {
|
|||
go keepAliveWorker()
|
||||
//[1]}
|
||||
|
||||
//=== Session entry (shellMode or copyMode)
|
||||
if shellMode {
|
||||
//=== (shell) launch tunnels
|
||||
launchTuns(&conn, remoteHost, tunSpecStr)
|
||||
doShellMode(isInteractive, &conn, oldState, rec)
|
||||
} else { // copyMode
|
||||
} else {
|
||||
//=== (.. or file copy)
|
||||
s, _ := doCopyMode(&conn, pathIsDest, fileArgs, copyQuiet, copyLimitBPS, rec) // nolint: errcheck,gosec
|
||||
rec.SetStatus(s)
|
||||
}
|
||||
|
@ -1040,6 +1070,7 @@ func main() {
|
|||
oldState = nil
|
||||
}
|
||||
|
||||
//=== Exit
|
||||
exitWithStatus(int(rec.Status()))
|
||||
}
|
||||
|
||||
|
|
|
@ -62,12 +62,12 @@ const (
|
|||
CSOTermSize // set term size (rows:cols)
|
||||
CSOExitStatus // Remote cmd exit status
|
||||
CSOChaff // Dummy packet, do not pass beyond decryption
|
||||
|
||||
|
||||
// Client side errors
|
||||
CSOLoginTimeout = 16
|
||||
CSOLoginTimeout
|
||||
|
||||
// Tunnel setup/control/status
|
||||
CSOTunSetup = 32 // client -> server tunnel setup request (dstport)
|
||||
CSOTunSetup // client -> server tunnel setup request (dstport)
|
||||
CSOTunSetupAck // server -> client tunnel setup ack
|
||||
CSOTunRefused // server -> client: tunnel rport connection refused
|
||||
CSOTunData // packet contains tunnel data [rport:data]
|
||||
|
|
Loading…
Reference in New Issue