summaryrefslogtreecommitdiff
path: root/shell.go
diff options
context:
space:
mode:
authorrunoneall <runoneall@serv00.net>2025-09-11 11:19:12 +0200
committerrunoneall <runoneall@serv00.net>2025-09-11 11:19:12 +0200
commit59c5a6c4950d340d248431b84452d86329024d76 (patch)
tree71d5e243090a319f35c6b35046e81ddf7271dc35 /shell.go
parent1ac4476d0a226c319200720a6ff63a5471bdc104 (diff)
add ssh server
Diffstat (limited to 'shell.go')
-rw-r--r--shell.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/shell.go b/shell.go
new file mode 100644
index 0000000..3492b33
--- /dev/null
+++ b/shell.go
@@ -0,0 +1,70 @@
+package main
+
+import (
+ "fmt"
+ "net"
+ "os"
+ "os/exec"
+
+ "golang.org/x/crypto/ssh"
+)
+
+func shell(conn net.Conn, config *ssh.ServerConfig) {
+ sshConn, chans, reqs, err := ssh.NewServerConn(conn, config)
+ if err != nil {
+ fmt.Println("不能创建连接:", err)
+ return
+ }
+ defer sshConn.Close()
+
+ fmt.Println("New connection from", sshConn.RemoteAddr(), "with client version", sshConn.ClientVersion())
+
+ go ssh.DiscardRequests(reqs)
+
+ for newChannel := range chans {
+ if newChannel.ChannelType() != "session" {
+ newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
+ continue
+ }
+
+ channel, requests, err := newChannel.Accept()
+ if err != nil {
+ fmt.Println("Can not accept channel:", err)
+ continue
+ }
+ defer channel.Close()
+
+ shell := os.Getenv("SHELL")
+ if shell == "" {
+ shell = "cmd.exe"
+ }
+
+ command := exec.Command(shell)
+ command.Stdin = channel
+ command.Stdout = channel
+ command.Stderr = channel
+
+ if err := command.Start(); err != nil {
+ fmt.Println("Failed to start shell:", err)
+ return
+ }
+
+ go func() {
+ if err := command.Wait(); err != nil {
+ fmt.Println("Run shell failed:", err)
+ }
+ channel.Close()
+ }()
+
+ go func() {
+ for req := range requests {
+ switch req.Type {
+ case "shell":
+ req.Reply(true, nil)
+ default:
+ req.Reply(false, nil)
+ }
+ }
+ }()
+ }
+}