1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
// +build windows
package e2e
import (
"bufio"
"context"
"fmt"
"io"
"net"
"net/http"
"strings"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
)
const fakeHostKey = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAkXGLzDNnY5+xdAgnt8FlBIZtoFOZEdTUkNxkdSM05PgAAAJg9WMAvPVjA
LwAAAAtzc2gtZWQyNTUxOQAAACAkXGLzDNnY5+xdAgnt8FlBIZtoFOZEdTUkNxkdSM05Pg
AAAEAFvLprhpMPdNsxSwo1Cs5VP5joCh9XLicRqKE0JJzdxCRcYvMM2djn7F0CCe3wWUEh
m2gU5kR1NSQ3GR1IzTk+AAAAEmphc29uQFRyaXBlbC5sb2NhbAECAw==
-----END OPENSSH PRIVATE KEY-----`
type streamLocalDirect struct {
SocketPath string
Reserved0 string
Reserved1 uint32
}
var cancel context.CancelFunc
func startMockServer() {
sshConfig := &ssh.ServerConfig{
NoClientAuth: true,
}
key, err := ssh.ParsePrivateKey([]byte(fakeHostKey))
if err != nil {
logrus.Errorf("Could not parse key: %s", err)
}
sshConfig.AddHostKey(key)
listener, err := net.Listen("tcp", ":2134")
if err != nil {
panic(err)
}
var ctx context.Context
ctx, cancel = context.WithCancel(context.Background())
go func() {
loop:
for {
select {
case <-ctx.Done():
break loop
default:
// proceed
}
conn, err := listener.Accept()
if err != nil {
panic(err)
}
// From a standard TCP connection to an encrypted SSH connection
_, chans, reqs, err := ssh.NewServerConn(conn, sshConfig)
if err != nil {
panic(err)
}
go handleRequests(reqs)
// Accept all channels
go handleChannels(chans)
}
listener.Close()
}()
}
func stopMockServer() {
cancel()
}
func handleRequests(reqs <-chan *ssh.Request) {
for _ = range reqs {
}
}
func handleChannels(chans <-chan ssh.NewChannel) {
directMsg := streamLocalDirect{}
for newChannel := range chans {
if t := newChannel.ChannelType(); t != "direct-streamlocal@openssh.com" {
newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
continue
}
if err := ssh.Unmarshal(newChannel.ExtraData(), &directMsg); err != nil {
logrus.Errorf("could not direct-streamlocal data: %s", err)
newChannel.Reject(ssh.Prohibited, "invalid format")
return
}
channel, _, err := newChannel.Accept()
if err != nil {
logrus.Errorf("could not accept channel: %s", err)
continue
}
req, err := http.ReadRequest(bufio.NewReader(channel))
if err != nil {
logrus.Errorf("could not process http request: %s", err)
}
resp := http.Response{}
resp.Close = true
switch req.RequestURI {
case "/ping":
resp.StatusCode = 200
resp.ContentLength = 4
resp.Body = io.NopCloser(strings.NewReader("pong"))
default:
resp.StatusCode = 404
resp.ContentLength = 0
}
resp.Write(channel)
channel.CloseWrite()
}
}
|