mirror of https://gogs.blitter.com/RLabs/xs
Fixed shell (interative & non-) exit status after cp status fixes
This commit is contained in:
parent
a6979298fd
commit
db1b494d00
|
@ -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,45 +425,47 @@ 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 {
|
||||||
log.Printf("[Chaff pkt, discarded (len %d)]\n", decryptN)
|
log.Printf("[Chaff pkt, discarded (len %d)]\n", decryptN)
|
||||||
} else if ctrlStatOp == CSOTermSize {
|
} else if ctrlStatOp == CSOTermSize {
|
||||||
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
|
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
|
||||||
log.Printf("[TermSize pkt: rows %v cols %v]\n", hc.Rows, hc.Cols)
|
log.Printf("[TermSize pkt: rows %v cols %v]\n", hc.Rows, hc.Cols)
|
||||||
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 {
|
||||||
|
log.Println("[truncated payload, cannot determine CSOExitStatus]")
|
||||||
|
*hc.closeStat = 98
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("[truncated payload, cannot determine CSOExitStatus]")
|
hc.dBuf.Write(payloadBytes)
|
||||||
*hc.closeStat = 98
|
//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
|
// Re-calculate hmac, compare with received value
|
||||||
hc.rm.Write(payloadBytes)
|
hc.rm.Write(payloadBytes)
|
||||||
hTmp := hc.rm.Sum(nil)[0:4]
|
hTmp := hc.rm.Sum(nil)[0:4]
|
||||||
log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
|
log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
|
||||||
|
|
||||||
if *hc.closeStat > 90 {
|
if *hc.closeStat > 90 {
|
||||||
log.Println("[cannot verify HMAC]")
|
log.Println("[cannot verify HMAC]")
|
||||||
} else {
|
} else {
|
||||||
// Log alert if hmac didn't match, corrupted channel
|
// Log alert if hmac didn't match, corrupted channel
|
||||||
if !bytes.Equal(hTmp, []byte(hmacIn[0:])) /*|| hmacIn[0] > 0xf8*/ {
|
if !bytes.Equal(hTmp, []byte(hmacIn[0:])) /*|| hmacIn[0] > 0xf8*/ {
|
||||||
fmt.Println("** ALERT - detected HMAC mismatch, possible channel tampering **")
|
fmt.Println("** ALERT - detected HMAC mismatch, possible channel tampering **")
|
||||||
_, _ = hc.c.Write([]byte{CSOHmacInvalid})
|
_, _ = 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 ***")
|
//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,9 +240,11 @@ 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.
|
||||||
os.Exit(1)
|
if !strings.HasSuffix(inerr.Error(), "use of closed network connection") {
|
||||||
|
log.Println(inerr)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rec.status = int(conn.GetStatus())
|
rec.status = int(conn.GetStatus())
|
||||||
|
@ -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 {
|
||||||
|
|
|
@ -315,7 +315,8 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = status.ExitStatus()
|
||||||
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 {
|
||||||
|
|
Loading…
Reference in New Issue