@@ -8,10 +8,13 @@ import (
8
8
"fmt"
9
9
"io"
10
10
"net"
11
+ "os/exec"
11
12
"sync"
13
+ "syscall"
12
14
"time"
13
15
14
16
"cdr.dev/slog"
17
+ "github.com/coder/coder/console/pty"
15
18
"github.com/coder/coder/peer"
16
19
"github.com/coder/coder/peerbroker"
17
20
"github.com/coder/retry"
@@ -50,33 +53,83 @@ type server struct {
50
53
}
51
54
52
55
func (s * server ) init (ctx context.Context ) {
53
- forwardHandler := & ssh.ForwardedTCPHandler {}
54
- key , err := rsa .GenerateKey (rand .Reader , 2048 )
56
+ // Clients' should ignore the host key when connecting.
57
+ // The agent needs to authenticate with coderd to SSH,
58
+ // so SSH authentication doesn't improve security.
59
+ randomHostKey , err := rsa .GenerateKey (rand .Reader , 2048 )
55
60
if err != nil {
56
61
panic (err )
57
62
}
58
- signer , err := gossh .NewSignerFromKey (key )
63
+ randomSigner , err := gossh .NewSignerFromKey (randomHostKey )
59
64
if err != nil {
60
65
panic (err )
61
66
}
67
+ sshLogger := s .options .Logger .Named ("ssh-server" )
68
+ forwardHandler := & ssh.ForwardedTCPHandler {}
62
69
s .sshServer = & ssh.Server {
63
70
ChannelHandlers : ssh .DefaultChannelHandlers ,
64
71
ConnectionFailedCallback : func (conn net.Conn , err error ) {
65
- fmt . Printf ( "Conn failed: %s \n " , err )
72
+ sshLogger . Info ( ctx , "ssh connection ended " , slog . Error ( err ) )
66
73
},
67
- Handler : func (s ssh.Session ) {
68
- fmt .Printf ("WE GOT %q %q\n " , s .User (), s .RawCommand ())
74
+ Handler : func (session ssh.Session ) {
75
+ fmt .Printf ("WE GOT %q %q\n " , session .User (), session .RawCommand ())
76
+
77
+ sshPty , windowSize , isPty := session .Pty ()
78
+ if isPty {
79
+ cmd := exec .CommandContext (ctx , session .Command ()[0 ], session .Command ()[1 :]... )
80
+ cmd .Env = append (cmd .Env , fmt .Sprintf ("TERM=%s" , sshPty .Term ))
81
+ cmd .SysProcAttr = & syscall.SysProcAttr {
82
+ Setsid : true ,
83
+ Setctty : true ,
84
+ }
85
+ pty , err := pty .New ()
86
+ if err != nil {
87
+ panic (err )
88
+ }
89
+ err = pty .Resize (uint16 (sshPty .Window .Width ), uint16 (sshPty .Window .Height ))
90
+ if err != nil {
91
+ panic (err )
92
+ }
93
+ cmd .Stdout = pty .OutPipe ()
94
+ cmd .Stderr = pty .OutPipe ()
95
+ cmd .Stdin = pty .InPipe ()
96
+ err = cmd .Start ()
97
+ if err != nil {
98
+ panic (err )
99
+ }
100
+ go func () {
101
+ for win := range windowSize {
102
+ err := pty .Resize (uint16 (win .Width ), uint16 (win .Height ))
103
+ if err != nil {
104
+ panic (err )
105
+ }
106
+ }
107
+ }()
108
+ go func () {
109
+ io .Copy (pty .Writer (), session )
110
+ }()
111
+ fmt .Printf ("Got here!\n " )
112
+ io .Copy (session , pty .Reader ())
113
+ fmt .Printf ("Done!\n " )
114
+ cmd .Wait ()
115
+ }
69
116
},
70
- HostSigners : []ssh.Signer {signer },
117
+ HostSigners : []ssh.Signer {randomSigner },
71
118
LocalPortForwardingCallback : func (ctx ssh.Context , destinationHost string , destinationPort uint32 ) bool {
72
119
// Allow local port forwarding all!
120
+ sshLogger .Debug (ctx , "local port forward" ,
121
+ slog .F ("destination-host" , destinationHost ),
122
+ slog .F ("destination-port" , destinationPort ))
73
123
return true
74
124
},
75
125
PtyCallback : func (ctx ssh.Context , pty ssh.Pty ) bool {
76
- return false
126
+ return true
77
127
},
78
128
ReversePortForwardingCallback : func (ctx ssh.Context , bindHost string , bindPort uint32 ) bool {
79
- // Allow revere port forwarding all!
129
+ // Allow reverse port forwarding all!
130
+ sshLogger .Debug (ctx , "local port forward" ,
131
+ slog .F ("bind-host" , bindHost ),
132
+ slog .F ("bind-port" , bindPort ))
80
133
return true
81
134
},
82
135
RequestHandlers : map [string ]ssh.RequestHandler {
@@ -91,9 +144,6 @@ func (s *server) init(ctx context.Context) {
91
144
// encrypted. If possible, we'd disable encryption entirely here.
92
145
Ciphers : []string {"arcfour" },
93
146
},
94
- PublicKeyCallback : func (conn gossh.ConnMetadata , key gossh.PublicKey ) (* gossh.Permissions , error ) {
95
- return & gossh.Permissions {}, nil
96
- },
97
147
NoClientAuth : true ,
98
148
}
99
149
},
0 commit comments