Removed :port: from 'fancy' arg syntax; more improvements to src/dest file spec logic (esp. fixing bug in multiple src file/dir args to remote dest)

This commit is contained in:
Russ Magee 2018-08-25 23:38:58 -07:00
parent ca2b6efd9b
commit 1986ec6f0c
2 changed files with 50 additions and 50 deletions

View File

@ -35,8 +35,7 @@ type cmdSpec struct {
} }
var ( var (
wg sync.WaitGroup wg sync.WaitGroup
defPort = "2000"
) )
// Get terminal size using 'stty' command // Get terminal size using 'stty' command
@ -54,36 +53,30 @@ func GetSize() (cols, rows int, err error) {
return return
} }
func parseNonSwitchArgs(a []string, dp string) (user, host, port, path string, isDest bool, otherArgs []string) { func parseNonSwitchArgs(a []string) (user, host, path string, isDest bool, otherArgs []string) {
// Whether fancyArg is src or dst file depends on flag.Args() index; // Whether fancyArg is src or dst file depends on flag.Args() index;
// fancyArg as last flag.Args() element denotes dstFile // fancyArg as last flag.Args() element denotes dstFile
// fancyArg as not-last flag.Args() element denotes srcFile // fancyArg as not-last flag.Args() element denotes srcFile
var fancyUser, fancyHost, fancyPort, fancyPath string var fancyUser, fancyHost, fancyPath string
for i, arg := range a { for i, arg := range a {
if strings.Contains(arg, ":") || strings.Contains(arg, "@") { if strings.Contains(arg, ":") || strings.Contains(arg, "@") {
fancyArg := strings.Split(flag.Arg(i), "@") fancyArg := strings.Split(flag.Arg(i), "@")
var fancyHostPortPath []string var fancyHostPath []string
if len(fancyArg) < 2 { if len(fancyArg) < 2 {
//TODO: no user specified, use current //TODO: no user specified, use current
fancyUser = "[default:getUser]" fancyUser = "[default:getUser]"
fancyHostPortPath = strings.Split(fancyArg[0], ":") fancyHostPath = strings.Split(fancyArg[0], ":")
} else { } else {
// user@.... // user@....
fancyUser = fancyArg[0] fancyUser = fancyArg[0]
fancyHostPortPath = strings.Split(fancyArg[1], ":") fancyHostPath = strings.Split(fancyArg[1], ":")
} }
// [...@]host[:port[:path]] // [...@]host[:path]
if len(fancyHostPortPath) > 2 { if len(fancyHostPath) > 1 {
fancyPath = fancyHostPortPath[2] fancyPath = fancyHostPath[1]
} else if len(fancyHostPortPath) > 1 {
fancyPort = fancyHostPortPath[1]
}
fancyHost = fancyHostPortPath[0]
if fancyPort == "" {
fancyPort = dp
} }
fancyHost = fancyHostPath[0]
//if fancyPath == "" { //if fancyPath == "" {
// fancyPath = "." // fancyPath = "."
@ -93,19 +86,18 @@ func parseNonSwitchArgs(a []string, dp string) (user, host, port, path string, i
isDest = true isDest = true
fmt.Println("remote path isDest") fmt.Println("remote path isDest")
} }
fmt.Println("fancyArgs: user:", fancyUser, "host:", fancyHost, "port:", fancyPort, "path:", fancyPath) fmt.Println("fancyArgs: user:", fancyUser, "host:", fancyHost, "path:", fancyPath)
} else { } else {
otherArgs = append(otherArgs, a[i]) otherArgs = append(otherArgs, a[i])
} }
} }
return fancyUser, fancyHost, fancyPort, fancyPath, isDest, otherArgs return fancyUser, fancyHost, fancyPath, isDest, otherArgs
} }
// 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, recurs bool, rec *cmdSpec) (err error, exitStatus int) { func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, recurs bool, rec *cmdSpec) (err error, exitStatus int) {
if remoteDest { if remoteDest {
fmt.Println("local files:", files, "remote filepath:", string(rec.cmd)) fmt.Println("local files:", files, "remote filepath:", string(rec.cmd))
//fmt.Fprintf(conn, "copyMode remoteDest ...\n")
var c *exec.Cmd var c *exec.Cmd
@ -114,7 +106,12 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, recurs bool,
//os.Setenv("TERM", "vt102") // TODO: server or client option? //os.Setenv("TERM", "vt102") // TODO: server or client option?
cmdName := "/bin/tar" cmdName := "/bin/tar"
cmdArgs := []string{"-c", "-f", "/dev/stdout", strings.TrimSpace(files)} cmdArgs := []string{"-c", "-f", "/dev/stdout"}
files = strings.TrimSpace(files)
for _, v := range strings.Split(files, " ") {
cmdArgs = append(cmdArgs, v)
}
fmt.Printf("[%v %v]\n", cmdName, cmdArgs) fmt.Printf("[%v %v]\n", cmdName, cmdArgs)
// NOTE the lack of quotes around --xform option's sed expression. // NOTE the lack of quotes around --xform option's sed expression.
// When args are passed in exec() format, no quoting is required // When args are passed in exec() format, no quoting is required
@ -124,7 +121,11 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, recurs bool,
c.Dir, _ = os.Getwd() c.Dir, _ = os.Getwd()
fmt.Println("[wd:", c.Dir, "]") fmt.Println("[wd:", c.Dir, "]")
c.Stdout = conn c.Stdout = conn
c.Stderr = os.Stderr // Stderr sinkholing is important. Any extraneous output to tarpipe
// messes up remote side as it's expecting pure tar data.
// (For example, if user specifies abs paths, tar outputs
// "Removing leading '/' from path names")
c.Stderr = nil
// Start the command (no pty) // Start the command (no pty)
err = c.Start() // returns immediately err = c.Start() // returns immediately
@ -150,7 +151,6 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, recurs bool,
} }
} else { } else {
fmt.Println("remote filepath:", string(rec.cmd), "local files:", files) fmt.Println("remote filepath:", string(rec.cmd), "local files:", files)
//fmt.Fprintf(conn, "copyMode localDest ...\n")
var c *exec.Cmd var c *exec.Cmd
//os.Clearenv() //os.Clearenv()
@ -159,11 +159,6 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, recurs bool,
cmdName := "/bin/tar" cmdName := "/bin/tar"
destPath := files destPath := files
//if path.IsAbs(files) {
// destPath := files
//} else {
// destPath := strings.Join({os.Getenv("PWD"),files}, os.PathSeparator)
//}
cmdArgs := []string{"-x", "-C", destPath} cmdArgs := []string{"-x", "-C", destPath}
fmt.Printf("[%v %v]\n", cmdName, cmdArgs) fmt.Printf("[%v %v]\n", cmdName, cmdArgs)
@ -284,13 +279,13 @@ func main() {
var cAlg string var cAlg string
var hAlg string var hAlg string
var server string var server string
var port uint
var cmdStr string var cmdStr string
var recursiveCopy bool var recursiveCopy bool
var copySrc []byte var copySrc []byte
var copyDst string var copyDst string
var altUser string
var authCookie string var authCookie string
var chaffEnabled bool var chaffEnabled bool
var chaffFreqMin uint var chaffFreqMin uint
@ -304,8 +299,7 @@ func main() {
flag.BoolVar(&dbg, "d", false, "debug logging") flag.BoolVar(&dbg, "d", false, "debug logging")
flag.StringVar(&cAlg, "c", "C_AES_256", "cipher [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\"]") flag.StringVar(&cAlg, "c", "C_AES_256", "cipher [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\"]")
flag.StringVar(&hAlg, "m", "H_SHA256", "hmac [\"H_SHA256\"]") flag.StringVar(&hAlg, "m", "H_SHA256", "hmac [\"H_SHA256\"]")
flag.StringVar(&server, "s", "localhost:"+defPort, "server hostname/address[:port]") flag.UintVar(&port, "p", 2000, "port")
flag.StringVar(&altUser, "u", "", "specify alternate user")
flag.StringVar(&authCookie, "a", "", "auth cookie") flag.StringVar(&authCookie, "a", "", "auth cookie")
flag.BoolVar(&chaffEnabled, "e", true, "enabled chaff pkts (default true)") flag.BoolVar(&chaffEnabled, "e", true, "enabled chaff pkts (default true)")
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min (msecs)") flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min (msecs)")
@ -325,21 +319,28 @@ func main() {
} }
flag.Parse() flag.Parse()
tmpUser, tmpHost, tmpPort, tmpPath, pathIsDest, otherArgs := remoteUser, tmpHost, tmpPath, pathIsDest, otherArgs :=
parseNonSwitchArgs(flag.Args(), defPort /* defPort */) parseNonSwitchArgs(flag.Args())
fmt.Println("otherArgs:", otherArgs) fmt.Println("otherArgs:", otherArgs)
//fmt.Println("tmpHost:", tmpHost)
//fmt.Println("tmpPath:", tmpPath) // Set defaults if user doesn't specify user, path or port
if tmpUser != "" { var uname string
altUser = tmpUser if remoteUser == "" {
u, _ := user.Current()
uname = u.Username
} else {
uname = remoteUser
} }
if tmpHost != "" { if tmpHost != "" {
server = tmpHost + ":" + tmpPort server = tmpHost + ":" + fmt.Sprintf("%d", port)
//fmt.Println("tmpHost sets server to", server) }
if tmpPath == "" {
tmpPath = "."
} }
var fileArgs string var fileArgs string
if !shellMode && tmpPath != "" { if !shellMode /*&& tmpPath != ""*/ {
// -if pathIsSrc && len(otherArgs) > 1 ERROR // -if pathIsSrc && len(otherArgs) > 1 ERROR
// -else flatten otherArgs into space-delim list => copySrc // -else flatten otherArgs into space-delim list => copySrc
if pathIsDest { if pathIsDest {
@ -456,14 +457,6 @@ func main() {
} }
} }
var uname string
if len(altUser) == 0 {
u, _ := user.Current()
uname = u.Username
} else {
uname = altUser
}
if len(authCookie) == 0 { if len(authCookie) == 0 {
fmt.Printf("Gimme cookie:") fmt.Printf("Gimme cookie:")
ab, err := hkexsh.ReadPassword(int(os.Stdin.Fd())) ab, err := hkexsh.ReadPassword(int(os.Stdin.Fd()))

View File

@ -150,7 +150,10 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
var c *exec.Cmd var c *exec.Cmd
cmdName := "/bin/tar" cmdName := "/bin/tar"
cmdArgs := []string{"-c", "-f", "-", srcPath} //cmdArgs := []string{"-c", "-f", "-", srcPath}
srcDir, srcBase := path.Split(srcPath)
cmdArgs := []string{"-c", "-C", srcDir, "-f", "-", srcBase}
c = exec.Command(cmdName, cmdArgs...) c = exec.Command(cmdName, cmdArgs...)
//If os.Clearenv() isn't called by server above these will be seen in the //If os.Clearenv() isn't called by server above these will be seen in the
@ -160,7 +163,11 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
c.SysProcAttr = &syscall.SysProcAttr{} c.SysProcAttr = &syscall.SysProcAttr{}
c.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid} c.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
c.Stdout = conn c.Stdout = conn
c.Stderr = conn // Stderr sinkholing is important. Any extraneous output to tarpipe
// messes up remote side as it's expecting pure tar data.
// (For example, if user specifies abs paths, tar outputs
// "Removing leading '/' from path names")
c.Stderr = nil
if chaffing { if chaffing {
conn.EnableChaff() conn.EnableChaff()