diff --git a/hkexnet/hkexnet.go b/hkexnet/hkexnet.go index f88e5d8..15dedd4 100644 --- a/hkexnet/hkexnet.go +++ b/hkexnet/hkexnet.go @@ -37,7 +37,7 @@ import ( // const CSExtendedCode - extended (>255 UNIX exit status) codes // This indicate channel-related or internal errors const ( - CSEBadAuth = 1024 // failed login + CSEBadAuth = 1024 // Failed login password CSETruncCSO // No CSOExitStatus in payload CSEStillOpen // Channel closed unexpectedly CSEExecFail // cmd.Start() (exec) failed diff --git a/hkexsh/hkexsh.go b/hkexsh/hkexsh.go index 1e04624..4e42f86 100755 --- a/hkexsh/hkexsh.go +++ b/hkexsh/hkexsh.go @@ -27,6 +27,7 @@ import ( hkexsh "blitter.com/go/hkexsh" "blitter.com/go/hkexsh/hkexnet" + "blitter.com/go/hkexsh/spinsult" isatty "github.com/mattn/go-isatty" ) @@ -163,7 +164,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec) // an ExitStatus() method with the same signature. if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { exitStatus = uint32(status.ExitStatus()) - log.Printf("Exit Status: %d", exitStatus) + log.Printf("Exit Status: %d", exitStatus) //# fmt.Print(stdErrBuffer) } } @@ -285,9 +286,9 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State, log.Println(outerr) fmt.Println(outerr) _ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort. - os.Exit(254) + log.Println("[Hanging up]") + os.Exit(0) } - log.Println("[Sent EOF]") }() } @@ -309,6 +310,10 @@ func UsageCp() { flag.PrintDefaults() } +func rejectUserMsg() string { + return "Begone, " + spinsult.GetSentence() + "\r\n" +} + // hkexsh - a client for secure shell and file copy operations. // // While conforming to the basic net.Conn interface HKex.Conn has extra @@ -533,34 +538,35 @@ func main() { _, err = conn.Write(rec.cmd) _, err = conn.Write(rec.authCookie) - // Set up chaffing to server - conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing - if chaffEnabled { - conn.EnableChaff() - defer conn.DisableChaff() - defer conn.ShutdownChaff() - } - - if shellMode { - doShellMode(isInteractive, conn, oldState, rec) + // Read auth reply from server + authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass + _, err = conn.Read(authReply) + if authReply[0] == 0 { + fmt.Fprintln(os.Stderr, rejectUserMsg()) + rec.status = 255 } else { - _, rec.status = doCopyMode(conn, pathIsDest, fileArgs, rec) + + // Set up chaffing to server + conn.SetupChaff(chaffFreqMin, chaffFreqMax, chaffBytesMax) // enable client->server chaffing + if chaffEnabled { + conn.EnableChaff() + defer conn.DisableChaff() + defer conn.ShutdownChaff() + } + + if shellMode { + doShellMode(isInteractive, conn, oldState, rec) + } else { // copyMode + _, rec.status = doCopyMode(conn, pathIsDest, fileArgs, rec) + } + + if rec.status != 0 { + fmt.Fprintln(os.Stderr, "Remote end exited with status:", rec.status) + } } if oldState != nil { _ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort. } - - if rec.status != 0 { - fmt.Fprint(os.Stderr, "Remote end ") - if rec.status == hkexnet.CSEBadAuth { - // shell exit status can't hold CSEBadAuth (uint32) - rec.status = 255 - fmt.Fprintln(os.Stderr, "replied: bad auth") - } else { - fmt.Fprintln(os.Stderr, "exited with status:", rec.status) - } - - } os.Exit(int(rec.status)) } diff --git a/hkexshd/hkexshd.go b/hkexshd/hkexshd.go index b9c8000..aa26764 100755 --- a/hkexshd/hkexshd.go +++ b/hkexshd/hkexshd.go @@ -27,7 +27,6 @@ import ( "blitter.com/go/goutmp" hkexsh "blitter.com/go/hkexsh" "blitter.com/go/hkexsh/hkexnet" - "blitter.com/go/hkexsh/spinsult" "github.com/kr/pty" ) @@ -324,10 +323,6 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha return } -func rejectUserMsg() string { - return "Begone, " + spinsult.GetSentence() + "\r\n" -} - // Demo of a simple server that listens and spawns goroutines for each // connecting client. Note this code is identical to standard tcp // server code, save for declaring 'hkex' rather than 'net' @@ -454,19 +449,15 @@ func main() { } runtime.GC() - if !valid { + // Tell client if auth was valid + if valid { + hc.Write([]byte{1}) + } else { log.Println("Invalid user", string(rec.who)) - - // Signal other end auth failed - rec.status = hkexnet.CSEBadAuth - hc.SetStatus(hkexnet.CSEBadAuth) - s := make([]byte, 4) - binary.BigEndian.PutUint32(s, hkexnet.CSEBadAuth) - hc.WritePacket(s, hkexnet.CSOExitStatus) - - hc.Write([]byte(rejectUserMsg())) + hc.Write([]byte{0}) return } + log.Printf("[allowedCmds:%s]\n", allowedCmds) if rec.op[0] == 'c' {