mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/peer"
|
|
"github.com/coder/coder/peerbroker/proto"
|
|
)
|
|
|
|
// Conn wraps a peer connection with helper functions to
|
|
// communicate with the agent.
|
|
type Conn struct {
|
|
// Negotiator is responsible for exchanging messages.
|
|
Negotiator proto.DRPCPeerBrokerClient
|
|
|
|
*peer.Conn
|
|
}
|
|
|
|
// SSH dials the built-in SSH server.
|
|
func (c *Conn) SSH() (net.Conn, error) {
|
|
channel, err := c.Dial(context.Background(), "ssh", &peer.ChannelOptions{
|
|
Protocol: "ssh",
|
|
})
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("dial: %w", err)
|
|
}
|
|
return channel.NetConn(), nil
|
|
}
|
|
|
|
// SSHClient calls SSH to create a client that uses a weak cipher
|
|
// for high throughput.
|
|
func (c *Conn) SSHClient() (*ssh.Client, error) {
|
|
netConn, err := c.SSH()
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("ssh: %w", err)
|
|
}
|
|
sshConn, channels, requests, err := ssh.NewClientConn(netConn, "localhost:22", &ssh.ClientConfig{
|
|
// SSH host validation isn't helpful, because obtaining a peer
|
|
// connection already signifies user-intent to dial a workspace.
|
|
// #nosec
|
|
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("ssh conn: %w", err)
|
|
}
|
|
return ssh.NewClient(sshConn, channels, requests), nil
|
|
}
|
|
|
|
func (c *Conn) Close() error {
|
|
_ = c.Negotiator.DRPCConn().Close()
|
|
return c.Conn.Close()
|
|
}
|