mirror of https://gogs.blitter.com/RLabs/xs
				
				
				
			-Moved recCmd out of hkexsh and hkexshd into hkexsession.go (now abstract Session type)
This commit is contained in:
		
							parent
							
								
									bff56a2c61
								
							
						
					
					
						commit
						9e803ffc19
					
				| 
						 | 
					@ -0,0 +1,88 @@
 | 
				
			||||||
 | 
					// Session info/routines for the HKExSh
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Copyright (c) 2017-2018 Russell Magee
 | 
				
			||||||
 | 
					// Licensed under the terms of the MIT license (see LICENSE.mit in this
 | 
				
			||||||
 | 
					// distribution)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// golang implementation by Russ Magee (rmagee_at_gmail.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package hkexsh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Session struct {
 | 
				
			||||||
 | 
						op         []byte
 | 
				
			||||||
 | 
						who        []byte
 | 
				
			||||||
 | 
						cmd        []byte
 | 
				
			||||||
 | 
						authCookie []byte
 | 
				
			||||||
 | 
						status     uint32 // exit status (0-255 is std UNIX status)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Output Session record as a string. Implements Stringer interface.
 | 
				
			||||||
 | 
					func (h *Session) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("hkexsh.Session:\nOp:%v\nWho:%v\nCmd:%v\nAuthCookie:%v\nStatus:%v",
 | 
				
			||||||
 | 
							h.op, h.who, h.cmd, h.AuthCookie(false), h.status)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h Session) Op() []byte {
 | 
				
			||||||
 | 
						return h.op
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Session) SetOp(o []byte) {
 | 
				
			||||||
 | 
						h.op = o
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h Session) Who() []byte {
 | 
				
			||||||
 | 
						return h.who
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Session) SetWho(w []byte) {
 | 
				
			||||||
 | 
						h.who = w
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h Session) Cmd() []byte {
 | 
				
			||||||
 | 
						return h.cmd
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Session) SetCmd(c []byte) {
 | 
				
			||||||
 | 
						h.cmd = c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h Session) AuthCookie(reallyShow bool) []byte {
 | 
				
			||||||
 | 
						if reallyShow {
 | 
				
			||||||
 | 
							return h.authCookie
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return []byte("**REDACTED**")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Session) SetAuthCookie(a []byte) {
 | 
				
			||||||
 | 
						h.authCookie = a
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Session) ClearAuthCookie() {
 | 
				
			||||||
 | 
						for i := range h.authCookie {
 | 
				
			||||||
 | 
							h.authCookie[i] = 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						runtime.GC()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h Session) Status() uint32 {
 | 
				
			||||||
 | 
						return h.status
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Session) SetStatus(s uint32) {
 | 
				
			||||||
 | 
						h.status = s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewSession(op, who, cmd, authcookie []byte, status uint32) *Session {
 | 
				
			||||||
 | 
						return &Session{
 | 
				
			||||||
 | 
							op:         op,
 | 
				
			||||||
 | 
							who:        who,
 | 
				
			||||||
 | 
							cmd:        cmd,
 | 
				
			||||||
 | 
							authCookie: authcookie,
 | 
				
			||||||
 | 
							status:     status}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -31,14 +31,6 @@ import (
 | 
				
			||||||
	isatty "github.com/mattn/go-isatty"
 | 
						isatty "github.com/mattn/go-isatty"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cmdSpec struct {
 | 
					 | 
				
			||||||
	op         []byte
 | 
					 | 
				
			||||||
	who        []byte
 | 
					 | 
				
			||||||
	cmd        []byte
 | 
					 | 
				
			||||||
	authCookie []byte
 | 
					 | 
				
			||||||
	status     uint32 // exit status (0-255 is std UNIX status)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	wg sync.WaitGroup
 | 
						wg sync.WaitGroup
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -100,9 +92,9 @@ func parseNonSwitchArgs(a []string) (user, host, path string, isDest bool, other
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// doCopyMode begins a secure hkexsh local<->remote file copy operation.
 | 
					// doCopyMode begins a secure hkexsh local<->remote file copy operation.
 | 
				
			||||||
func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec) (err error, exitStatus uint32) {
 | 
					func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *hkexsh.Session) (err error, exitStatus uint32) {
 | 
				
			||||||
	if remoteDest {
 | 
						if remoteDest {
 | 
				
			||||||
		log.Println("local files:", files, "remote filepath:", string(rec.cmd))
 | 
							log.Println("local files:", files, "remote filepath:", string(rec.Cmd()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var c *exec.Cmd
 | 
							var c *exec.Cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -172,12 +164,12 @@ 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
 | 
				
			||||||
			s := make([]byte, 4)
 | 
								s := make([]byte, 4)
 | 
				
			||||||
			binary.BigEndian.PutUint32(s, rec.status)
 | 
								binary.BigEndian.PutUint32(s, rec.Status())
 | 
				
			||||||
			conn.WritePacket(s, hkexnet.CSOExitStatus)
 | 
								conn.WritePacket(s, hkexnet.CSOExitStatus)
 | 
				
			||||||
			_, _ = conn.Read(nil /*ackByte*/)
 | 
								_, _ = conn.Read(nil /*ackByte*/)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		log.Println("remote filepath:", string(rec.cmd), "local files:", files)
 | 
							log.Println("remote filepath:", string(rec.Cmd()), "local files:", files)
 | 
				
			||||||
		var c *exec.Cmd
 | 
							var c *exec.Cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//os.Clearenv()
 | 
							//os.Clearenv()
 | 
				
			||||||
| 
						 | 
					@ -230,7 +222,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// doShellMode begins an hkexsh shell session (one-shot command or interactive).
 | 
					// doShellMode begins an hkexsh shell session (one-shot command or interactive).
 | 
				
			||||||
func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State, rec *cmdSpec) {
 | 
					func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State, rec *hkexsh.Session) {
 | 
				
			||||||
	//client reader (from server) goroutine
 | 
						//client reader (from server) goroutine
 | 
				
			||||||
	//Read remote end's stdout
 | 
						//Read remote end's stdout
 | 
				
			||||||
	wg.Add(1)
 | 
						wg.Add(1)
 | 
				
			||||||
| 
						 | 
					@ -254,8 +246,8 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rec.status = uint32(conn.GetStatus())
 | 
							rec.SetStatus(uint32(conn.GetStatus()))
 | 
				
			||||||
		log.Println("rec.status:", rec.status)
 | 
							log.Println("rec.status:", rec.Status)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if isInteractive {
 | 
							if isInteractive {
 | 
				
			||||||
			log.Println("[* Got EOF *]")
 | 
								log.Println("[* Got EOF *]")
 | 
				
			||||||
| 
						 | 
					@ -523,27 +515,22 @@ func main() {
 | 
				
			||||||
		runtime.GC()
 | 
							runtime.GC()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	rec := &cmdSpec{
 | 
						rec := hkexsh.NewSession(op, []byte(uname), []byte(cmdStr), []byte(authCookie),0)
 | 
				
			||||||
		op:         op,
 | 
					 | 
				
			||||||
		who:        []byte(uname),
 | 
					 | 
				
			||||||
		cmd:        []byte(cmdStr),
 | 
					 | 
				
			||||||
		authCookie: []byte(authCookie),
 | 
					 | 
				
			||||||
		status:     0}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = fmt.Fprintf(conn, "%d %d %d %d\n",
 | 
						_, err = fmt.Fprintf(conn, "%d %d %d %d\n",
 | 
				
			||||||
		len(rec.op), len(rec.who), len(rec.cmd), len(rec.authCookie))
 | 
							len(rec.Op()), len(rec.Who()), len(rec.Cmd()), len(rec.AuthCookie(true)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = conn.Write(rec.op)
 | 
						_, err = conn.Write(rec.Op())
 | 
				
			||||||
	_, err = conn.Write(rec.who)
 | 
						_, err = conn.Write(rec.Who())
 | 
				
			||||||
	_, err = conn.Write(rec.cmd)
 | 
						_, err = conn.Write(rec.Cmd())
 | 
				
			||||||
	_, err = conn.Write(rec.authCookie)
 | 
						_, err = conn.Write(rec.AuthCookie(true))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Read auth reply from server
 | 
						// Read auth reply from server
 | 
				
			||||||
	authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass
 | 
						authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass
 | 
				
			||||||
	_, err = conn.Read(authReply)
 | 
						_, err = conn.Read(authReply)
 | 
				
			||||||
	if authReply[0] == 0 {
 | 
						if authReply[0] == 0 {
 | 
				
			||||||
		fmt.Fprintln(os.Stderr, rejectUserMsg())
 | 
							fmt.Fprintln(os.Stderr, rejectUserMsg())
 | 
				
			||||||
		rec.status = 255
 | 
							rec.SetStatus(255)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Set up chaffing to server
 | 
							// Set up chaffing to server
 | 
				
			||||||
| 
						 | 
					@ -557,16 +544,17 @@ func main() {
 | 
				
			||||||
		if shellMode {
 | 
							if shellMode {
 | 
				
			||||||
			doShellMode(isInteractive, conn, oldState, rec)
 | 
								doShellMode(isInteractive, conn, oldState, rec)
 | 
				
			||||||
		} else { // copyMode
 | 
							} else { // copyMode
 | 
				
			||||||
			_, rec.status = doCopyMode(conn, pathIsDest, fileArgs, rec)
 | 
									_, s := doCopyMode(conn, pathIsDest, fileArgs, rec)
 | 
				
			||||||
 | 
									rec.SetStatus(s)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if rec.status != 0 {
 | 
							if rec.Status() != 0 {
 | 
				
			||||||
			fmt.Fprintln(os.Stderr, "Remote end exited with status:", rec.status)
 | 
								fmt.Fprintln(os.Stderr, "Remote end exited with status:", rec.Status())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if oldState != nil {
 | 
						if oldState != nil {
 | 
				
			||||||
		_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
 | 
							_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	os.Exit(int(rec.status))
 | 
						os.Exit(int(rec.Status()))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,6 @@ import (
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"os/user"
 | 
						"os/user"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"runtime"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
| 
						 | 
					@ -30,14 +29,6 @@ import (
 | 
				
			||||||
	"github.com/kr/pty"
 | 
						"github.com/kr/pty"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cmdSpec struct {
 | 
					 | 
				
			||||||
	op         []byte
 | 
					 | 
				
			||||||
	who        []byte
 | 
					 | 
				
			||||||
	cmd        []byte
 | 
					 | 
				
			||||||
	authCookie []byte
 | 
					 | 
				
			||||||
	status     int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* -------------------------------------------------------------- */
 | 
					/* -------------------------------------------------------------- */
 | 
				
			||||||
// Perform a client->server copy
 | 
					// Perform a client->server copy
 | 
				
			||||||
func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffing bool) (err error, exitStatus uint32) {
 | 
					func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffing bool) (err error, exitStatus uint32) {
 | 
				
			||||||
| 
						 | 
					@ -394,138 +385,140 @@ func main() {
 | 
				
			||||||
				defer hc.Close()
 | 
									defer hc.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				//We use io.ReadFull() here to guarantee we consume
 | 
									//We use io.ReadFull() here to guarantee we consume
 | 
				
			||||||
				//just the data we want for the cmdSpec, and no more.
 | 
									//just the data we want for the hkexsh.Session, and no more.
 | 
				
			||||||
				//Otherwise data will be sitting in the channel that isn't
 | 
									//Otherwise data will be sitting in the channel that isn't
 | 
				
			||||||
				//passed down to the command handlers.
 | 
									//passed down to the command handlers.
 | 
				
			||||||
				var rec cmdSpec
 | 
									var rec hkexsh.Session
 | 
				
			||||||
				var len1, len2, len3, len4 uint32
 | 
									var len1, len2, len3, len4 uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				n, err := fmt.Fscanf(hc, "%d %d %d %d\n", &len1, &len2, &len3, &len4)
 | 
									n, err := fmt.Fscanf(hc, "%d %d %d %d\n", &len1, &len2, &len3, &len4)
 | 
				
			||||||
				log.Printf("cmdSpec read:%d %d %d %d\n", len1, len2, len3, len4)
 | 
									log.Printf("hkexsh.Session read:%d %d %d %d\n", len1, len2, len3, len4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if err != nil || n < 4 {
 | 
									if err != nil || n < 4 {
 | 
				
			||||||
					log.Println("[Bad cmdSpec fmt]")
 | 
										log.Println("[Bad hkexsh.Session fmt]")
 | 
				
			||||||
					return err
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				//fmt.Printf("  lens:%d %d %d %d\n", len1, len2, len3, len4)
 | 
									//fmt.Printf("  lens:%d %d %d %d\n", len1, len2, len3, len4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				rec.op = make([]byte, len1, len1)
 | 
									tmp := make([]byte, len1, len1)
 | 
				
			||||||
				_, err = io.ReadFull(hc, rec.op)
 | 
									_, err = io.ReadFull(hc, tmp)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					log.Println("[Bad cmdSpec.op]")
 | 
										log.Println("[Bad hkexsh.Session.Op]")
 | 
				
			||||||
					return err
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				rec.who = make([]byte, len2, len2)
 | 
									rec.SetOp(tmp)
 | 
				
			||||||
				_, err = io.ReadFull(hc, rec.who)
 | 
					
 | 
				
			||||||
 | 
									tmp = make([]byte, len2, len2)
 | 
				
			||||||
 | 
									_, err = io.ReadFull(hc, tmp)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					log.Println("[Bad cmdSpec.who]")
 | 
										log.Println("[Bad hkexsh.Session.Who]")
 | 
				
			||||||
					return err
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									rec.SetWho(tmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				rec.cmd = make([]byte, len3, len3)
 | 
									tmp = make([]byte, len3, len3)
 | 
				
			||||||
				_, err = io.ReadFull(hc, rec.cmd)
 | 
									_, err = io.ReadFull(hc, tmp)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					log.Println("[Bad cmdSpec.cmd]")
 | 
										log.Println("[Bad hkexsh.Session.Cmd]")
 | 
				
			||||||
					return err
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									rec.SetCmd(tmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				rec.authCookie = make([]byte, len4, len4)
 | 
									tmp = make([]byte, len4, len4)
 | 
				
			||||||
				_, err = io.ReadFull(hc, rec.authCookie)
 | 
									_, err = io.ReadFull(hc, tmp)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					log.Println("[Bad cmdSpec.authCookie]")
 | 
										log.Println("[Bad hkexsh.Session.AuthCookie]")
 | 
				
			||||||
					return err
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									rec.SetAuthCookie(tmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				log.Printf("[cmdSpec: op:%c who:%s cmd:%s auth:****]\n",
 | 
									log.Printf("[hkexsh.Session: op:%c who:%s cmd:%s auth:****]\n",
 | 
				
			||||||
					rec.op[0], string(rec.who), string(rec.cmd))
 | 
										rec.Op()[0], string(rec.Who()), string(rec.Cmd()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				valid, allowedCmds := hkexsh.AuthUser(string(rec.who), string(rec.authCookie), "/etc/hkexsh.passwd")
 | 
									valid, allowedCmds := hkexsh.AuthUser(string(rec.Who()), string(rec.AuthCookie(true)), "/etc/hkexsh.passwd")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Security scrub
 | 
									// Security scrub
 | 
				
			||||||
				for i := range rec.authCookie {
 | 
									rec.ClearAuthCookie()
 | 
				
			||||||
					rec.authCookie[i] = 0
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				runtime.GC()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Tell client if auth was valid
 | 
									// Tell client if auth was valid
 | 
				
			||||||
				if valid {
 | 
									if valid {
 | 
				
			||||||
					hc.Write([]byte{1})
 | 
										hc.Write([]byte{1})
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					log.Println("Invalid user", string(rec.who))
 | 
										log.Println("Invalid user", string(rec.Who()))
 | 
				
			||||||
					hc.Write([]byte{0})
 | 
										hc.Write([]byte{0}) // ? required?
 | 
				
			||||||
					return
 | 
										return
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				log.Printf("[allowedCmds:%s]\n", allowedCmds)
 | 
									log.Printf("[allowedCmds:%s]\n", allowedCmds)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if rec.op[0] == 'c' {
 | 
									if rec.Op()[0] == 'c' {
 | 
				
			||||||
					// Non-interactive command
 | 
										// Non-interactive command
 | 
				
			||||||
					addr := hc.RemoteAddr()
 | 
										addr := hc.RemoteAddr()
 | 
				
			||||||
					//hname := goutmp.GetHost(addr.String())
 | 
										//hname := goutmp.GetHost(addr.String())
 | 
				
			||||||
					hname := strings.Split(addr.String(), ":")[0]
 | 
										hname := strings.Split(addr.String(), ":")[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					log.Printf("[Running command for [%s@%s]]\n", rec.who, hname)
 | 
										log.Printf("[Running command for [%s@%s]]\n", rec.Who(), hname)
 | 
				
			||||||
					runErr, cmdStatus := runShellAs(string(rec.who), string(rec.cmd), false, hc, chaffEnabled)
 | 
										runErr, cmdStatus := runShellAs(string(rec.Who()), string(rec.Cmd()), false, hc, chaffEnabled)
 | 
				
			||||||
					// 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.SetOp([]byte{0})
 | 
				
			||||||
					if runErr != nil {
 | 
										if runErr != nil {
 | 
				
			||||||
						log.Printf("[Error spawning cmd for %s@%s]\n", rec.who, hname)
 | 
											log.Printf("[Error spawning cmd for %s@%s]\n", rec.Who, hname)
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
 | 
											log.Printf("[Command completed for %s@%s, status %d]\n", rec.Who, hname, cmdStatus)
 | 
				
			||||||
						hc.SetStatus(cmdStatus)
 | 
											hc.SetStatus(cmdStatus)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if rec.op[0] == 's' {
 | 
									} else if rec.Op()[0] == 's' {
 | 
				
			||||||
					// Interactive session
 | 
										// Interactive session
 | 
				
			||||||
					addr := hc.RemoteAddr()
 | 
										addr := hc.RemoteAddr()
 | 
				
			||||||
					//hname := goutmp.GetHost(addr.String())
 | 
										//hname := goutmp.GetHost(addr.String())
 | 
				
			||||||
					hname := strings.Split(addr.String(), ":")[0]
 | 
										hname := strings.Split(addr.String(), ":")[0]
 | 
				
			||||||
					log.Printf("[Running shell for [%s@%s]]\n", rec.who, hname)
 | 
										log.Printf("[Running shell for [%s@%s]]\n", rec.Who(), hname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					utmpx := goutmp.Put_utmp(string(rec.who), hname)
 | 
										utmpx := goutmp.Put_utmp(string(rec.Who()), hname)
 | 
				
			||||||
					defer func() { goutmp.Unput_utmp(utmpx) }()
 | 
										defer func() { goutmp.Unput_utmp(utmpx) }()
 | 
				
			||||||
					goutmp.Put_lastlog_entry("hkexsh", string(rec.who), hname)
 | 
										goutmp.Put_lastlog_entry("hkexsh", string(rec.Who()), hname)
 | 
				
			||||||
					runErr, cmdStatus := runShellAs(string(rec.who), string(rec.cmd), true, hc, chaffEnabled)
 | 
										runErr, cmdStatus := runShellAs(string(rec.Who()), string(rec.Cmd()), true, hc, chaffEnabled)
 | 
				
			||||||
					// 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.SetOp([]byte{0})
 | 
				
			||||||
					if runErr != nil {
 | 
										if runErr != nil {
 | 
				
			||||||
						log.Printf("[Error spawning shell for %s@%s]\n", rec.who, hname)
 | 
											log.Printf("[Error spawning shell for %s@%s]\n", rec.Who(), hname)
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						log.Printf("[Shell completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
 | 
											log.Printf("[Shell completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)
 | 
				
			||||||
						hc.SetStatus(cmdStatus)
 | 
											hc.SetStatus(cmdStatus)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if rec.op[0] == 'D' {
 | 
									} else if rec.Op()[0] == 'D' {
 | 
				
			||||||
					// File copy (destination) operation - client copy to server
 | 
										// File copy (destination) operation - client copy to server
 | 
				
			||||||
					log.Printf("[Client->Server copy]\n")
 | 
										log.Printf("[Client->Server copy]\n")
 | 
				
			||||||
					addr := hc.RemoteAddr()
 | 
										addr := hc.RemoteAddr()
 | 
				
			||||||
					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 := runClientToServerCopyAs(string(rec.who), hc, string(rec.cmd), chaffEnabled)
 | 
										runErr, cmdStatus := runClientToServerCopyAs(string(rec.Who()), hc, string(rec.Cmd()), chaffEnabled)
 | 
				
			||||||
					// 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.SetOp([]byte{0})
 | 
				
			||||||
					if runErr != nil {
 | 
										if runErr != nil {
 | 
				
			||||||
						log.Printf("[Error spawning cp for %s@%s]\n", rec.who, hname)
 | 
											log.Printf("[Error spawning cp for %s@%s]\n", rec.Who(), hname)
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
 | 
											log.Printf("[Command completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					hc.SetStatus(cmdStatus)
 | 
										hc.SetStatus(cmdStatus)
 | 
				
			||||||
				} else if rec.op[0] == 'S' {
 | 
									} else if rec.Op()[0] == 'S' {
 | 
				
			||||||
					// File copy (src) operation - server copy to client
 | 
										// File copy (src) operation - server copy to client
 | 
				
			||||||
					log.Printf("[Server->Client copy]\n")
 | 
										log.Printf("[Server->Client copy]\n")
 | 
				
			||||||
					addr := hc.RemoteAddr()
 | 
										addr := hc.RemoteAddr()
 | 
				
			||||||
					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)
 | 
										//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.SetOp([]byte{0})
 | 
				
			||||||
					if runErr != nil {
 | 
										if runErr != nil {
 | 
				
			||||||
						log.Printf("[Error spawning cp for %s@%s]\n", rec.who, hname)
 | 
											log.Printf("[Error spawning cp for %s@%s]\n", rec.Who(), hname)
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
 | 
											log.Printf("[Command completed for %s@%s, status %d]\n", rec.Who(), hname, cmdStatus)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					hc.SetStatus(cmdStatus)
 | 
										hc.SetStatus(cmdStatus)
 | 
				
			||||||
					// Signal other end transfer is complete
 | 
										// Signal other end transfer is complete
 | 
				
			||||||
| 
						 | 
					@ -536,7 +529,7 @@ func main() {
 | 
				
			||||||
					_, _ = hc.Read(nil /*ackByte*/)
 | 
										_, _ = hc.Read(nil /*ackByte*/)
 | 
				
			||||||
					//fmt.Println("Got remote end ack.")
 | 
										//fmt.Println("Got remote end ack.")
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					log.Println("[Bad cmdSpec]")
 | 
										log.Println("[Bad hkexsh.Session]")
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}(conn)
 | 
								}(conn)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue