1

I need to use password authenticated scp to download a file from a server. How do I do so using Go? Tried the following code, but it doesn't pass in the password.

package main

import (
    "os/exec"
    "time"
)

func main() {
    password := "password"
    cmd := exec.Command("scp", "admin@192.168.1.150:file", "file")

    in, err := cmd.StdinPipe()
    if err != nil {
        panic(err)
    }

    defer in.Close()

    out, err := cmd.StdoutPipe()
    if err != nil {
        panic(err)
    }

    defer out.Close()

    if err = cmd.Run(); err != nil {
        panic(err)
    }

    go func() {
        time.Sleep(10 * time.Second)
        _, err = in.Write([]byte(password + "\n"))
        if err != nil {
            panic(err)
        }
    }()
}

Edit: I ended up using the gexpect (github.com/ThomasRooney/gexpect) library.

package main

import (
    "github.com/ThomasRooney/gexpect"
    "log"
)

func main() {
    child, err := gexpect.Spawn("scp admin@192.168.1.150:file file")
    if err != nil {
        log.Fatalln(err)
    }
    child.Expect("password:")
    child.SendLine("password")
    child.Interact()
    child.Close()
}
  • 5
    Don't do that; configure your `ssh` for public/private keys – Basile Starynkevitch Feb 28 '15 at 20:00
  • 1
    There a few cases where I need this, would be useful if you could provide some help :) – user2509594 Feb 28 '15 at 20:04
  • 1
    The problem in doing this is that the password prompt is not to your stdin/stdout, but to the /dev/tty device. It might be possible to work around that using pseudo-terminal connections, but I haven't seen it done. – Thomas Dickey Feb 28 '15 at 20:56
  • @ThomasDickey Interesting, could you tell me more on how to implement this? – user2509594 Feb 28 '15 at 21:24
  • An explanation would be lengthy (I don't program in go, and my explanation would require some tinkering to make it useful to you). I checked my recollection of scp's use of /dev/tty using strace. – Thomas Dickey Feb 28 '15 at 21:34
  • The "expect" program might be able to supply the password, for instance -- http://expect.sourceforge.net/ using a suitable script. From the nature of what it does, I assume it is manipulating things with pseudo-terminals. The "script" program is much simpler, if you simply wanted to study the topic. But that assumes you would call some special wrapper for scp. Within go, there might be some more elegant solution. – Thomas Dickey Feb 28 '15 at 21:42
  • @ThomasDickey If ssh does not support getting a password from a file descriptor or similar, there is probably a damn good reason for that. – fuz Feb 28 '15 at 21:49
  • I'm well aware of that. However, that was not the question. – Thomas Dickey Feb 28 '15 at 21:57

1 Answers1

1

The answer to this self-answered question might help:

Golang write input and get output from terminal process

at least, he mentions in the answer that he "was able to get ssh access working with a password", which is not mentioned explicitly in the question - that's why you probably didn't find it while searching the site?

Community
  • 1
  • 1
rob74
  • 4,939
  • 29
  • 31
  • That's using the SSH library, it makes a connection to the server and calls scp from the server. I don't have scp available to me on the server. – user2509594 Feb 28 '15 at 21:23
  • 1
    @user2509594: for scp to work, you must have scp on the server. scp works over ssh, but technically has nothing to do with it, and the scp binary is required on both sides since it is called via `ssh hostname scp -t` – JimB Feb 28 '15 at 22:41