...

Source file src/golang.org/x/crypto/ssh/test/server_test.go

Documentation: golang.org/x/crypto/ssh/test

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package test
     6  
     7  import (
     8  	"net"
     9  
    10  	"golang.org/x/crypto/ssh"
    11  )
    12  
    13  type exitStatusMsg struct {
    14  	Status uint32
    15  }
    16  
    17  // goServer is a test Go SSH server that accepts public key and certificate
    18  // authentication and replies with a 0 exit status to any exec request without
    19  // running any commands.
    20  type goTestServer struct {
    21  	listener net.Listener
    22  	config   *ssh.ServerConfig
    23  	done     <-chan struct{}
    24  }
    25  
    26  func newTestServer(config *ssh.ServerConfig) (*goTestServer, error) {
    27  	server := &goTestServer{
    28  		config: config,
    29  	}
    30  	listener, err := net.Listen("tcp", "127.0.0.1:")
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	server.listener = listener
    35  	done := make(chan struct{}, 1)
    36  	server.done = done
    37  	go server.acceptConnections(done)
    38  
    39  	return server, nil
    40  }
    41  
    42  func (s *goTestServer) port() (string, error) {
    43  	_, port, err := net.SplitHostPort(s.listener.Addr().String())
    44  	return port, err
    45  }
    46  
    47  func (s *goTestServer) acceptConnections(done chan<- struct{}) {
    48  	defer close(done)
    49  
    50  	for {
    51  		c, err := s.listener.Accept()
    52  		if err != nil {
    53  			return
    54  		}
    55  		_, chans, reqs, err := ssh.NewServerConn(c, s.config)
    56  		if err != nil {
    57  			return
    58  		}
    59  		go ssh.DiscardRequests(reqs)
    60  		defer c.Close()
    61  
    62  		for newChannel := range chans {
    63  			if newChannel.ChannelType() != "session" {
    64  				newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
    65  				continue
    66  			}
    67  
    68  			channel, requests, err := newChannel.Accept()
    69  			if err != nil {
    70  				continue
    71  			}
    72  
    73  			go func(in <-chan *ssh.Request) {
    74  				for req := range in {
    75  					ok := false
    76  					switch req.Type {
    77  					case "exec":
    78  						ok = true
    79  						go func() {
    80  							channel.SendRequest("exit-status", false, ssh.Marshal(&exitStatusMsg{Status: 0}))
    81  							channel.Close()
    82  						}()
    83  					}
    84  					if req.WantReply {
    85  						req.Reply(ok, nil)
    86  					}
    87  				}
    88  			}(requests)
    89  		}
    90  	}
    91  }
    92  
    93  func (s *goTestServer) Close() error {
    94  	err := s.listener.Close()
    95  	// wait for the accept loop to exit
    96  	<-s.done
    97  	return err
    98  }
    99  

View as plain text