func pipe(dst, src ssh.Channel) { _, err := io.Copy(dst, src) if err != nil { fmt.Println(err.Error()) } dst.CloseWrite() }
func (s *sshServer) handleRequests(channel ssh.Channel, in <-chan *ssh.Request) error { env := make(map[string]string) for req := range in { switch req.Type { default: log.Printf("unrecognized ssh request type=%q payload=%s wantreply=%t", req.Type, req.Payload, req.WantReply) req.Reply(false, nil) // unhandled; tell them so case "env": var e envReq if err := ssh.Unmarshal(req.Payload, &e); err != nil { req.Reply(false, nil) return err } req.Reply(true, nil) env[string(e.Key)] = string(e.Val) case "exec": var e execReq if err := ssh.Unmarshal(req.Payload, &e); err != nil { req.Reply(false, nil) return err } req.Reply(true, nil) var cmdbuf bytes.Buffer for k, v := range env { cmdbuf.WriteString(k) cmdbuf.WriteByte('=') cmdbuf.WriteString(v) cmdbuf.WriteByte(' ') } cmdbuf.Write(e.Command) log.Printf("Running command %q", cmdbuf.String()) cmd := &packer.RemoteCmd{Command: cmdbuf.String()} cmd.Stdout = channel cmd.Stderr = channel.Stderr() var rc int if err := s.comm.Start(cmd); err != nil { rc = 255 // TODO: What is a better choice here? } else { cmd.Wait() rc = cmd.ExitStatus } channel.CloseWrite() channel.SendRequest("exit-status", false, []byte{0, 0, 0, byte(rc)}) channel.Close() } } return nil }
func forwardUnixSocket(channel ssh.Channel, addr string) { conn, err := net.Dial("unix", addr) if err != nil { return } var wg sync.WaitGroup wg.Add(2) go func() { io.Copy(conn, channel) conn.(*net.UnixConn).CloseWrite() wg.Done() }() go func() { io.Copy(channel, conn) channel.CloseWrite() wg.Done() }() wg.Wait() conn.Close() channel.Close() }