mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
Merge branch 'metalint'
This commit is contained in:
commit
fa398159e3
2 changed files with 75 additions and 58 deletions
132
hkexsh/hkexsh.go
132
hkexsh/hkexsh.go
|
@ -36,13 +36,14 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
Log *logger.Writer // reg. syslog output (no -d)
|
||||
wg sync.WaitGroup
|
||||
// Log defaults to regular syslog output (no -d)
|
||||
Log *logger.Writer
|
||||
)
|
||||
|
||||
// Get terminal size using 'stty' command
|
||||
// GetSize gets the terminal size using 'stty' command
|
||||
func GetSize() (cols, rows int, err error) {
|
||||
cmd := exec.Command("stty", "size")
|
||||
cmd := exec.Command("stty", "size") // #nosec
|
||||
cmd.Stdin = os.Stdin
|
||||
out, err := cmd.Output()
|
||||
|
||||
|
@ -50,13 +51,22 @@ func GetSize() (cols, rows int, err error) {
|
|||
log.Println(err)
|
||||
cols, rows = 80, 24 //failsafe
|
||||
} else {
|
||||
fmt.Sscanf(string(out), "%d %d\n", &rows, &cols)
|
||||
n, err := fmt.Sscanf(string(out), "%d %d\n", &rows, &cols)
|
||||
if n < 2 ||
|
||||
rows < 0 ||
|
||||
cols < 0 ||
|
||||
rows > 9000 ||
|
||||
cols > 9000 ||
|
||||
err != nil {
|
||||
log.Printf("GetSize error: rows:%d cols:%d; %v\n",
|
||||
rows, cols, err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// doCopyMode begins a secure hkexsh local<->remote file copy operation.
|
||||
func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *hkexsh.Session) (err error, exitStatus uint32) {
|
||||
func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *hkexsh.Session) (exitStatus uint32, err error) {
|
||||
if remoteDest {
|
||||
log.Println("local files:", files, "remote filepath:", string(rec.Cmd()))
|
||||
|
||||
|
@ -82,7 +92,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *hkexsh.S
|
|||
// files and dirs in different trees to be deposited in a single
|
||||
// remote destDir.
|
||||
for _, v := range strings.Split(files, " ") {
|
||||
v, _ = filepath.Abs(v)
|
||||
v, _ = filepath.Abs(v) // #nosec
|
||||
dirTmp, fileTmp := path.Split(v)
|
||||
if dirTmp == "" {
|
||||
cmdArgs = append(cmdArgs, fileTmp)
|
||||
|
@ -96,8 +106,8 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *hkexsh.S
|
|||
// When args are passed in exec() format, no quoting is required
|
||||
// (as this isn't input from a shell) (right? -rlm 20180823)
|
||||
//cmdArgs := []string{"-xvz", "-C", files, `--xform=s#.*/\(.*\)#\1#`}
|
||||
c = exec.Command(cmdName, cmdArgs...)
|
||||
c.Dir, _ = os.Getwd()
|
||||
c = exec.Command(cmdName, cmdArgs...) // #nosec
|
||||
c.Dir, _ = os.Getwd() // #nosec
|
||||
log.Println("[wd:", c.Dir, "]")
|
||||
c.Stdout = conn
|
||||
stdErrBuffer := new(bytes.Buffer)
|
||||
|
@ -143,7 +153,10 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *hkexsh.S
|
|||
log.Println("Sending local exitStatus:", exitStatus)
|
||||
r := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(r, exitStatus)
|
||||
conn.WritePacket(r, hkexnet.CSOExitStatus)
|
||||
_, we := conn.WritePacket(r, hkexnet.CSOExitStatus)
|
||||
if we != nil {
|
||||
fmt.Println("Error:", we)
|
||||
}
|
||||
|
||||
// Do a final read for remote's exit status
|
||||
s := make([]byte, 4)
|
||||
|
@ -180,7 +193,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *hkexsh.S
|
|||
// When args are passed in exec() format, no quoting is required
|
||||
// (as this isn't input from a shell) (right? -rlm 20180823)
|
||||
//cmdArgs := []string{"-xvz", "-C", destPath, `--xform=s#.*/\(.*\)#\1#`}
|
||||
c = exec.Command(cmdName, cmdArgs...)
|
||||
c = exec.Command(cmdName, cmdArgs...) // #nosec
|
||||
c.Stdin = conn
|
||||
c.Stdout = os.Stdout
|
||||
c.Stderr = os.Stderr
|
||||
|
@ -232,7 +245,7 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
|
|||
// exit with inerr == nil
|
||||
_, inerr := io.Copy(os.Stdout, conn)
|
||||
if inerr != nil {
|
||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
|
||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // #nosec
|
||||
// Copy operations and user logging off will cause
|
||||
// a "use of closed network connection" so handle that
|
||||
// gracefully here
|
||||
|
@ -243,11 +256,11 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
|
|||
}
|
||||
|
||||
rec.SetStatus(uint32(conn.GetStatus()))
|
||||
log.Println("rec.status:", rec.Status)
|
||||
log.Println("rec.status:", rec.Status())
|
||||
|
||||
if isInteractive {
|
||||
log.Println("[* Got EOF *]")
|
||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
|
||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // #nosec
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -273,7 +286,7 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
|
|||
if outerr != nil {
|
||||
log.Println(outerr)
|
||||
fmt.Println(outerr)
|
||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // Best effort.
|
||||
_ = hkexsh.Restore(int(os.Stdin.Fd()), oldState) // #nosec
|
||||
log.Println("[Hanging up]")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
@ -283,16 +296,15 @@ func doShellMode(isInteractive bool, conn *hkexnet.Conn, oldState *hkexsh.State,
|
|||
// Wait until both stdin and stdout goroutines finish before returning
|
||||
// (ensure client gets all data from server before closing)
|
||||
wg.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
func UsageShell() {
|
||||
func usageShell() {
|
||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "%s [opts] [user]@server\n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
func UsageCp() {
|
||||
func usageCp() {
|
||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "%s [opts] srcFileOrDir [...] [user]@server[:dstpath]\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "%s [opts] [user]@server[:srcFileOrDir] dstPath\n", os.Args[0])
|
||||
|
@ -310,10 +322,16 @@ func rejectUserMsg() string {
|
|||
func reqTunnel(hc *hkexnet.Conn, lp uint16, p string /*net.Addr*/, rp uint16) {
|
||||
// Write request to server so it can attempt to set up its end
|
||||
var bTmp bytes.Buffer
|
||||
binary.Write(&bTmp, binary.BigEndian, lp)
|
||||
binary.Write(&bTmp, binary.BigEndian, rp)
|
||||
logger.LogDebug(fmt.Sprintln("[Client sending CSOTunSetup]"))
|
||||
hc.WritePacket(bTmp.Bytes(), hkexnet.CSOTunSetup)
|
||||
if e := binary.Write(&bTmp, binary.BigEndian, lp); e != nil {
|
||||
fmt.Fprintln(os.Stderr, "reqTunnel:", e)
|
||||
}
|
||||
if e := binary.Write(&bTmp, binary.BigEndian, rp); e != nil {
|
||||
fmt.Fprintln(os.Stderr, "reqTunnel:", e)
|
||||
}
|
||||
_ = logger.LogDebug(fmt.Sprintln("[Client sending CSOTunSetup]"))
|
||||
if n, e := hc.WritePacket(bTmp.Bytes(), hkexnet.CSOTunSetup); e != nil || n != len(bTmp.Bytes()) {
|
||||
fmt.Fprintln(os.Stderr, "reqTunnel:", e)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -374,6 +392,18 @@ func launchTuns(conn *hkexnet.Conn, remoteHost string, tuns string) {
|
|||
}
|
||||
}
|
||||
|
||||
func sendSessionParams(conn io.Writer /* *hkexnet.Conn*/, rec *hkexsh.Session) (e error) {
|
||||
_, e = fmt.Fprintf(conn, "%d %d %d %d %d %d\n",
|
||||
len(rec.Op()), len(rec.Who()), len(rec.ConnHost()), len(rec.TermType()), len(rec.Cmd()), len(rec.AuthCookie(true)))
|
||||
_, e = conn.Write(rec.Op())
|
||||
_, e = conn.Write(rec.Who())
|
||||
_, e = conn.Write(rec.ConnHost())
|
||||
_, e = conn.Write(rec.TermType())
|
||||
_, e = conn.Write(rec.Cmd())
|
||||
_, e = conn.Write(rec.AuthCookie(true))
|
||||
return
|
||||
}
|
||||
|
||||
// hkexsh - a client for secure shell and file copy operations.
|
||||
//
|
||||
// While conforming to the basic net.Conn interface HKex.Conn has extra
|
||||
|
@ -390,10 +420,10 @@ func main() {
|
|||
var vopt bool
|
||||
var gopt bool //login via password, asking server to generate authToken
|
||||
var dbg bool
|
||||
var shellMode bool // if true act as shell, else file copier
|
||||
var cAlg string //cipher alg
|
||||
var hAlg string //hmac alg
|
||||
var kAlg string //KEX/KEM alg
|
||||
var shellMode bool // if true act as shell, else file copier
|
||||
var cipherAlg string //cipher alg
|
||||
var hmacAlg string //hmac alg
|
||||
var kexAlg string //KEX/KEM alg
|
||||
var server string
|
||||
var port uint
|
||||
var cmdStr string
|
||||
|
@ -413,9 +443,9 @@ func main() {
|
|||
|
||||
flag.BoolVar(&vopt, "v", false, "show version")
|
||||
flag.BoolVar(&dbg, "d", false, "debug logging")
|
||||
flag.StringVar(&cAlg, "c", "C_AES_256", "`cipher` [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\" | \"C_CRYPTMT1\"]")
|
||||
flag.StringVar(&hAlg, "m", "H_SHA256", "`hmac` [\"H_SHA256\"]")
|
||||
flag.StringVar(&kAlg, "k", "KEX_HERRADURA256", "`kex` [\"KEX_HERRADURA{256/512/1024/2048}\" | \"KEX_KYBER{512/768/1024}\"]")
|
||||
flag.StringVar(&cipherAlg, "c", "C_AES_256", "`cipher` [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\" | \"C_CRYPTMT1\"]")
|
||||
flag.StringVar(&hmacAlg, "m", "H_SHA256", "`hmac` [\"H_SHA256\"]")
|
||||
flag.StringVar(&kexAlg, "k", "KEX_HERRADURA256", "`kex` [\"KEX_HERRADURA{256/512/1024/2048}\" | \"KEX_KYBER{512/768/1024}\"]")
|
||||
flag.UintVar(&port, "p", 2000, "`port`")
|
||||
//flag.StringVar(&authCookie, "a", "", "auth cookie")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enabled chaff pkts (default true)")
|
||||
|
@ -432,9 +462,9 @@ func main() {
|
|||
flag.StringVar(&tunSpecStr, "T", "", "`tunnelspec` localPort:remotePort[,localPort:remotePort,...]")
|
||||
flag.BoolVar(&gopt, "g", false, "ask server to generate authtoken")
|
||||
shellMode = true
|
||||
flag.Usage = UsageShell
|
||||
flag.Usage = usageShell
|
||||
} else {
|
||||
flag.Usage = UsageCp
|
||||
flag.Usage = usageCp
|
||||
}
|
||||
flag.Parse()
|
||||
|
||||
|
@ -524,25 +554,16 @@ func main() {
|
|||
u, _ := user.Current()
|
||||
ab, aerr := ioutil.ReadFile(fmt.Sprintf("%s/.hkexsh_id", u.HomeDir))
|
||||
if aerr == nil {
|
||||
//authCookie = string(ab)
|
||||
idx := strings.Index(string(ab), remoteHost)
|
||||
//fmt.Printf("auth entry idx:%d\n", idx)
|
||||
if idx >= 0 {
|
||||
//fmt.Fprintln(os.Stderr, "[authtoken]")
|
||||
ab = ab[idx:]
|
||||
entries := strings.SplitN(string(ab), "\n", -1)
|
||||
//if len(entries) > 0 {
|
||||
//fmt.Println("entries[0]:", entries[0])
|
||||
authCookie = strings.TrimSpace(entries[0])
|
||||
//} else {
|
||||
// fmt.Fprintln(os.Stderr, "ERROR: no matching authtoken")
|
||||
// os.Exit(1)
|
||||
//}
|
||||
// Security scrub
|
||||
ab = nil
|
||||
runtime.GC()
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, "[no authtoken, use -g to request one from server]")
|
||||
_, _ = fmt.Fprintln(os.Stderr, "[no authtoken, use -g to request one from server]")
|
||||
}
|
||||
} else {
|
||||
log.Printf("[cannot read %s/.hkexsh_id]\n", u.HomeDir)
|
||||
|
@ -589,7 +610,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
conn, err := hkexnet.Dial("tcp", server, cAlg, hAlg, kAlg)
|
||||
conn, err := hkexnet.Dial("tcp", server, cipherAlg, hmacAlg, kexAlg)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
panic(err)
|
||||
|
@ -616,27 +637,19 @@ func main() {
|
|||
if len(authCookie) == 0 {
|
||||
//No auth token, prompt for password
|
||||
fmt.Printf("Gimme cookie:")
|
||||
ab, err := hkexsh.ReadPassword(int(os.Stdin.Fd()))
|
||||
ab, e := hkexsh.ReadPassword(int(os.Stdin.Fd()))
|
||||
fmt.Printf("\r\n")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
authCookie = string(ab)
|
||||
// Security scrub
|
||||
ab = nil
|
||||
runtime.GC()
|
||||
}
|
||||
// Security scrub
|
||||
runtime.GC()
|
||||
|
||||
// Set up session params and send over to server
|
||||
rec := hkexsh.NewSession(op, []byte(uname), []byte(remoteHost), []byte(os.Getenv("TERM")), []byte(cmdStr), []byte(authCookie), 0)
|
||||
_, err = fmt.Fprintf(conn, "%d %d %d %d %d %d\n",
|
||||
len(rec.Op()), len(rec.Who()), len(rec.ConnHost()), len(rec.TermType()), len(rec.Cmd()), len(rec.AuthCookie(true)))
|
||||
_, err = conn.Write(rec.Op())
|
||||
_, err = conn.Write(rec.Who())
|
||||
_, err = conn.Write(rec.ConnHost())
|
||||
_, err = conn.Write(rec.TermType())
|
||||
_, err = conn.Write(rec.Cmd())
|
||||
_, err = conn.Write(rec.AuthCookie(true))
|
||||
sendSessionParams(&conn, rec)
|
||||
|
||||
//Security scrub
|
||||
authCookie = ""
|
||||
|
@ -645,7 +658,10 @@ func main() {
|
|||
// Read auth reply from server
|
||||
authReply := make([]byte, 1) // bool: 0 = fail, 1 = pass
|
||||
_, err = conn.Read(authReply)
|
||||
if authReply[0] == 0 {
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error reading auth reply")
|
||||
rec.SetStatus(255)
|
||||
} else if authReply[0] == 0 {
|
||||
fmt.Fprintln(os.Stderr, rejectUserMsg())
|
||||
rec.SetStatus(255)
|
||||
} else {
|
||||
|
@ -671,7 +687,7 @@ func main() {
|
|||
|
||||
doShellMode(isInteractive, &conn, oldState, rec)
|
||||
} else { // copyMode
|
||||
_, s := doCopyMode(&conn, pathIsDest, fileArgs, rec)
|
||||
s, _ := doCopyMode(&conn, pathIsDest, fileArgs, rec)
|
||||
rec.SetStatus(s)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// +build linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
Loading…
Reference in a new issue