...
1 package ssh
2
3 import (
4 "errors"
5 "io"
6 "net"
7 )
8
9
10
11
12
13
14 type streamLocalChannelOpenDirectMsg struct {
15 socketPath string
16 reserved0 string
17 reserved1 uint32
18 }
19
20
21
22 type forwardedStreamLocalPayload struct {
23 SocketPath string
24 Reserved0 string
25 }
26
27
28
29 type streamLocalChannelForwardMsg struct {
30 socketPath string
31 }
32
33
34 func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
35 c.handleForwardsOnce.Do(c.handleForwards)
36 m := streamLocalChannelForwardMsg{
37 socketPath,
38 }
39
40 ok, _, err := c.SendRequest("streamlocal-forward@openssh.com", true, Marshal(&m))
41 if err != nil {
42 return nil, err
43 }
44 if !ok {
45 return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer")
46 }
47 ch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: "unix"})
48
49 return &unixListener{socketPath, c, ch}, nil
50 }
51
52 func (c *Client) dialStreamLocal(socketPath string) (Channel, error) {
53 msg := streamLocalChannelOpenDirectMsg{
54 socketPath: socketPath,
55 }
56 ch, in, err := c.OpenChannel("direct-streamlocal@openssh.com", Marshal(&msg))
57 if err != nil {
58 return nil, err
59 }
60 go DiscardRequests(in)
61 return ch, err
62 }
63
64 type unixListener struct {
65 socketPath string
66
67 conn *Client
68 in <-chan forward
69 }
70
71
72 func (l *unixListener) Accept() (net.Conn, error) {
73 s, ok := <-l.in
74 if !ok {
75 return nil, io.EOF
76 }
77 ch, incoming, err := s.newCh.Accept()
78 if err != nil {
79 return nil, err
80 }
81 go DiscardRequests(incoming)
82
83 return &chanConn{
84 Channel: ch,
85 laddr: &net.UnixAddr{
86 Name: l.socketPath,
87 Net: "unix",
88 },
89 raddr: &net.UnixAddr{
90 Name: "@",
91 Net: "unix",
92 },
93 }, nil
94 }
95
96
97 func (l *unixListener) Close() error {
98
99 l.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: "unix"})
100 m := streamLocalChannelForwardMsg{
101 l.socketPath,
102 }
103 ok, _, err := l.conn.SendRequest("cancel-streamlocal-forward@openssh.com", true, Marshal(&m))
104 if err == nil && !ok {
105 err = errors.New("ssh: cancel-streamlocal-forward@openssh.com failed")
106 }
107 return err
108 }
109
110
111 func (l *unixListener) Addr() net.Addr {
112 return &net.UnixAddr{
113 Name: l.socketPath,
114 Net: "unix",
115 }
116 }
117
View as plain text