blob: 63ea84f2a5879ee505e3c32ce91cf582b1b0f386 [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"io"
"log"
"github.com/UserExistsError/conpty"
"github.com/gliderlabs/ssh"
)
func startSSHServerSwarming() {
buildletSSHServer = &ssh.Server{
Addr: "localhost:" + sshPort(),
Handler: sshHandler,
PublicKeyHandler: func(ctx ssh.Context, key ssh.PublicKey) bool {
allowed, _, _, _, err := ssh.ParseAuthorizedKey(buldletAuthKeys)
if err != nil {
log.Printf("error parsing authorized key: %s", err)
return false
}
return ssh.KeysEqual(key, allowed)
},
}
go func() {
err := buildletSSHServer.ListenAndServe()
if err != nil {
log.Printf("buildlet SSH Server stopped: %s", err)
}
}()
teardownFuncs = append(teardownFuncs, func() {
buildletSSHServer.Close()
log.Println("shutting down SSH Server")
})
}
func sshHandler(s ssh.Session) {
ptyReq, winCh, isPty := s.Pty()
if !isPty {
fmt.Fprint(s, "scp is not supported\n")
return
}
f, err := conpty.Start(shell(), conpty.ConPtyDimensions(ptyReq.Window.Width, ptyReq.Window.Height))
if err != nil {
fmt.Fprintf(s, "unable to start shell %q: %s\n", shell(), err)
log.Printf("unable to start shell: %s", err)
return
}
defer f.Close()
go func() {
for win := range winCh {
err := f.Resize(win.Width, win.Height)
if err != nil {
log.Printf("error resizing pty: %s", err)
}
}
}()
go io.Copy(f, s) // stdin
go io.Copy(s, f) // stdout
_, err = f.Wait(s.Context())
if err != nil {
log.Printf("Error: %s", err)
return
}
}