mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 18:02:25 -05:00 
			
		
		
		
	
		
			
	
	
		
			144 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			144 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | // 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. | ||
|  | 	User() string | ||
|  | 
 | ||
|  | 	// SessionID returns the session 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) | ||
|  | } |