title: Golang SSH-Server: How to handle file transfer with scp?
body: <p>I have written a small SSH-Server in golang with the crypto/ssh package.</p>
  
  <p>It supports returning an interactive shell and immediate command execution.</p>
  
  <p>Here is a minimal example of the server:</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "io/ioutil"
      "log"
      "net"
      "os/exec"
  
      "golang.org/x/crypto/ssh"
  )
  
  func main() {
      c := &amp;ssh.ServerConfig{
          PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
              if c.User() == "foo" &amp;&amp; string(pass) == "bar" {
                  return nil, nil
              }
              return nil, fmt.Errorf("password rejected for %q", c.User())
          },
      }
  
      keyBytes, _ := ioutil.ReadFile("key")
      key, _ := ssh.ParsePrivateKey(keyBytes)
      c.AddHostKey(key)
  
      listener, _ := net.Listen("tcp", "0.0.0.0:2200")
      for {
          tcpConn, _ := listener.Accept()
          _, chans, reqs, _ := ssh.NewServerConn(tcpConn, c)
          go ssh.DiscardRequests(reqs)
          go handleChannels(chans)
      }
  }
  
  func handleChannels(chans &lt;-chan ssh.NewChannel) {
      for newChannel := range chans {
          go handleChannel(newChannel)
      }
  }
  
  func handleChannel(newChannel ssh.NewChannel) {
      channel, requests, _ := newChannel.Accept()
      for req := range requests {
          switch req.Type {
          case "shell":
              go handleShell(channel)
          case "exec":
              go handleExec(channel, req)
          }
      }
  }
  
  func handleShell(c ssh.Channel) {}
  func handleExec(c ssh.Channel, r *ssh.Request) {
      cmdString, args, _ := parseCommand(r.Payload)
      log.Printf("exec: %s\n", cmdString)
      for i := range args {
          log.Printf("arg %d: %s\n", i, args[i])
      }
      cmd := exec.Command(cmdString, args...)
      cmd.Run()
  }
  
  func parseCommand(b []byte) (string, []string, error) {
      cmdString := strings.TrimSpace(string(b))
      cmdArray := strings.Split(cmdString, " ")
  
      cmd := strings.Trim(cmdArray[0], " ")
      args := cmdArray[1:]
  
      return cmd, args, nil
  }
  </code></pre>
  
  <p>If I run the server and execute scp as follows:</p>
  
  <pre><code>scp -P 2200 test.file foo@localhost:~/
  </code></pre>
  
  <p>the handleExec function is called.</p>
  
  <p>The output of the cmdString shows:</p>
  
  <pre><code>2015/11/22 17:49:14 exec: scp
  2015/11/22 17:49:14 arg 0: -t
  2015/11/22 17:49:14 arg 1: ~/
  </code></pre>
  
  <p>But how can I implement the handleExec function to actually save the file/dir I passed via scp?</p>