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
 | 
			
		||||
 | 
			
		||||
		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 New Issue