mirror of https://github.com/gogits/gogs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
3.4 KiB
144 lines
3.4 KiB
// Copyright 2013 The Go Authors. All rights reserved. |
|
// Use of this source code is governed by a BSD-style |
|
// license that can be found in the LICENSE file. |
|
|
|
package ssh |
|
|
|
import ( |
|
"fmt" |
|
"net" |
|
) |
|
|
|
// OpenChannelError is returned if the other side rejects an |
|
// OpenChannel request. |
|
type OpenChannelError struct { |
|
Reason RejectionReason |
|
Message string |
|
} |
|
|
|
func (e *OpenChannelError) Error() string { |
|
return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message) |
|
} |
|
|
|
// ConnMetadata holds metadata for the connection. |
|
type ConnMetadata interface { |
|
// User returns the user ID for this connection. |
|
// It is empty if no authentication is used. |
|
User() string |
|
|
|
// SessionID returns the sesson hash, also denoted by H. |
|
SessionID() []byte |
|
|
|
// ClientVersion returns the client's version string as hashed |
|
// into the session ID. |
|
ClientVersion() []byte |
|
|
|
// ServerVersion returns the server's version string as hashed |
|
// into the session ID. |
|
ServerVersion() []byte |
|
|
|
// RemoteAddr returns the remote address for this connection. |
|
RemoteAddr() net.Addr |
|
|
|
// LocalAddr returns the local address for this connection. |
|
LocalAddr() net.Addr |
|
} |
|
|
|
// Conn represents an SSH connection for both server and client roles. |
|
// Conn is the basis for implementing an application layer, such |
|
// as ClientConn, which implements the traditional shell access for |
|
// clients. |
|
type Conn interface { |
|
ConnMetadata |
|
|
|
// SendRequest sends a global request, and returns the |
|
// reply. If wantReply is true, it returns the response status |
|
// and payload. See also RFC4254, section 4. |
|
SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) |
|
|
|
// OpenChannel tries to open an channel. If the request is |
|
// rejected, it returns *OpenChannelError. On success it returns |
|
// the SSH Channel and a Go channel for incoming, out-of-band |
|
// requests. The Go channel must be serviced, or the |
|
// connection will hang. |
|
OpenChannel(name string, data []byte) (Channel, <-chan *Request, error) |
|
|
|
// Close closes the underlying network connection |
|
Close() error |
|
|
|
// Wait blocks until the connection has shut down, and returns the |
|
// error causing the shutdown. |
|
Wait() error |
|
|
|
// TODO(hanwen): consider exposing: |
|
// RequestKeyChange |
|
// Disconnect |
|
} |
|
|
|
// DiscardRequests consumes and rejects all requests from the |
|
// passed-in channel. |
|
func DiscardRequests(in <-chan *Request) { |
|
for req := range in { |
|
if req.WantReply { |
|
req.Reply(false, nil) |
|
} |
|
} |
|
} |
|
|
|
// A connection represents an incoming connection. |
|
type connection struct { |
|
transport *handshakeTransport |
|
sshConn |
|
|
|
// The connection protocol. |
|
*mux |
|
} |
|
|
|
func (c *connection) Close() error { |
|
return c.sshConn.conn.Close() |
|
} |
|
|
|
// sshconn provides net.Conn metadata, but disallows direct reads and |
|
// writes. |
|
type sshConn struct { |
|
conn net.Conn |
|
|
|
user string |
|
sessionID []byte |
|
clientVersion []byte |
|
serverVersion []byte |
|
} |
|
|
|
func dup(src []byte) []byte { |
|
dst := make([]byte, len(src)) |
|
copy(dst, src) |
|
return dst |
|
} |
|
|
|
func (c *sshConn) User() string { |
|
return c.user |
|
} |
|
|
|
func (c *sshConn) RemoteAddr() net.Addr { |
|
return c.conn.RemoteAddr() |
|
} |
|
|
|
func (c *sshConn) Close() error { |
|
return c.conn.Close() |
|
} |
|
|
|
func (c *sshConn) LocalAddr() net.Addr { |
|
return c.conn.LocalAddr() |
|
} |
|
|
|
func (c *sshConn) SessionID() []byte { |
|
return dup(c.sessionID) |
|
} |
|
|
|
func (c *sshConn) ClientVersion() []byte { |
|
return dup(c.clientVersion) |
|
} |
|
|
|
func (c *sshConn) ServerVersion() []byte { |
|
return dup(c.serverVersion) |
|
}
|
|
|