Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / golang.org / x / crypto / ssh / streamlocal.go
1 package ssh
2
3 import (
4         "errors"
5         "io"
6         "net"
7 )
8
9 // streamLocalChannelOpenDirectMsg is a struct used for SSH_MSG_CHANNEL_OPEN message
10 // with "direct-streamlocal@openssh.com" string.
11 //
12 // See openssh-portable/PROTOCOL, section 2.4. connection: Unix domain socket forwarding
13 // https://github.com/openssh/openssh-portable/blob/master/PROTOCOL#L235
14 type streamLocalChannelOpenDirectMsg struct {
15         socketPath string
16         reserved0  string
17         reserved1  uint32
18 }
19
20 // forwardedStreamLocalPayload is a struct used for SSH_MSG_CHANNEL_OPEN message
21 // with "forwarded-streamlocal@openssh.com" string.
22 type forwardedStreamLocalPayload struct {
23         SocketPath string
24         Reserved0  string
25 }
26
27 // streamLocalChannelForwardMsg is a struct used for SSH2_MSG_GLOBAL_REQUEST message
28 // with "streamlocal-forward@openssh.com"/"cancel-streamlocal-forward@openssh.com" string.
29 type streamLocalChannelForwardMsg struct {
30         socketPath string
31 }
32
33 // ListenUnix is similar to ListenTCP but uses a Unix domain socket.
34 func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
35         c.handleForwardsOnce.Do(c.handleForwards)
36         m := streamLocalChannelForwardMsg{
37                 socketPath,
38         }
39         // send message
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 // Accept waits for and returns the next connection to the listener.
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 // Close closes the listener.
97 func (l *unixListener) Close() error {
98         // this also closes the listener.
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 // Addr returns the listener's network address.
111 func (l *unixListener) Addr() net.Addr {
112         return &net.UnixAddr{
113                 Name: l.socketPath,
114                 Net:  "unix",
115         }
116 }