mirror of https://gogs.blitter.com/RLabs/xs
xs/ lint cleanups
This commit is contained in:
parent
0f28d2c023
commit
667328a91c
|
@ -25,6 +25,8 @@ linters-settings:
|
|||
#- style
|
||||
#- opinionated
|
||||
disabled-checks:
|
||||
- commentFormatting
|
||||
- commentedOutCode
|
||||
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||
- ifElseChain
|
||||
- octalLiteral
|
||||
|
|
|
@ -31,7 +31,7 @@ func handleTermResizes(conn *xsnet.Conn) {
|
|||
log.Println(err)
|
||||
}
|
||||
termSzPacket := fmt.Sprintf("%d %d", rows, cols)
|
||||
conn.WritePacket([]byte(termSzPacket), xsnet.CSOTermSize)
|
||||
conn.WritePacket([]byte(termSzPacket), xsnet.CSOTermSize) //nolint:errcheck
|
||||
}
|
||||
}()
|
||||
ch <- syscall.SIGWINCH // Initial resize.
|
||||
|
|
183
xs/xs.go
183
xs/xs.go
|
@ -14,7 +14,6 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
|
@ -57,6 +56,18 @@ var (
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
const (
|
||||
CmdExitedEarly = 2
|
||||
XSNetDialFailed = 3
|
||||
ErrReadingAuthReply = 253
|
||||
ServerRejectedSecureProposal = 254
|
||||
GeneralProtocolErr = 255
|
||||
)
|
||||
|
||||
const (
|
||||
DeadCharPrefix = 0x1d
|
||||
)
|
||||
|
||||
// Praise Bob. Do not remove, lest ye lose Slack.
|
||||
const bob = string("\r\n\r\n" +
|
||||
"@@@@@@@^^~~~~~~~~~~~~~~~~~~~~^@@@@@@@@@\r\n" +
|
||||
|
@ -154,7 +165,7 @@ func copyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err er
|
|||
if rt, ok := dst.(io.ReaderFrom); ok {
|
||||
return rt.ReadFrom(src)
|
||||
}
|
||||
*/
|
||||
*/ //nolint:gocritic,nolintlint
|
||||
if buf == nil {
|
||||
size := 32 * 1024
|
||||
if l, ok := src.(*io.LimitedReader); ok && int64(size) > l.N {
|
||||
|
@ -175,8 +186,8 @@ func copyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err er
|
|||
// A repeat of 4 keys (conveniently 'dead' chars for most
|
||||
// interactive shells; here CTRL-]) shall introduce
|
||||
// some special responses or actions on the client side.
|
||||
if seqPos < 4 {
|
||||
if buf[0] == 0x1d {
|
||||
if seqPos < 4 { //nolint:gomnd
|
||||
if buf[0] == DeadCharPrefix {
|
||||
seqPos++
|
||||
}
|
||||
} else {
|
||||
|
@ -223,7 +234,7 @@ func GetSize() (cols, rows int, err error) {
|
|||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
cols, rows = 80, 24 //failsafe
|
||||
cols, rows = 80, 24 // failsafe
|
||||
} else {
|
||||
n, err := fmt.Sscanf(string(out), "%d %d\n", &rows, &cols)
|
||||
if n < 2 ||
|
||||
|
@ -257,7 +268,7 @@ func buildCmdRemoteToLocal(copyQuiet bool, copyLimitBPS uint, destPath string) (
|
|||
} else {
|
||||
// TODO: Query remote side for total file/dir size
|
||||
bandwidthInBytesPerSec := " -L " + fmt.Sprintf("%d ", copyLimitBPS)
|
||||
displayOpts := " -pre "
|
||||
displayOpts := " -pre " //nolint:goconst
|
||||
cmd = xs.GetTool("bash")
|
||||
args = []string{"-c", "pv " + displayOpts + bandwidthInBytesPerSec + "| tar -xz -C " + destPath}
|
||||
}
|
||||
|
@ -305,7 +316,7 @@ func buildCmdLocalToRemote(copyQuiet bool, copyLimitBPS uint, files string) (cap
|
|||
} else {
|
||||
captureStderr = copyQuiet
|
||||
bandwidthInBytesPerSec := " -L " + fmt.Sprintf("%d", copyLimitBPS)
|
||||
displayOpts := " -pre "
|
||||
displayOpts := " -pre " //nolint:goconst,nolintlint
|
||||
cmd = xs.GetTool("bash")
|
||||
args = []string{"-c", xs.GetTool("tar") + " -cz -f /dev/stdout "}
|
||||
files = strings.TrimSpace(files)
|
||||
|
@ -355,9 +366,9 @@ func doCopyMode(conn *xsnet.Conn, remoteDest bool, files string, copyQuiet bool,
|
|||
|
||||
var c *exec.Cmd
|
||||
|
||||
//os.Clearenv()
|
||||
//os.Setenv("HOME", u.HomeDir)
|
||||
//os.Setenv("TERM", "vt102") // TODO: server or client option?
|
||||
// os.Clearenv()
|
||||
// os.Setenv("HOME", u.HomeDir)
|
||||
// os.Setenv("TERM", "vt102") // TODO: server or client option?
|
||||
|
||||
captureStderr, cmdName, cmdArgs := buildCmdLocalToRemote(copyQuiet, copyLimitBPS, strings.TrimSpace(files))
|
||||
c = exec.Command(cmdName, cmdArgs...) // #nosec
|
||||
|
@ -390,7 +401,7 @@ func doCopyMode(conn *xsnet.Conn, remoteDest bool, files string, copyQuiet bool,
|
|||
if err != nil {
|
||||
fmt.Println("cmd exited immediately. Cannot get cmd.Wait().ExitStatus()")
|
||||
err = errors.New("cmd exited prematurely")
|
||||
exitStatus = uint32(2)
|
||||
exitStatus = uint32(CmdExitedEarly)
|
||||
} else {
|
||||
if err = c.Wait(); err != nil {
|
||||
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||
|
@ -410,7 +421,7 @@ func doCopyMode(conn *xsnet.Conn, remoteDest bool, files string, copyQuiet bool,
|
|||
}
|
||||
// send CSOExitStatus to inform remote (server) end cp is done
|
||||
log.Println("Sending local exitStatus:", exitStatus)
|
||||
r := make([]byte, 4)
|
||||
r := make([]byte, 4) //nolint:gomnd
|
||||
binary.BigEndian.PutUint32(r, exitStatus)
|
||||
_, we := conn.WritePacket(r, xsnet.CSOExitStatus)
|
||||
if we != nil {
|
||||
|
@ -418,7 +429,7 @@ func doCopyMode(conn *xsnet.Conn, remoteDest bool, files string, copyQuiet bool,
|
|||
}
|
||||
|
||||
// Do a final read for remote's exit status
|
||||
s := make([]byte, 4)
|
||||
s := make([]byte, 4) //nolint:gomnd
|
||||
_, remErr := conn.Read(s)
|
||||
if remErr != io.EOF &&
|
||||
!strings.Contains(remErr.Error(), "use of closed network") &&
|
||||
|
@ -478,8 +489,8 @@ func doCopyMode(conn *xsnet.Conn, remoteDest bool, files string, copyQuiet bool,
|
|||
// doShellMode begins an xs shell session (one-shot command or
|
||||
// interactive).
|
||||
func doShellMode(isInteractive bool, conn *xsnet.Conn, oldState *xs.State, rec *xs.Session) {
|
||||
//client reader (from server) goroutine
|
||||
//Read remote end's stdout
|
||||
// Client reader (from server) goroutine
|
||||
// Read remote end's stdout
|
||||
|
||||
wg.Add(1)
|
||||
// #gv:s/label=\"doShellMode\$1\"/label=\"shellRemoteToStdin\"/
|
||||
|
@ -602,7 +613,7 @@ func parseNonSwitchArgs(a []string) (user, host, path string, isDest bool, other
|
|||
if strings.Contains(arg, ":") || strings.Contains(arg, "@") {
|
||||
fancyArg := strings.Split(flag.Arg(i), "@")
|
||||
var fancyHostPath []string
|
||||
if len(fancyArg) < 2 {
|
||||
if len(fancyArg) < 2 { //nolint:gomnd
|
||||
//TODO: no user specified, use current
|
||||
fancyUser = "[default:getUser]"
|
||||
fancyHostPath = strings.Split(fancyArg[0], ":")
|
||||
|
@ -628,8 +639,8 @@ func parseNonSwitchArgs(a []string) (user, host, path string, isDest bool, other
|
|||
return fancyUser, fancyHost, fancyPath, isDest, otherArgs
|
||||
}
|
||||
|
||||
func launchTuns(conn *xsnet.Conn, remoteHost string, tuns string) {
|
||||
/*remAddrs, _ := net.LookupHost(remoteHost)*/
|
||||
func launchTuns(conn *xsnet.Conn /*remoteHost string,*/, tuns string) {
|
||||
/*remAddrs, _ := net.LookupHost(remoteHost)*/ //nolint:gocritic,nolintlint
|
||||
|
||||
if tuns == "" {
|
||||
return
|
||||
|
@ -678,12 +689,12 @@ func main() { //nolint: funlen, gocyclo
|
|||
var (
|
||||
isInteractive bool
|
||||
vopt bool
|
||||
gopt bool //login via password, asking server to generate authToken
|
||||
gopt bool // true: 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
|
||||
shellMode bool // true: act as shell, false: file copier
|
||||
cipherAlg string
|
||||
hmacAlg string
|
||||
kexAlg string
|
||||
server string
|
||||
port uint
|
||||
cmdStr string
|
||||
|
@ -703,7 +714,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
op []byte
|
||||
)
|
||||
|
||||
//=== Common (xs and xc) option parsing
|
||||
// === Common (xs and xc) option parsing
|
||||
|
||||
flag.BoolVar(&vopt, "v", false, "show version")
|
||||
flag.BoolVar(&dbg, "d", false, "debug logging")
|
||||
|
@ -731,18 +742,18 @@ func main() { //nolint: funlen, gocyclo
|
|||
KEX_FRODOKEM_1344SHAKE
|
||||
KEX_FRODOKEM_976AES
|
||||
KEX_FRODOKEM_976SHAKE`)
|
||||
flag.StringVar(&kcpMode, "K", "unused", "KCP `alg`, one of [KCP_NONE | KCP_AES | KCP_BLOWFISH | KCP_CAST5 | KCP_SM4 | KCP_SALSA20 | KCP_SIMPLEXOR | KCP_TEA | KCP_3DES | KCP_TWOFISH | KCP_XTEA] to use KCP (github.com/xtaci/kcp-go) reliable UDP instead of TCP")
|
||||
flag.UintVar(&port, "p", 2000, "``port")
|
||||
//flag.StringVar(&authCookie, "a", "", "auth cookie")
|
||||
flag.StringVar(&kcpMode, "K", "unused", "KCP `alg`, one of [KCP_NONE | KCP_AES | KCP_BLOWFISH | KCP_CAST5 | KCP_SM4 | KCP_SALSA20 | KCP_SIMPLEXOR | KCP_TEA | KCP_3DES | KCP_TWOFISH | KCP_XTEA] to use KCP (github.com/xtaci/kcp-go) reliable UDP instead of TCP") //nolint:lll
|
||||
flag.UintVar(&port, "p", 2000, "``port") //nolint:gomnd,lll
|
||||
//nolint:gocritic,nolintlint // flag.StringVar(&authCookie, "a", "", "auth cookie")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
|
||||
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min `msecs`")
|
||||
flag.UintVar(&chaffFreqMax, "F", 5000, "chaff pkt freq max `msecs`")
|
||||
flag.UintVar(&chaffBytesMax, "B", 64, "chaff pkt size max `bytes`")
|
||||
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min `msecs`") //nolint:gomnd
|
||||
flag.UintVar(&chaffFreqMax, "F", 5000, "chaff pkt freq max `msecs`") //nolint:gomnd
|
||||
flag.UintVar(&chaffBytesMax, "B", 64, "chaff pkt size max `bytes`") //nolint:gomnd
|
||||
|
||||
flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to <`file`>")
|
||||
flag.StringVar(&memprofile, "memprofile", "", "write memory profile to <`file`>")
|
||||
|
||||
//=== xc vs. xs option parsing
|
||||
// === xc vs. xs option parsing
|
||||
|
||||
// Find out what program we are (shell or copier)
|
||||
myPath := strings.Split(os.Args[0], string(os.PathSeparator))
|
||||
|
@ -759,7 +770,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
flag.Usage = usageShell
|
||||
} else {
|
||||
flag.BoolVar(©Quiet, "q", false, "do not output progress bar during copy")
|
||||
flag.UintVar(©LimitBPS, "L", 8589934592, "copy max rate in bytes per sec")
|
||||
flag.UintVar(©LimitBPS, "L", 8589934592, "copy max rate in bytes per sec") //nolint:gomnd
|
||||
flag.Usage = usageCp
|
||||
}
|
||||
flag.Parse()
|
||||
|
@ -769,7 +780,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
exitWithStatus(0)
|
||||
}
|
||||
|
||||
//=== Profiling instrumentation
|
||||
// === Profiling instrumentation
|
||||
|
||||
if cpuprofile != "" {
|
||||
f, err := os.Create(cpuprofile)
|
||||
|
@ -779,19 +790,19 @@ func main() { //nolint: funlen, gocyclo
|
|||
defer f.Close()
|
||||
fmt.Println("StartCPUProfile()")
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
log.Fatal("could not start CPU profile: ", err)
|
||||
log.Fatal("could not start CPU profile: ", err) //nolint:gocritic
|
||||
} else {
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
go func() { http.ListenAndServe("localhost:6060", nil) }()
|
||||
go func() { http.ListenAndServe("localhost:6060", nil) }() //nolint:errcheck,gosec
|
||||
}
|
||||
|
||||
//=== User, host, port and path args for file operations, if applicable
|
||||
// === User, host, port and path args for file operations, if applicable
|
||||
|
||||
remoteUser, remoteHost, tmpPath, pathIsDest, otherArgs :=
|
||||
parseNonSwitchArgs(flag.Args())
|
||||
//fmt.Println("otherArgs:", otherArgs)
|
||||
//nolint:gocritic,nolintlint // fmt.Println("otherArgs:", otherArgs)
|
||||
|
||||
// Set defaults if user doesn't specify user, path or port
|
||||
var uname string
|
||||
|
@ -809,7 +820,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
tmpPath = "."
|
||||
}
|
||||
|
||||
//=== Copy mode arg and copy src/dest setup
|
||||
// === Copy mode arg and copy src/dest setup
|
||||
|
||||
var fileArgs string
|
||||
if !shellMode /*&& tmpPath != ""*/ {
|
||||
|
@ -842,15 +853,15 @@ func main() { //nolint: funlen, gocyclo
|
|||
}
|
||||
}
|
||||
|
||||
//=== Do some final option consistency checks
|
||||
// === Do some final option consistency checks
|
||||
|
||||
//fmt.Println("server finally is:", server)
|
||||
//nolint:gocritic,nolintlint // fmt.Println("server finally is:", server)
|
||||
if flag.NFlag() == 0 && server == "" {
|
||||
flag.Usage()
|
||||
exitWithStatus(0)
|
||||
}
|
||||
|
||||
if len(cmdStr) != 0 && (len(copySrc) != 0 || len(copyDst) != 0) {
|
||||
if cmdStr != "" && (len(copySrc) != 0 || copyDst != "") {
|
||||
log.Fatal("incompatible options -- either cmd (-x) or copy ops but not both")
|
||||
}
|
||||
|
||||
|
@ -863,18 +874,18 @@ func main() { //nolint: funlen, gocyclo
|
|||
if dbg {
|
||||
log.SetOutput(Log)
|
||||
} else {
|
||||
log.SetOutput(ioutil.Discard)
|
||||
log.SetOutput(io.Discard)
|
||||
}
|
||||
|
||||
//=== Auth token fetch for login
|
||||
// === Auth token fetch for login
|
||||
|
||||
if !gopt {
|
||||
// See if we can log in via an auth token
|
||||
u, _ := user.Current()
|
||||
ab, aerr := ioutil.ReadFile(fmt.Sprintf("%s/.xs_id", u.HomeDir))
|
||||
ab, aerr := os.ReadFile(fmt.Sprintf("%s/.xs_id", u.HomeDir))
|
||||
if aerr == nil {
|
||||
for _, line := range strings.Split(string(ab), "\n") {
|
||||
line = line + "\n"
|
||||
line += "\n"
|
||||
idx := strings.Index(line, remoteHost+":"+uname)
|
||||
if idx >= 0 {
|
||||
line = line[idx:]
|
||||
|
@ -894,8 +905,8 @@ func main() { //nolint: funlen, gocyclo
|
|||
}
|
||||
runtime.GC()
|
||||
|
||||
//=== Enforce some sane min/max vals on chaff flags
|
||||
if chaffFreqMin < 2 {
|
||||
// === Enforce some sane min/max vals on chaff flags
|
||||
if chaffFreqMin < 2 { //nolint:gomnd
|
||||
chaffFreqMin = 2
|
||||
}
|
||||
if chaffFreqMax == 0 {
|
||||
|
@ -905,7 +916,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
chaffBytesMax = 64
|
||||
}
|
||||
|
||||
//=== Shell vs. Copy mode chaff and cmd setup
|
||||
// === Shell vs. Copy mode chaff and cmd setup
|
||||
|
||||
if shellMode {
|
||||
// We must make the decision about interactivity before Dial()
|
||||
|
@ -915,7 +926,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
op = []byte{'A'}
|
||||
chaffFreqMin = 2
|
||||
chaffFreqMax = 10
|
||||
} else if len(cmdStr) == 0 {
|
||||
} else if cmdStr == "" {
|
||||
op = []byte{'s'}
|
||||
isInteractive = true
|
||||
} else {
|
||||
|
@ -936,18 +947,18 @@ func main() { //nolint: funlen, gocyclo
|
|||
// client->server file copy
|
||||
// src file list is in copySrc
|
||||
op = []byte{'D'}
|
||||
//fmt.Println("client->server copy:", string(copySrc), "->", copyDst)
|
||||
//nolint:gocritic,nolintlint // fmt.Println("client->server copy:", string(copySrc), "->", copyDst)
|
||||
cmdStr = copyDst
|
||||
} else {
|
||||
// server->client file copy
|
||||
// remote src file(s) in copyDsr
|
||||
op = []byte{'S'}
|
||||
//fmt.Println("server->client copy:", string(copySrc), "->", copyDst)
|
||||
//nolint:gocritic,nolintlint // fmt.Println("server->client copy:", string(copySrc), "->", copyDst)
|
||||
cmdStr = string(copySrc)
|
||||
}
|
||||
}
|
||||
|
||||
//=== TCP / KCP Dial setup
|
||||
// === TCP / KCP Dial setup
|
||||
|
||||
proto := "tcp"
|
||||
if kcpMode != "unused" {
|
||||
|
@ -956,10 +967,10 @@ func main() { //nolint: funlen, gocyclo
|
|||
conn, err := xsnet.Dial(proto, server, cipherAlg, hmacAlg, kexAlg, kcpMode)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
exitWithStatus(3)
|
||||
exitWithStatus(XSNetDialFailed)
|
||||
}
|
||||
|
||||
//=== Shell terminal mode (Shell vs. Copy) setup
|
||||
// === 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
|
||||
|
@ -967,7 +978,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
var oldState *xs.State
|
||||
defer conn.Close()
|
||||
|
||||
//=== 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()) {
|
||||
|
@ -983,20 +994,20 @@ func main() { //nolint: funlen, gocyclo
|
|||
}
|
||||
}
|
||||
|
||||
//=== Login phase
|
||||
// === 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.]")
|
||||
//i})
|
||||
loginTimeout := time.AfterFunc(30*time.Second, func() {
|
||||
// iloginImpatience := time.AfterFunc(20*time.Second, func() {
|
||||
// i fmt.Printf(" .. [you still there? Waiting for a password.]")
|
||||
// i})
|
||||
loginTimeout := time.AfterFunc(30*time.Second, func() { //nolint:gomnd
|
||||
restoreTermState(oldState)
|
||||
fmt.Printf(" .. [login timeout]\n")
|
||||
exitWithStatus(xsnet.CSOLoginTimeout)
|
||||
})
|
||||
|
||||
if len(authCookie) == 0 {
|
||||
//No auth token, prompt for password
|
||||
if authCookie == "" {
|
||||
// No auth token, prompt for password
|
||||
fmt.Printf("Gimme cookie:")
|
||||
ab, e := xs.ReadPassword(os.Stdin.Fd())
|
||||
fmt.Printf("\r\n")
|
||||
|
@ -1006,43 +1017,43 @@ func main() { //nolint: funlen, gocyclo
|
|||
authCookie = string(ab)
|
||||
}
|
||||
|
||||
//i_ = loginImpatience.Stop()
|
||||
//nolint:gocritic,nolintlint // i_ = loginImpatience.Stop()
|
||||
_ = loginTimeout.Stop()
|
||||
// Security scrub
|
||||
runtime.GC()
|
||||
|
||||
//=== Session param and TERM setup
|
||||
// === 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)
|
||||
if sendErr != nil {
|
||||
restoreTermState(oldState)
|
||||
rec.SetStatus(254)
|
||||
rec.SetStatus(ServerRejectedSecureProposal)
|
||||
fmt.Fprintln(os.Stderr, "Error: server rejected secure proposal params or login timed out")
|
||||
exitWithStatus(int(rec.Status()))
|
||||
//log.Fatal(sendErr)
|
||||
//nolint:gocritic,nolintlint // log.Fatal(sendErr)
|
||||
}
|
||||
|
||||
//Security scrub
|
||||
// Security scrub
|
||||
authCookie = "" //nolint: ineffassign
|
||||
runtime.GC()
|
||||
|
||||
//=== Login Auth
|
||||
// === Login Auth
|
||||
|
||||
//=== Read auth reply from server
|
||||
// === 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
|
||||
// === Exit if auth reply not received
|
||||
fmt.Fprintln(os.Stderr, "Error reading auth reply")
|
||||
rec.SetStatus(255)
|
||||
rec.SetStatus(ErrReadingAuthReply)
|
||||
} else if authReply[0] == 0 {
|
||||
//=== .. or if auth failed
|
||||
// === .. or if auth failed
|
||||
fmt.Fprintln(os.Stderr, rejectUserMsg())
|
||||
rec.SetStatus(255)
|
||||
rec.SetStatus(GeneralProtocolErr)
|
||||
} 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\"/
|
||||
|
@ -1052,16 +1063,16 @@ func main() { //nolint: funlen, gocyclo
|
|||
defer conn.ShutdownChaff()
|
||||
}
|
||||
|
||||
//=== (goroutine) Start keepAliveWorker for tunnels
|
||||
// === (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
|
||||
// any, to prevent listeners from knowing this.
|
||||
//[1] if tunSpecStr != "" {
|
||||
// [1]: better to always send tunnel keepAlives even if client didn't specify
|
||||
// any, to prevent listeners from knowing this.
|
||||
// [1] if tunSpecStr != "" {
|
||||
keepAliveWorker := func() {
|
||||
for {
|
||||
// Add a bit of jitter to keepAlive so it doesn't stand out quite as much
|
||||
time.Sleep(time.Duration(2000-rand.Intn(200)) * time.Millisecond) //nolint:gosec
|
||||
time.Sleep(time.Duration(2000-rand.Intn(200)) * time.Millisecond) //nolint:gosec,gomnd
|
||||
// FIXME: keepAlives should probably have small random packet len/data as well
|
||||
// to further obscure them vs. interactive or tunnel data
|
||||
// keepAlives must be >=2 bytes, due to processing elsewhere
|
||||
|
@ -1069,15 +1080,15 @@ func main() { //nolint: funlen, gocyclo
|
|||
}
|
||||
}
|
||||
go keepAliveWorker()
|
||||
//[1]}
|
||||
// [1]}
|
||||
|
||||
//=== Session entry (shellMode or copyMode)
|
||||
// === Session entry (shellMode or copyMode)
|
||||
if shellMode {
|
||||
//=== (shell) launch tunnels
|
||||
launchTuns(&conn, remoteHost, tunSpecStr)
|
||||
// === (shell) launch tunnels
|
||||
launchTuns(&conn /*remoteHost,*/, tunSpecStr)
|
||||
doShellMode(isInteractive, &conn, oldState, rec)
|
||||
} else {
|
||||
//=== (.. or file copy)
|
||||
// === (.. or file copy)
|
||||
s, _ := doCopyMode(&conn, pathIsDest, fileArgs, copyQuiet, copyLimitBPS, rec)
|
||||
rec.SetStatus(s)
|
||||
}
|
||||
|
@ -1093,7 +1104,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
oldState = nil
|
||||
}
|
||||
|
||||
//=== Exit
|
||||
// === Exit
|
||||
exitWithStatus(int(rec.Status()))
|
||||
}
|
||||
|
||||
|
@ -1128,7 +1139,7 @@ func exitWithStatus(status int) {
|
|||
defer f.Close()
|
||||
runtime.GC() // get up-to-date statistics
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
log.Fatal("could not write memory profile: ", err)
|
||||
log.Fatal("could not write memory profile: ", err) //nolint:gocritic
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue