github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/exp/newsshd/newsshd.go (about) 1 // Copyright 2018 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "io" 10 "io/ioutil" 11 "log" 12 "os" 13 "os/exec" 14 "strings" 15 "syscall" 16 "unsafe" 17 18 "github.com/gliderlabs/ssh" 19 "github.com/kr/pty" // TODO: get rid of krpty 20 flag "github.com/spf13/pflag" 21 ) 22 23 var ( 24 hostKeyFile = flag.StringP("hostkeyfile", "h", "/etc/ssh_host_rsa_key", "file for host key") 25 pubKeyFile = flag.StringP("pubkeyfile", "k", "key.pub", "file for public key") 26 port = flag.StringP("port", "p", "2222", "default port") 27 ) 28 29 func setWinsize(f *os.File, w, h int) { 30 syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), uintptr(syscall.TIOCSWINSZ), 31 uintptr(unsafe.Pointer(&struct{ h, w, x, y uint16 }{uint16(h), uint16(w), 0, 0}))) 32 } 33 34 func handler(s ssh.Session) { 35 var a []string 36 if len(s.Command()) > 0 { 37 a = append([]string{"-c"}, strings.Join(s.Command(), " ")) 38 } 39 cmd := exec.Command("/bin/sh", a...) 40 cmd.Env = append(cmd.Env, s.Environ()...) 41 ptyReq, winCh, isPty := s.Pty() 42 if isPty { 43 cmd.Env = append(cmd.Env, fmt.Sprintf("TERM=%s", ptyReq.Term)) 44 f, err := pty.Start(cmd) 45 if err != nil { 46 log.Print(err) 47 return 48 } 49 go func() { 50 for win := range winCh { 51 setWinsize(f, win.Width, win.Height) 52 } 53 }() 54 go func() { 55 io.Copy(f, s) // stdin 56 }() 57 io.Copy(s, f) // stdout 58 } else { 59 cmd.Stdin, cmd.Stdout, cmd.Stderr = s, s, s 60 if err := cmd.Run(); err != nil { 61 log.Print(err) 62 return 63 } 64 } 65 } 66 func main() { 67 flag.Parse() 68 publicKeyOption := func(ctx ssh.Context, key ssh.PublicKey) bool { 69 // Glob the users's home directory for all the 70 // possible keys? 71 data, err := ioutil.ReadFile(*pubKeyFile) 72 if err != nil { 73 fmt.Print(err) 74 return false 75 } 76 allowed, _, _, _, _ := ssh.ParseAuthorizedKey(data) 77 return ssh.KeysEqual(key, allowed) 78 } 79 80 server := ssh.Server{ 81 LocalPortForwardingCallback: ssh.LocalPortForwardingCallback(func(ctx ssh.Context, dhost string, dport uint32) bool { 82 log.Println("Accepted forward", dhost, dport) 83 return true 84 }), 85 Addr: ":" + *port, 86 PublicKeyHandler: publicKeyOption, 87 ReversePortForwardingCallback: ssh.ReversePortForwardingCallback(func(ctx ssh.Context, host string, port uint32) bool { 88 log.Println("attempt to bind", host, port, "granted") 89 return true 90 }), 91 Handler: handler, 92 } 93 94 server.SetOption(ssh.HostKeyFile(*hostKeyFile)) 95 log.Println("starting ssh server on port " + *port) 96 log.Fatal(server.ListenAndServe()) 97 }