Fixed shell (interative & non-) exit status after cp status fixes

This commit is contained in:
Russ Magee 2018-09-06 00:16:44 -07:00
parent a6979298fd
commit db1b494d00
3 changed files with 51 additions and 40 deletions

View File

@ -77,7 +77,7 @@ type (
chaff ChaffConfig chaff ChaffConfig
closeStat *uint8 // close status (shell exit status: UNIX uint8) closeStat *uint8 // close status
r cipher.Stream //read cipherStream r cipher.Stream //read cipherStream
rm hash.Hash rm hash.Hash
w cipher.Stream //write cipherStream w cipher.Stream //write cipherStream
@ -213,7 +213,6 @@ func Dial(protocol string, ipport string, extensions ...string) (hc *Conn, err e
func (hc *Conn) Close() (err error) { func (hc *Conn) Close() (err error) {
hc.DisableChaff() hc.DisableChaff()
hc.WritePacket([]byte{byte(*hc.closeStat)}, CSOExitStatus) hc.WritePacket([]byte{byte(*hc.closeStat)}, CSOExitStatus)
*hc.closeStat = 0
err = hc.c.Close() err = hc.c.Close()
log.Println("[Conn Closing]") log.Println("[Conn Closing]")
return return
@ -379,8 +378,10 @@ func (hc Conn) Read(b []byte) (n int, err error) {
// (on server side) err.Error() == "<iface/addr info ...>: use of closed network connection" // (on server side) err.Error() == "<iface/addr info ...>: use of closed network connection"
if err != nil { if err != nil {
if !strings.HasSuffix(err.Error(), "use of closed network connection") { if !strings.HasSuffix(err.Error(), "use of closed network connection") {
//fmt.Println("[1]unexpected Read() err:", err)
log.Println("[1]unexpected Read() err:", err) log.Println("[1]unexpected Read() err:", err)
} else { } else {
//fmt.Println("[Client hung up]")
log.Println("[Client hung up]") log.Println("[Client hung up]")
} }
return 0, err return 0, err
@ -424,8 +425,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
decryptN, err := rs.Read(payloadBytes) decryptN, err := rs.Read(payloadBytes)
log.Printf(" <-ptext:\r\n%s\r\n", hex.Dump(payloadBytes[:n])) log.Printf(" <-ptext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
if err != nil { if err != nil {
panic(err) //fmt.Print(err)
} //panic(err)
} else {
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data) // Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
if ctrlStatOp == CSOChaff { if ctrlStatOp == CSOChaff {
@ -436,12 +438,12 @@ func (hc Conn) Read(b []byte) (n int, err error) {
hc.WinCh <- WinSize{hc.Rows, hc.Cols} hc.WinCh <- WinSize{hc.Rows, hc.Cols}
} else if ctrlStatOp == CSOExitStatus { } else if ctrlStatOp == CSOExitStatus {
if len(payloadBytes) > 0 { if len(payloadBytes) > 0 {
*hc.closeStat = uint8(payloadBytes[0])
// If remote end is closing with an error, reply we're closing ours
if payloadBytes[0] != 0 {
hc.SetStatus(payloadBytes[0]) hc.SetStatus(payloadBytes[0])
//!// If remote end is closing with an error, reply we're closing ours
//!if hc.GetStatus() != 0 {
//! log.Print("CSOExitStatus:", hc.GetStatus())
hc.Close() hc.Close()
} //!}
} else { } else {
log.Println("[truncated payload, cannot determine CSOExitStatus]") log.Println("[truncated payload, cannot determine CSOExitStatus]")
*hc.closeStat = 98 *hc.closeStat = 98
@ -466,6 +468,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
} }
} }
} }
}
retN := hc.dBuf.Len() retN := hc.dBuf.Len()
if retN > len(b) { if retN > len(b) {

View File

@ -169,7 +169,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
} }
//fmt.Println("*** client->server cp finished ***") //fmt.Println("*** client->server cp finished ***")
// Signal other end transfer is complete // Signal other end transfer is complete
conn.WritePacket([]byte{byte(rec.status)}, hkexnet.CSOExitStatus) conn.WritePacket([]byte{byte( /*255*/ rec.status)}, hkexnet.CSOExitStatus)
_, _ = conn.Read(nil /*ackByte*/) _, _ = conn.Read(nil /*ackByte*/)
} }
} else { } else {
@ -214,6 +214,11 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
} }
} }
} }
// return local status, if nonzero;
// otherwise, return remote status if nonzero
if exitStatus == 0 {
exitStatus = int(conn.GetStatus())
}
//fmt.Println("*** server->client cp finished ***") //fmt.Println("*** server->client cp finished ***")
} }
} }
@ -235,10 +240,12 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
// exit with inerr == nil // exit with inerr == nil
_, inerr := io.Copy(os.Stdout, conn) _, inerr := io.Copy(os.Stdout, conn)
if inerr != nil { if inerr != nil {
fmt.Println(inerr)
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort. _ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
if !strings.HasSuffix(inerr.Error(), "use of closed network connection") {
log.Println(inerr)
os.Exit(1) os.Exit(1)
} }
}
rec.status = int(conn.GetStatus()) rec.status = int(conn.GetStatus())
log.Println("rec.status:", rec.status) log.Println("rec.status:", rec.status)
@ -531,7 +538,7 @@ func main() {
if shellMode { if shellMode {
doShellMode(isInteractive, conn, oldState, rec) doShellMode(isInteractive, conn, oldState, rec)
} else { } else {
doCopyMode(conn, pathIsDest, fileArgs, rec) _, rec.status = doCopyMode(conn, pathIsDest, fileArgs, rec)
} }
if oldState != nil { if oldState != nil {

View File

@ -316,6 +316,7 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
log.Printf("Exit Status: %d", exitStatus) log.Printf("Exit Status: %d", exitStatus)
} }
} }
conn.SetStatus(uint8(exitStatus))
} }
wg.Wait() // Wait on pty->stdout completion to client wg.Wait() // Wait on pty->stdout completion to client
} }
@ -518,6 +519,7 @@ func main() {
hname := strings.Split(addr.String(), ":")[0] hname := strings.Split(addr.String(), ":")[0]
log.Printf("[Running copy for [%s@%s]]\n", rec.who, hname) log.Printf("[Running copy for [%s@%s]]\n", rec.who, hname)
runErr, cmdStatus := runServerToClientCopyAs(string(rec.who), hc, string(rec.cmd), chaffEnabled) runErr, cmdStatus := runServerToClientCopyAs(string(rec.who), hc, string(rec.cmd), chaffEnabled)
//fmt.Print("ServerToClient cmdStatus:", cmdStatus)
// Returned hopefully via an EOF or exit/logout; // Returned hopefully via an EOF or exit/logout;
// Clear current op so user can enter next, or EOF // Clear current op so user can enter next, or EOF
rec.op[0] = 0 rec.op[0] = 0
@ -528,9 +530,8 @@ func main() {
} }
hc.SetStatus(uint8(cmdStatus)) hc.SetStatus(uint8(cmdStatus))
// Signal other end transfer is complete // Signal other end transfer is complete
hc.WritePacket([]byte{byte(cmdStatus)}, hkexnet.CSOExitStatus) hc.WritePacket([]byte{byte(/*255*/cmdStatus)}, hkexnet.CSOExitStatus)
//fmt.Println("Waiting for EOF from other end.") //fmt.Println("Waiting for EOF from other end.")
//ackByte := make([]byte, 1, 1)
_, _ = hc.Read(nil /*ackByte*/) _, _ = hc.Read(nil /*ackByte*/)
//fmt.Println("Got remote end ack.") //fmt.Println("Got remote end ack.")
} else { } else {