mirror of https://gogs.blitter.com/RLabs/xs
-Converted exit status to uint32 (0-255: UNIX exit codes), above for OOB (out-of-band) status
-Failed auth for shell logins now returns extended code CSEBadAuth to client
This commit is contained in:
parent
8a24fb113f
commit
9ff35a69fe
|
@ -34,6 +34,16 @@ import (
|
||||||
"blitter.com/go/hkexsh/herradurakex"
|
"blitter.com/go/hkexsh/herradurakex"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// const CSExtendedCode - extended (>255 UNIX exit status) codes
|
||||||
|
// This indicate channel-related or internal errors
|
||||||
|
const (
|
||||||
|
CSEBadAuth = 1024 // failed login
|
||||||
|
CSETruncCSO // No CSOExitStatus in payload
|
||||||
|
CSEStillOpen // Channel closed unexpectedly
|
||||||
|
CSEExecFail // cmd.Start() (exec) failed
|
||||||
|
CSEPtyExecFail // pty.Start() (exec w/pty) failed
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CSONone = iota // No error, normal packet
|
CSONone = iota // No error, normal packet
|
||||||
CSOHmacInvalid // HMAC mismatch detected on remote end
|
CSOHmacInvalid // HMAC mismatch detected on remote end
|
||||||
|
@ -77,7 +87,7 @@ type (
|
||||||
|
|
||||||
chaff ChaffConfig
|
chaff ChaffConfig
|
||||||
|
|
||||||
closeStat *uint8 // close status
|
closeStat *uint32 // close status (CSOExitStatus)
|
||||||
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
|
||||||
|
@ -86,11 +96,11 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (hc Conn) GetStatus() uint8 {
|
func (hc Conn) GetStatus() uint32 {
|
||||||
return *hc.closeStat
|
return *hc.closeStat
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) SetStatus(stat uint8) {
|
func (hc *Conn) SetStatus(stat uint32) {
|
||||||
*hc.closeStat = stat
|
*hc.closeStat = stat
|
||||||
//fmt.Println("closeStat:", *hc.closeStat)
|
//fmt.Println("closeStat:", *hc.closeStat)
|
||||||
log.Println("closeStat:", *hc.closeStat)
|
log.Println("closeStat:", *hc.closeStat)
|
||||||
|
@ -177,7 +187,7 @@ func Dial(protocol string, ipport string, extensions ...string) (hc *Conn, err e
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Init hkexnet.Conn hc over net.Conn c
|
// Init hkexnet.Conn hc over net.Conn c
|
||||||
hc = &Conn{m: &sync.Mutex{}, c: c, closeStat: new(uint8), h: hkex.New(0, 0), dBuf: new(bytes.Buffer)}
|
hc = &Conn{m: &sync.Mutex{}, c: c, closeStat: new(uint32), h: hkex.New(0, 0), dBuf: new(bytes.Buffer)}
|
||||||
hc.applyConnExtensions(extensions...)
|
hc.applyConnExtensions(extensions...)
|
||||||
|
|
||||||
// Send hkexnet.Conn parameters to remote side
|
// Send hkexnet.Conn parameters to remote side
|
||||||
|
@ -205,14 +215,16 @@ func Dial(protocol string, ipport string, extensions ...string) (hc *Conn, err e
|
||||||
|
|
||||||
hc.r, hc.rm, err = hc.getStream(hc.h.FA())
|
hc.r, hc.rm, err = hc.getStream(hc.h.FA())
|
||||||
hc.w, hc.wm, err = hc.getStream(hc.h.FA())
|
hc.w, hc.wm, err = hc.getStream(hc.h.FA())
|
||||||
*hc.closeStat = 99 // open or prematurely-closed status
|
*hc.closeStat = CSEStillOpen // open or prematurely-closed status
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close a hkex.Conn
|
// Close a hkex.Conn
|
||||||
func (hc *Conn) Close() (err error) {
|
func (hc *Conn) Close() (err error) {
|
||||||
hc.DisableChaff()
|
hc.DisableChaff()
|
||||||
hc.WritePacket([]byte{byte(*hc.closeStat)}, CSOExitStatus)
|
s := make([]byte, 4)
|
||||||
|
binary.BigEndian.PutUint32(s, *hc.closeStat)
|
||||||
|
hc.WritePacket(s, CSOExitStatus)
|
||||||
err = hc.c.Close()
|
err = hc.c.Close()
|
||||||
log.Println("[Conn Closing]")
|
log.Println("[Conn Closing]")
|
||||||
return
|
return
|
||||||
|
@ -308,13 +320,13 @@ func (hl *HKExListener) Accept() (hc Conn, err error) {
|
||||||
// Open raw Conn c
|
// Open raw Conn c
|
||||||
c, err := hl.l.Accept()
|
c, err := hl.l.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hc := Conn{m: &sync.Mutex{}, c: nil, h: nil, closeStat: new(uint8), cipheropts: 0, opts: 0,
|
hc := Conn{m: &sync.Mutex{}, c: nil, h: nil, closeStat: new(uint32), cipheropts: 0, opts: 0,
|
||||||
r: nil, w: nil}
|
r: nil, w: nil}
|
||||||
return hc, err
|
return hc, err
|
||||||
}
|
}
|
||||||
log.Println("[Accepted]")
|
log.Println("[Accepted]")
|
||||||
|
|
||||||
hc = Conn{m: &sync.Mutex{}, c: c, h: hkex.New(0, 0), closeStat: new(uint8), WinCh: make(chan WinSize, 1),
|
hc = Conn{m: &sync.Mutex{}, c: c, h: hkex.New(0, 0), closeStat: new(uint32), WinCh: make(chan WinSize, 1),
|
||||||
dBuf: new(bytes.Buffer)}
|
dBuf: new(bytes.Buffer)}
|
||||||
|
|
||||||
// Read in hkexnet.Conn parameters over raw Conn c
|
// Read in hkexnet.Conn parameters over raw Conn c
|
||||||
|
@ -438,7 +450,7 @@ 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.SetStatus(payloadBytes[0])
|
hc.SetStatus(binary.BigEndian.Uint32(payloadBytes))
|
||||||
//!// If remote end is closing with an error, reply we're closing ours
|
//!// If remote end is closing with an error, reply we're closing ours
|
||||||
//!if hc.GetStatus() != 0 {
|
//!if hc.GetStatus() != 0 {
|
||||||
//! log.Print("CSOExitStatus:", hc.GetStatus())
|
//! log.Print("CSOExitStatus:", hc.GetStatus())
|
||||||
|
@ -446,7 +458,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
//!}
|
//!}
|
||||||
} else {
|
} else {
|
||||||
log.Println("[truncated payload, cannot determine CSOExitStatus]")
|
log.Println("[truncated payload, cannot determine CSOExitStatus]")
|
||||||
*hc.closeStat = 98
|
*hc.closeStat = CSETruncCSO
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hc.dBuf.Write(payloadBytes)
|
hc.dBuf.Write(payloadBytes)
|
||||||
|
@ -458,7 +470,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
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 == CSETruncCSO {
|
||||||
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
|
||||||
|
|
|
@ -9,6 +9,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -34,7 +35,7 @@ type cmdSpec struct {
|
||||||
who []byte
|
who []byte
|
||||||
cmd []byte
|
cmd []byte
|
||||||
authCookie []byte
|
authCookie []byte
|
||||||
status int // UNIX exit status is uint8, but os.Exit() wants int
|
status uint32 // exit status (0-255 is std UNIX status)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -98,7 +99,7 @@ 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 int) {
|
func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec) (err error, exitStatus uint32) {
|
||||||
if remoteDest {
|
if remoteDest {
|
||||||
fmt.Println("local files:", files, "remote filepath:", string(rec.cmd))
|
fmt.Println("local files:", files, "remote filepath:", string(rec.cmd))
|
||||||
|
|
||||||
|
@ -161,7 +162,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
||||||
// defined for both Unix and Windows and in both cases has
|
// defined for both Unix and Windows and in both cases has
|
||||||
// an ExitStatus() method with the same signature.
|
// an ExitStatus() method with the same signature.
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = uint32(status.ExitStatus())
|
||||||
log.Printf("Exit Status: %d", exitStatus)
|
log.Printf("Exit Status: %d", exitStatus)
|
||||||
fmt.Print(stdErrBuffer)
|
fmt.Print(stdErrBuffer)
|
||||||
}
|
}
|
||||||
|
@ -169,7 +170,9 @@ 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( /*255*/ rec.status)}, hkexnet.CSOExitStatus)
|
s := make([]byte, 4)
|
||||||
|
binary.BigEndian.PutUint32(s, rec.status)
|
||||||
|
conn.WritePacket(s, hkexnet.CSOExitStatus)
|
||||||
_, _ = conn.Read(nil /*ackByte*/)
|
_, _ = conn.Read(nil /*ackByte*/)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,7 +212,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
||||||
// defined for both Unix and Windows and in both cases has
|
// defined for both Unix and Windows and in both cases has
|
||||||
// an ExitStatus() method with the same signature.
|
// an ExitStatus() method with the same signature.
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = uint32(status.ExitStatus())
|
||||||
log.Printf("Exit Status: %d", exitStatus)
|
log.Printf("Exit Status: %d", exitStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +220,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
||||||
// return local status, if nonzero;
|
// return local status, if nonzero;
|
||||||
// otherwise, return remote status if nonzero
|
// otherwise, return remote status if nonzero
|
||||||
if exitStatus == 0 {
|
if exitStatus == 0 {
|
||||||
exitStatus = int(conn.GetStatus())
|
exitStatus = uint32(conn.GetStatus())
|
||||||
}
|
}
|
||||||
//fmt.Println("*** server->client cp finished ***")
|
//fmt.Println("*** server->client cp finished ***")
|
||||||
}
|
}
|
||||||
|
@ -250,7 +253,7 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rec.status = int(conn.GetStatus())
|
rec.status = uint32(conn.GetStatus())
|
||||||
log.Println("rec.status:", rec.status)
|
log.Println("rec.status:", rec.status)
|
||||||
|
|
||||||
if isInteractive {
|
if isInteractive {
|
||||||
|
@ -282,7 +285,7 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
|
||||||
log.Println(outerr)
|
log.Println(outerr)
|
||||||
fmt.Println(outerr)
|
fmt.Println(outerr)
|
||||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
|
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
|
||||||
os.Exit(255)
|
os.Exit(254)
|
||||||
}
|
}
|
||||||
log.Println("[Sent EOF]")
|
log.Println("[Sent EOF]")
|
||||||
}()
|
}()
|
||||||
|
@ -549,7 +552,15 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if rec.status != 0 {
|
if rec.status != 0 {
|
||||||
fmt.Fprintln(os.Stderr, "Remote end exited with status:", rec.status)
|
fmt.Fprint(os.Stderr, "Remote end ")
|
||||||
|
if rec.status == hkexnet.CSEBadAuth {
|
||||||
|
// shell exit status can't hold CSEBadAuth (uint32)
|
||||||
|
rec.status = 255
|
||||||
|
fmt.Fprintln(os.Stderr, "replied: bad auth")
|
||||||
|
} else {
|
||||||
|
fmt.Fprintln(os.Stderr, "exited with status:", rec.status)
|
||||||
}
|
}
|
||||||
os.Exit(rec.status)
|
|
||||||
|
}
|
||||||
|
os.Exit(int(rec.status))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -40,7 +41,7 @@ type cmdSpec struct {
|
||||||
|
|
||||||
/* -------------------------------------------------------------- */
|
/* -------------------------------------------------------------- */
|
||||||
// Perform a client->server copy
|
// Perform a client->server copy
|
||||||
func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffing bool) (err error, exitStatus int) {
|
func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffing bool) (err error, exitStatus uint32) {
|
||||||
u, _ := user.Lookup(who)
|
u, _ := user.Lookup(who)
|
||||||
var uid, gid uint32
|
var uid, gid uint32
|
||||||
fmt.Sscanf(u.Uid, "%d", &uid)
|
fmt.Sscanf(u.Uid, "%d", &uid)
|
||||||
|
@ -99,7 +100,7 @@ func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffi
|
||||||
err = c.Start() // returns immediately
|
err = c.Start() // returns immediately
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Command finished with error: %v", err)
|
log.Printf("Command finished with error: %v", err)
|
||||||
return err, 253 // !?
|
return err, hkexnet.CSEExecFail // !?
|
||||||
} else {
|
} else {
|
||||||
if err := c.Wait(); err != nil {
|
if err := c.Wait(); err != nil {
|
||||||
//fmt.Println("*** c.Wait() done ***")
|
//fmt.Println("*** c.Wait() done ***")
|
||||||
|
@ -111,7 +112,7 @@ func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffi
|
||||||
// defined for both Unix and Windows and in both cases has
|
// defined for both Unix and Windows and in both cases has
|
||||||
// an ExitStatus() method with the same signature.
|
// an ExitStatus() method with the same signature.
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = uint32(status.ExitStatus())
|
||||||
log.Printf("Exit Status: %d", exitStatus)
|
log.Printf("Exit Status: %d", exitStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +123,7 @@ func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a server->client copy
|
// Perform a server->client copy
|
||||||
func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaffing bool) (err error, exitStatus int) {
|
func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaffing bool) (err error, exitStatus uint32) {
|
||||||
u, _ := user.Lookup(who)
|
u, _ := user.Lookup(who)
|
||||||
var uid, gid uint32
|
var uid, gid uint32
|
||||||
fmt.Sscanf(u.Uid, "%d", &uid)
|
fmt.Sscanf(u.Uid, "%d", &uid)
|
||||||
|
@ -179,7 +180,7 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
|
||||||
err = c.Start() // returns immediately
|
err = c.Start() // returns immediately
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Command finished with error: %v", err)
|
log.Printf("Command finished with error: %v", err)
|
||||||
return err, 253 // !?
|
return err, hkexnet.CSEExecFail // !?
|
||||||
} else {
|
} else {
|
||||||
if err := c.Wait(); err != nil {
|
if err := c.Wait(); err != nil {
|
||||||
//fmt.Println("*** c.Wait() done ***")
|
//fmt.Println("*** c.Wait() done ***")
|
||||||
|
@ -191,7 +192,7 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
|
||||||
// defined for both Unix and Windows and in both cases has
|
// defined for both Unix and Windows and in both cases has
|
||||||
// an ExitStatus() method with the same signature.
|
// an ExitStatus() method with the same signature.
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = uint32(status.ExitStatus())
|
||||||
log.Printf("Exit Status: %d", exitStatus)
|
log.Printf("Exit Status: %d", exitStatus)
|
||||||
// TODO: send stdErrBuffer to client via specific packet
|
// TODO: send stdErrBuffer to client via specific packet
|
||||||
// type so it can inform user
|
// type so it can inform user
|
||||||
|
@ -209,7 +210,7 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
|
||||||
// Run a command (via default shell) as a specific user
|
// Run a command (via default shell) as a specific user
|
||||||
//
|
//
|
||||||
// Uses ptys to support commands which expect a terminal.
|
// Uses ptys to support commands which expect a terminal.
|
||||||
func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, chaffing bool) (err error, exitStatus int) {
|
func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, chaffing bool) (err error, exitStatus uint32) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
u, _ := user.Lookup(who)
|
u, _ := user.Lookup(who)
|
||||||
var uid, gid uint32
|
var uid, gid uint32
|
||||||
|
@ -248,7 +249,7 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
|
||||||
// Start the command with a pty.
|
// Start the command with a pty.
|
||||||
ptmx, err := pty.Start(c) // returns immediately with ptmx file
|
ptmx, err := pty.Start(c) // returns immediately with ptmx file
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, 0
|
return err, hkexnet.CSEPtyExecFail
|
||||||
}
|
}
|
||||||
// Make sure to close the pty at the end.
|
// Make sure to close the pty at the end.
|
||||||
defer func() { _ = ptmx.Close() }() // Best effort.
|
defer func() { _ = ptmx.Close() }() // Best effort.
|
||||||
|
@ -312,11 +313,11 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
|
||||||
// defined for both Unix and Windows and in both cases has
|
// defined for both Unix and Windows and in both cases has
|
||||||
// an ExitStatus() method with the same signature.
|
// an ExitStatus() method with the same signature.
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = uint32(status.ExitStatus())
|
||||||
log.Printf("Exit Status: %d", exitStatus)
|
log.Printf("Exit Status: %d", exitStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.SetStatus(uint8(exitStatus))
|
conn.SetStatus(exitStatus)
|
||||||
}
|
}
|
||||||
wg.Wait() // Wait on pty->stdout completion to client
|
wg.Wait() // Wait on pty->stdout completion to client
|
||||||
}
|
}
|
||||||
|
@ -446,6 +447,7 @@ func main() {
|
||||||
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), "/etc/hkexsh.passwd")
|
||||||
|
|
||||||
// Security scrub
|
// Security scrub
|
||||||
for i := range rec.authCookie {
|
for i := range rec.authCookie {
|
||||||
rec.authCookie[i] = 0
|
rec.authCookie[i] = 0
|
||||||
|
@ -454,6 +456,14 @@ func main() {
|
||||||
|
|
||||||
if !valid {
|
if !valid {
|
||||||
log.Println("Invalid user", string(rec.who))
|
log.Println("Invalid user", string(rec.who))
|
||||||
|
|
||||||
|
// Signal other end auth failed
|
||||||
|
rec.status = hkexnet.CSEBadAuth
|
||||||
|
hc.SetStatus(hkexnet.CSEBadAuth)
|
||||||
|
s := make([]byte, 4)
|
||||||
|
binary.BigEndian.PutUint32(s, hkexnet.CSEBadAuth)
|
||||||
|
hc.WritePacket(s, hkexnet.CSOExitStatus)
|
||||||
|
|
||||||
hc.Write([]byte(rejectUserMsg()))
|
hc.Write([]byte(rejectUserMsg()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -474,7 +484,7 @@ func main() {
|
||||||
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(uint8(cmdStatus))
|
hc.SetStatus(cmdStatus)
|
||||||
}
|
}
|
||||||
} else if rec.op[0] == 's' {
|
} else if rec.op[0] == 's' {
|
||||||
// Interactive session
|
// Interactive session
|
||||||
|
@ -494,7 +504,7 @@ func main() {
|
||||||
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(uint8(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
|
||||||
|
@ -511,7 +521,7 @@ func main() {
|
||||||
} 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(uint8(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")
|
||||||
|
@ -528,9 +538,11 @@ func main() {
|
||||||
} 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(uint8(cmdStatus))
|
hc.SetStatus(cmdStatus)
|
||||||
// Signal other end transfer is complete
|
// Signal other end transfer is complete
|
||||||
hc.WritePacket([]byte{byte( /*255*/ cmdStatus)}, hkexnet.CSOExitStatus)
|
s := make([]byte, 4)
|
||||||
|
binary.BigEndian.PutUint32(s, cmdStatus)
|
||||||
|
hc.WritePacket(s, hkexnet.CSOExitStatus)
|
||||||
//fmt.Println("Waiting for EOF from other end.")
|
//fmt.Println("Waiting for EOF from other end.")
|
||||||
_, _ = hc.Read(nil /*ackByte*/)
|
_, _ = hc.Read(nil /*ackByte*/)
|
||||||
//fmt.Println("Got remote end ack.")
|
//fmt.Println("Got remote end ack.")
|
||||||
|
|
Loading…
Reference in New Issue