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:
Russ Magee 2020-07-24 21:47:29 -07:00
parent 1b01ed14f2
commit eb373ff37b
3 changed files with 66 additions and 35 deletions

View File

@ -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.

View File

@ -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()))
}

View File

@ -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]