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 .PHONY: lint vis clean common client server passwd subpkgs install uninstall reinstall
## Tag version of binaries with build info wrt. ## 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 // TODO: reduce gocyclo
func main() { func main() {
var vopt bool var (
var gopt bool //login via password, asking server to generate authToken isInteractive bool
var dbg bool vopt bool
var shellMode bool // if true act as shell, else file copier gopt bool //login via password, asking server to generate authToken
var cipherAlg string //cipher alg dbg bool
var hmacAlg string //hmac alg shellMode bool // if true act as shell, else file copier
var kexAlg string //KEX/KEM alg cipherAlg string //cipher alg
var server string hmacAlg string //hmac alg
var port uint kexAlg string //KEX/KEM alg
var cmdStr string server string
var tunSpecStr string // lport1:rport1[,lport2:rport2,...] port uint
cmdStr string
tunSpecStr string // lport1:rport1[,lport2:rport2,...]
var copySrc []byte copySrc []byte
var copyDst string copyDst string
var copyQuiet bool copyQuiet bool
var copyLimitBPS uint copyLimitBPS uint
var authCookie string authCookie string
var chaffEnabled bool chaffEnabled bool
var chaffFreqMin uint chaffFreqMin uint
var chaffFreqMax uint chaffFreqMax uint
var chaffBytesMax uint chaffBytesMax uint
var op []byte op []byte
isInteractive := false )
//=== Common (xs and xc) option parsing
flag.BoolVar(&vopt, "v", false, "show version") flag.BoolVar(&vopt, "v", false, "show version")
flag.BoolVar(&dbg, "d", false, "debug logging") flag.BoolVar(&dbg, "d", false, "debug logging")
@ -720,6 +724,8 @@ func main() {
flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to <`file`>") flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to <`file`>")
flag.StringVar(&memprofile, "memprofile", "", "write memory 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) // Find out what program we are (shell or copier)
myPath := strings.Split(os.Args[0], string(os.PathSeparator)) myPath := strings.Split(os.Args[0], string(os.PathSeparator))
if myPath[len(myPath)-1] != "xc" && if myPath[len(myPath)-1] != "xc" &&
@ -745,6 +751,8 @@ func main() {
exitWithStatus(0) exitWithStatus(0)
} }
//=== Profiling instrumentation
if cpuprofile != "" { if cpuprofile != "" {
f, err := os.Create(cpuprofile) f, err := os.Create(cpuprofile)
if err != nil { if err != nil {
@ -761,6 +769,8 @@ func main() {
go func() { http.ListenAndServe("localhost:6060", nil) }() go func() { http.ListenAndServe("localhost:6060", nil) }()
} }
//=== User, host, port and path args for file operations, if applicable
remoteUser, remoteHost, tmpPath, pathIsDest, otherArgs := remoteUser, remoteHost, tmpPath, pathIsDest, otherArgs :=
parseNonSwitchArgs(flag.Args()) parseNonSwitchArgs(flag.Args())
//fmt.Println("otherArgs:", otherArgs) //fmt.Println("otherArgs:", otherArgs)
@ -781,6 +791,8 @@ func main() {
tmpPath = "." tmpPath = "."
} }
//=== Copy mode arg and copy src/dest setup
var fileArgs string var fileArgs string
if !shellMode /*&& tmpPath != ""*/ { if !shellMode /*&& tmpPath != ""*/ {
// -if pathIsSrc && len(otherArgs) > 1 ERROR // -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) //fmt.Println("server finally is:", server)
if flag.NFlag() == 0 && 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") log.Fatal("incompatible options -- either cmd (-x) or copy ops but not both")
} }
//-------------------------------------------------------------------
// Here we have parsed all options and can now carry out // Here we have parsed all options and can now carry out
// either the shell session or copy operation. // either the shell session or copy operation.
_ = shellMode _ = shellMode
@ -837,6 +848,8 @@ func main() {
log.SetOutput(ioutil.Discard) log.SetOutput(ioutil.Discard)
} }
//=== Auth token fetch for login
if !gopt { if !gopt {
// See if we can log in via an auth token // See if we can log in via an auth token
u, _ := user.Current() // nolint: gosec 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 { if chaffFreqMin < 2 {
chaffFreqMin = 2 chaffFreqMin = 2
} }
@ -869,6 +882,8 @@ func main() {
chaffBytesMax = 64 chaffBytesMax = 64
} }
//=== Shell vs. Copy mode chaff and cmd setup
if shellMode { if shellMode {
// We must make the decision about interactivity before Dial() // We must make the decision about interactivity before Dial()
// as it affects chaffing behaviour. 20180805 // as it affects chaffing behaviour. 20180805
@ -909,6 +924,8 @@ func main() {
} }
} }
//=== TCP / KCP Dial setup
proto := "tcp" proto := "tcp"
if kcpMode != "unused" { if kcpMode != "unused" {
proto = "kcp" proto = "kcp"
@ -919,13 +936,15 @@ func main() {
exitWithStatus(3) exitWithStatus(3)
} }
//=== Shell terminal mode (Shell vs. Copy) setup
// Set stdin in raw mode if it's an interactive session // Set stdin in raw mode if it's an interactive session
// TODO: send flag to server side indicating this // TODO: send flag to server side indicating this
// affects shell command used // affects shell command used
var oldState *xs.State var oldState *xs.State
defer conn.Close() // nolint: errcheck 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 shellMode {
if isatty.IsTerminal(os.Stdin.Fd()) { 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 // Start login timeout here and disconnect if user/pass phase stalls
//iloginImpatience := time.AfterFunc(20*time.Second, func() { //iloginImpatience := time.AfterFunc(20*time.Second, func() {
//i fmt.Printf(" .. [you still there? Waiting for a password.]") //i fmt.Printf(" .. [you still there? Waiting for a password.]")
@ -961,12 +982,14 @@ func main() {
} }
authCookie = string(ab) authCookie = string(ab)
} }
//i_ = loginImpatience.Stop() //i_ = loginImpatience.Stop()
_ = loginTimeout.Stop() _ = loginTimeout.Stop()
// Security scrub // Security scrub
runtime.GC() runtime.GC()
//=== Session param and TERM setup
// Set up session params and send over to server // 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) rec := xs.NewSession(op, []byte(uname), []byte(remoteHost), []byte(os.Getenv("TERM")), []byte(cmdStr), []byte(authCookie), 0)
sendErr := sendSessionParams(&conn, rec) sendErr := sendSessionParams(&conn, rec)
@ -982,17 +1005,21 @@ func main() {
authCookie = "" // nolint: ineffassign authCookie = "" // nolint: ineffassign
runtime.GC() runtime.GC()
// Read auth reply from server //=== Login Auth
//=== Read auth reply from server
authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass
_, err = conn.Read(authReply) _, err = conn.Read(authReply)
if err != nil { if err != nil {
//=== Exit if auth reply not received
fmt.Fprintln(os.Stderr, "Error reading auth reply") // nolint: errcheck fmt.Fprintln(os.Stderr, "Error reading auth reply") // nolint: errcheck
rec.SetStatus(255) rec.SetStatus(255)
} else if authReply[0] == 0 { } else if authReply[0] == 0 {
//=== .. or if auth failed
fmt.Fprintln(os.Stderr, rejectUserMsg()) // nolint: errcheck fmt.Fprintln(os.Stderr, rejectUserMsg()) // nolint: errcheck
rec.SetStatus(255) rec.SetStatus(255)
} else { } else {
// Set up chaffing to server //=== Set up chaffing to server
conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing
if chaffEnabled { if chaffEnabled {
// #gv:s/label=\"main\$2\"/label=\"deferCloseChaff\"/ // #gv:s/label=\"main\$2\"/label=\"deferCloseChaff\"/
@ -1002,7 +1029,7 @@ func main() {
defer conn.ShutdownChaff() defer conn.ShutdownChaff()
} }
// Keepalive for any tunnels that may exist //=== (goroutine) Start keepAliveWorker for tunnels
// #gv:s/label=\"main\$1\"/label=\"tunKeepAlive\"/ // #gv:s/label=\"main\$1\"/label=\"tunKeepAlive\"/
// TODO:.gv:main:1:tunKeepAlive // TODO:.gv:main:1:tunKeepAlive
//[1]: better to always send tunnel keepAlives even if client didn't specify //[1]: better to always send tunnel keepAlives even if client didn't specify
@ -1021,10 +1048,13 @@ func main() {
go keepAliveWorker() go keepAliveWorker()
//[1]} //[1]}
//=== Session entry (shellMode or copyMode)
if shellMode { if shellMode {
//=== (shell) launch tunnels
launchTuns(&conn, remoteHost, tunSpecStr) launchTuns(&conn, remoteHost, tunSpecStr)
doShellMode(isInteractive, &conn, oldState, rec) doShellMode(isInteractive, &conn, oldState, rec)
} else { // copyMode } else {
//=== (.. or file copy)
s, _ := doCopyMode(&conn, pathIsDest, fileArgs, copyQuiet, copyLimitBPS, rec) // nolint: errcheck,gosec s, _ := doCopyMode(&conn, pathIsDest, fileArgs, copyQuiet, copyLimitBPS, rec) // nolint: errcheck,gosec
rec.SetStatus(s) rec.SetStatus(s)
} }
@ -1040,6 +1070,7 @@ func main() {
oldState = nil oldState = nil
} }
//=== Exit
exitWithStatus(int(rec.Status())) exitWithStatus(int(rec.Status()))
} }

View File

@ -62,12 +62,12 @@ const (
CSOTermSize // set term size (rows:cols) CSOTermSize // set term size (rows:cols)
CSOExitStatus // Remote cmd exit status CSOExitStatus // Remote cmd exit status
CSOChaff // Dummy packet, do not pass beyond decryption CSOChaff // Dummy packet, do not pass beyond decryption
// Client side errors // Client side errors
CSOLoginTimeout = 16 CSOLoginTimeout
// Tunnel setup/control/status // 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 CSOTunSetupAck // server -> client tunnel setup ack
CSOTunRefused // server -> client: tunnel rport connection refused CSOTunRefused // server -> client: tunnel rport connection refused
CSOTunData // packet contains tunnel data [rport:data] CSOTunData // packet contains tunnel data [rport:data]