forked from jaksi/sshesame
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
111 lines (104 loc) · 3.32 KB
/
main.go
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
package main
import (
"crypto/sha256"
"flag"
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/bechampion/sshesame/request"
//"./request"
"github.com/bechampion/sshesame/channel"
//"./channel"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ssh"
"io/ioutil"
"net"
"strconv"
)
func main() {
hostKey := flag.String("host_key", "", "a file containing a private key to use")
listenAddress := flag.String("listen_address", "localhost", "the local address to listen on")
port := flag.Uint("port", 2022, "the port number to listen on")
jsonLogging := flag.Bool("json_logging", false, "enable logging in JSON")
serverVersion := flag.String("server_version", "SSH-2.0-sshesame", "The version identification of the server (RFC 4253 section 4.2 requires that this string start with \"SSH-2.0-\")")
flag.Parse()
if *jsonLogging {
log.SetFormatter(&log.JSONFormatter{})
}
var key ssh.Signer
sshmap := make(map[string]string)
var err error
if *hostKey != "" {
keyBytes, err := ioutil.ReadFile(*hostKey)
if err != nil {
log.Fatal("Failed to read host key:", err.Error())
}
key, err = ssh.ParsePrivateKey(keyBytes)
if err != nil {
log.Fatal("Failed to parse host key:", err.Error())
}
} else {
_, keyBytes, err := ed25519.GenerateKey(nil)
if err != nil {
log.Fatal("Failed to generate temporary private key:", err.Error())
}
key, err = ssh.NewSignerFromSigner(keyBytes)
if err != nil {
log.Fatal("Failed to parse generated private key:", err.Error())
}
log.WithFields(log.Fields{
"sha256_fingerprint": sha256.Sum256(key.PublicKey().Marshal()),
}).Warning("Using a temporary host key, consider creating a permanent one and passing it to -host_key")
}
serverConfig := &ssh.ServerConfig{
ServerVersion: *serverVersion,
PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
sshmap[conn.RemoteAddr().String()] = conn.User()
log.WithFields(log.Fields{
"client": conn.RemoteAddr(),
"user": conn.User(),
"password": string(password),
"version": string(conn.ClientVersion()),
}).Info("Password authentication accepted")
return nil, nil
},
}
serverConfig.AddHostKey(key)
listener, err := net.Listen("tcp", net.JoinHostPort(*listenAddress, strconv.Itoa(int(*port))))
fmt.Println(sshmap)
if err != nil {
log.Fatal("Failed to listen:", err.Error())
}
log.WithFields(log.Fields{
"listen_address": listener.Addr(),
}).Info("Listening")
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
log.Warning("Failed to accept connection:", err.Error())
continue
}
log.WithFields(log.Fields{
"client": conn.RemoteAddr(),
}).Info("Client connected")
go handleConn(serverConfig, conn ,sshmap)
}
}
func handleConn(serverConfig *ssh.ServerConfig, conn net.Conn , sshmap map[string]string ) {
defer conn.Close()
_, channels, requests, err := ssh.NewServerConn(conn, serverConfig)
if err != nil {
log.Warning("Failed to establish SSH connection:", err.Error())
return
}
log.WithFields(log.Fields{
"client": conn.RemoteAddr(),
}).Info("SSH connection established")
go request.Handle(conn.RemoteAddr(), "global", requests)
for newChannel := range channels {
go channel.Handle(conn.RemoteAddr(), newChannel , sshmap)
}
log.WithFields(log.Fields{
"client": conn.RemoteAddr(),
}).Info("Client disconnected")
}