mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
Fixed shell (interative & non-) exit status after cp status fixes
This commit is contained in:
parent
a6979298fd
commit
db1b494d00
3 changed files with 51 additions and 40 deletions
|
@ -77,7 +77,7 @@ type (
|
|||
|
||||
chaff ChaffConfig
|
||||
|
||||
closeStat *uint8 // close status (shell exit status: UNIX uint8)
|
||||
closeStat *uint8 // close status
|
||||
r cipher.Stream //read cipherStream
|
||||
rm hash.Hash
|
||||
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) {
|
||||
hc.DisableChaff()
|
||||
hc.WritePacket([]byte{byte(*hc.closeStat)}, CSOExitStatus)
|
||||
*hc.closeStat = 0
|
||||
err = hc.c.Close()
|
||||
log.Println("[Conn Closing]")
|
||||
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"
|
||||
if err != nil {
|
||||
if !strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||
//fmt.Println("[1]unexpected Read() err:", err)
|
||||
log.Println("[1]unexpected Read() err:", err)
|
||||
} else {
|
||||
//fmt.Println("[Client hung up]")
|
||||
log.Println("[Client hung up]")
|
||||
}
|
||||
return 0, err
|
||||
|
@ -424,45 +425,47 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
|||
decryptN, err := rs.Read(payloadBytes)
|
||||
log.Printf(" <-ptext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
|
||||
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)
|
||||
if ctrlStatOp == CSOChaff {
|
||||
log.Printf("[Chaff pkt, discarded (len %d)]\n", decryptN)
|
||||
} else if ctrlStatOp == CSOTermSize {
|
||||
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
|
||||
log.Printf("[TermSize pkt: rows %v cols %v]\n", hc.Rows, hc.Cols)
|
||||
hc.WinCh <- WinSize{hc.Rows, hc.Cols}
|
||||
} else if ctrlStatOp == CSOExitStatus {
|
||||
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 {
|
||||
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
|
||||
if ctrlStatOp == CSOChaff {
|
||||
log.Printf("[Chaff pkt, discarded (len %d)]\n", decryptN)
|
||||
} else if ctrlStatOp == CSOTermSize {
|
||||
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
|
||||
log.Printf("[TermSize pkt: rows %v cols %v]\n", hc.Rows, hc.Cols)
|
||||
hc.WinCh <- WinSize{hc.Rows, hc.Cols}
|
||||
} else if ctrlStatOp == CSOExitStatus {
|
||||
if len(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()
|
||||
//!}
|
||||
} else {
|
||||
log.Println("[truncated payload, cannot determine CSOExitStatus]")
|
||||
*hc.closeStat = 98
|
||||
}
|
||||
} else {
|
||||
log.Println("[truncated payload, cannot determine CSOExitStatus]")
|
||||
*hc.closeStat = 98
|
||||
hc.dBuf.Write(payloadBytes)
|
||||
//log.Printf("hc.dBuf: %s\n", hex.Dump(hc.dBuf.Bytes()))
|
||||
}
|
||||
} else {
|
||||
hc.dBuf.Write(payloadBytes)
|
||||
//log.Printf("hc.dBuf: %s\n", hex.Dump(hc.dBuf.Bytes()))
|
||||
}
|
||||
|
||||
// Re-calculate hmac, compare with received value
|
||||
hc.rm.Write(payloadBytes)
|
||||
hTmp := hc.rm.Sum(nil)[0:4]
|
||||
log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
|
||||
// Re-calculate hmac, compare with received value
|
||||
hc.rm.Write(payloadBytes)
|
||||
hTmp := hc.rm.Sum(nil)[0:4]
|
||||
log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
|
||||
|
||||
if *hc.closeStat > 90 {
|
||||
log.Println("[cannot verify HMAC]")
|
||||
} else {
|
||||
// Log alert if hmac didn't match, corrupted channel
|
||||
if !bytes.Equal(hTmp, []byte(hmacIn[0:])) /*|| hmacIn[0] > 0xf8*/ {
|
||||
fmt.Println("** ALERT - detected HMAC mismatch, possible channel tampering **")
|
||||
_, _ = hc.c.Write([]byte{CSOHmacInvalid})
|
||||
if *hc.closeStat > 90 {
|
||||
log.Println("[cannot verify HMAC]")
|
||||
} else {
|
||||
// Log alert if hmac didn't match, corrupted channel
|
||||
if !bytes.Equal(hTmp, []byte(hmacIn[0:])) /*|| hmacIn[0] > 0xf8*/ {
|
||||
fmt.Println("** ALERT - detected HMAC mismatch, possible channel tampering **")
|
||||
_, _ = hc.c.Write([]byte{CSOHmacInvalid})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
|||
}
|
||||
//fmt.Println("*** client->server cp finished ***")
|
||||
// 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*/)
|
||||
}
|
||||
} 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 ***")
|
||||
}
|
||||
}
|
||||
|
@ -235,9 +240,11 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
|
|||
// exit with inerr == nil
|
||||
_, inerr := io.Copy(os.Stdout, conn)
|
||||
if inerr != nil {
|
||||
fmt.Println(inerr)
|
||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
|
||||
os.Exit(1)
|
||||
if !strings.HasSuffix(inerr.Error(), "use of closed network connection") {
|
||||
log.Println(inerr)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
rec.status = int(conn.GetStatus())
|
||||
|
@ -531,7 +538,7 @@ func main() {
|
|||
if shellMode {
|
||||
doShellMode(isInteractive, conn, oldState, rec)
|
||||
} else {
|
||||
doCopyMode(conn, pathIsDest, fileArgs, rec)
|
||||
_, rec.status = doCopyMode(conn, pathIsDest, fileArgs, rec)
|
||||
}
|
||||
|
||||
if oldState != nil {
|
||||
|
|
|
@ -315,7 +315,8 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
|
|||
exitStatus = status.ExitStatus()
|
||||
log.Printf("Exit Status: %d", exitStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
conn.SetStatus(uint8(exitStatus))
|
||||
}
|
||||
wg.Wait() // Wait on pty->stdout completion to client
|
||||
}
|
||||
|
@ -518,6 +519,7 @@ func main() {
|
|||
hname := strings.Split(addr.String(), ":")[0]
|
||||
log.Printf("[Running copy for [%s@%s]]\n", rec.who, hname)
|
||||
runErr, cmdStatus := runServerToClientCopyAs(string(rec.who), hc, string(rec.cmd), chaffEnabled)
|
||||
//fmt.Print("ServerToClient cmdStatus:", cmdStatus)
|
||||
// Returned hopefully via an EOF or exit/logout;
|
||||
// Clear current op so user can enter next, or EOF
|
||||
rec.op[0] = 0
|
||||
|
@ -528,9 +530,8 @@ func main() {
|
|||
}
|
||||
hc.SetStatus(uint8(cmdStatus))
|
||||
// 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.")
|
||||
//ackByte := make([]byte, 1, 1)
|
||||
_, _ = hc.Read(nil /*ackByte*/)
|
||||
//fmt.Println("Got remote end ack.")
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue