| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 | package mainimport (	"flag"	"fmt"	"net"	"os"	"strconv"	"strings"	"syscall"	"time")const (	connHost = "0.0.0.0"	connPort = "8080"	connType = "tcp")func main() {	var port int	flag.IntVar(&port, "p", 0, "Port number to listen on")	flag.Parse()	if port == 0 && flag.NArg() != 1 {		fmt.Println("I need a Port and a commandline to execute.")		flag.PrintDefaults()		os.Exit(2)	}	fmt.Println("Starting " + connType + " server on " + connHost + ":" + strconv.Itoa(port))	l, err := net.Listen("tcp", "0.0.0.0:"+strconv.Itoa(port))	if err != nil {		fmt.Println("Error listening:", err.Error())		os.Exit(1)	}	defer l.Close()	for {		c, err := l.Accept()		if err != nil {			fmt.Println("Error connecting:", err.Error())			return		}		fmt.Println("Client connected.")		fmt.Println("Client " + c.RemoteAddr().String() + " connected.")		// fork goes here		go handleConnection(c, flag.Arg(0))		c = nil	}}func drain(conn net.Conn) {	conn.SetReadDeadline(time.Now().Add(time.Second * 2))	recvData := make([]byte, 32)	n, err := conn.Read(recvData)	if n > 0 {		// do something with recvData[:n]		fmt.Printf(" [%d]\n", n)	}	if err != nil {		fmt.Printf("drain Error: %#v\n", err)	}	conn.SetReadDeadline(time.Time{})}func waitForIt(conn net.Conn, pid int) {	process, _ := os.FindProcess(pid)	state, _ := process.Wait()	fmt.Printf("%d State: %#v\n", pid, state)	conn.Write([]byte("\r\nThanks for calling!\r\n"))	conn.Close()	fmt.Println("Connection closed.")}func handleConnection(conn net.Conn, cmd string) {	// Something here confuses the crap out of Windows Telnet Client!	conn.Write([]byte("\xff\xfb\x01\xff\xfb\x03\xff\xfd\x10"))	drain(conn)	fmt.Printf("%#v\n", conn)	tcp, _ := conn.(*net.TCPConn)	fmt.Printf("%#v\n", tcp)	// https://github.com/golang/go/issues/10350	raw, err := tcp.SyscallConn()	fmt.Printf("%#v, err: %#v\n", raw, err)	var socket_fd uintptr	raw.Control(func(fd uintptr) {		socket_fd = fd	})	fmt.Printf("Socket: %#v\n", socket_fd)	proc, _ := syscall.GetCurrentProcess()	var dup_socket_fd syscall.Handle	err = syscall.DuplicateHandle(proc, syscall.Handle(socket_fd),		proc, &dup_socket_fd, syscall.DUPLICATE_SAME_ACCESS, true, 0)	if err != nil {		fmt.Printf("ERR DuplicateHandle: %#v\n", err)	}	fmt.Printf("Dup: %#v\n", dup_socket_fd)	// windows:  tcp.File() failes.  net.OpError	/*		file, err := tcp.File()		fd := file.Fd()		fmt.Printf("FD %#v, %#v\n", fd, err)	*/	/*		tcp, _ := conn.(*net.TCPConn)		file, _ := tcp.File()		fd := file.Fd()	*/	// what we actually put into the file	filefd := int64(dup_socket_fd)	// fdstr := strconv.Itoa(int(filefd))	fp, _ := os.Create("door32.sys")	fmt.Fprintf(fp, "2\n%d\n38400\nFake Door32\n1\nBugz Laundry\nBugz\n100\n120\n1\n1\n", filefd)	fp.Close()	parts := strings.Split(cmd, " ")	// parts = append(parts, fdstr)	// id, _ := syscall.ForkExec(parts[0], parts[1:], nil)	fmt.Printf("Running: [%s] with %#v\n", parts[0], parts[1:])	// https://stackoverflow.com/questions/35336131/createprocess-with-golang	var si syscall.StartupInfo	var pi syscall.ProcessInformation	argv := syscall.StringToUTF16Ptr(cmd)	err = syscall.CreateProcess(nil, argv, nil, nil, true, 0, nil, nil, &si, &pi)	fmt.Printf("Return: %#v\n", err)	raw = nil	if err == nil {		event, e := syscall.WaitForSingleObject(pi.Process, syscall.INFINITE)		fmt.Printf("Event %#v, err: %#v\n", event, e)	}	/*		exec_cmd := exec.Command(parts[0], parts[1:]...)		fmt.Printf("exec_cmd: %#v\n", exec_cmd)		err = exec_cmd.Run()		if err != nil {			fmt.Println("Error: ", err)		}		fmt.Println("Command completed.")		// UH, WHAT?  I didn't see that it started, and it certainly didn't keep running.  :(	*/	// id := 13	/*		id, _ := syscall.ForkExec(parts[0], parts,			&syscall.ProcAttr{				Env: os.Environ(),				Sys: &syscall.SysProcAttr{					Setsid: true,				},				Files: []uintptr{0, 1, 2, fd}, // print message to the same pty			})	*/	// go waitForIt(conn, id)	// id, _, _ := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)	/*		if id == 0 {			// child process			exec.Command(parts[0], parts[1:]...)			os.Exit(2)		}	*/	// fmt.Printf("Child started: %d\n", id)	// return	conn.Write([]byte("Welcome back!\r\nSeeya!\r\n"))	// I can't seem to get this to close the connection.  :(	conn.Close()	syscall.CloseHandle(syscall.Handle(socket_fd))	tcp.SetLinger(0)	tcp.Close()	/*		for {			buffer, err := bufio.NewReader(conn).ReadBytes('\r') // HMM.  \r ?			if err != nil {				fmt.Println("Client left.")				conn.Close()				return			}			// What am I seeing here?			log.Println("Client message:", string(buffer[:len(buffer)-1]))			conn.Write(buffer)			conn.Write([]byte("\n"))		}	*/}
 |