Example #1
0
//transfer a directory to remote host,with single tcp and tar.gz format
//Stdout will be ignore.
//Stderr will treat as an error from remote command
func CopyDirectory(client *ssh.Client, selfPath string, remotePath string) (err error) {
	session, err := client.NewSession()
	if err != nil {
		return fmt.Errorf("[CopyDirectory]Failed to create session: %s", err.Error())
	}
	defer session.Close()
	w, err := session.StdinPipe()
	if err != nil {
		return
	}
	defer w.Close()
	errBuf := &bytes.Buffer{}
	session.Stderr = errBuf
	escapedRemotePath := kmgCmd.BashEscape(remotePath)
	err = session.Start(fmt.Sprintf("mkdir -p %s;tar -xz -C %s", escapedRemotePath, escapedRemotePath))
	if err != nil {
		return fmt.Errorf("[CopyDirectory] Failed to Run: %s", err.Error())
	}
	err = kmgTar.PackageDirectoryTarGz(selfPath, w)
	if err != nil {
		return
	}
	err = w.Close()
	if err != nil {
		return
	}
	err = session.Wait()
	if err != nil {
		return fmt.Errorf("[CopyDirectory] session.Wait() err:%s", err.Error())
	}
	if errBuf.Len() != 0 {
		return fmt.Errorf("[CopyDirectory] remote: %s", string(errBuf.Bytes()))
	}
	return nil
}
Example #2
0
File: provi.go Project: rzh/utils
func (p *Jobs) runCmd(i int, cmd string, client *ssh.Client, outfile *os.File) {
	session, err := client.NewSession()
	if err != nil {
		log.Fatal("Failed to create SSH session to server [" + p.Servers[i] + "] with error: " + err.Error())
	}
	defer session.Close()

	session.Stdout = outfile
	session.Stderr = outfile

	// Set up terminal modes
	modes := ssh.TerminalModes{
		ssh.ECHO:          0,     // disable echoing
		ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
	}
	// Request pseudo terminal
	if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
		log.Fatalf("request for pseudo terminal failed: %s", err)
	}

	err = session.Start(cmd)
	if err != nil {
		log.Fatal("run command ["+cmd+"] on server ("+p.Servers[i]+") failed with -> ", err)
	}
	err = session.Wait()

	// TODO: make cmd not longer than 80
	if err == nil {
		log.Printf("[%15s] %-80s %s%s%s", p.Servers[i], cmd, CLR_G, "√", CLR_N)
	} else {
		log.Printf("[%15s] %-80s %s%s%s", p.Servers[i], cmd, CLR_R, "✗", CLR_N)
	}
}
Example #3
0
// New creates a new SFTP client on conn.
func NewClient(conn *ssh.Client) (*Client, error) {
	s, err := conn.NewSession()
	if err != nil {
		return nil, err
	}
	if err := s.RequestSubsystem("sftp"); err != nil {
		return nil, err
	}
	pw, err := s.StdinPipe()
	if err != nil {
		return nil, err
	}
	pr, err := s.StdoutPipe()
	if err != nil {
		return nil, err
	}
	sftp := &Client{
		w: pw,
		r: pr,
	}
	if err := sftp.sendInit(); err != nil {
		return nil, err
	}
	return sftp, sftp.recvVersion()
}
Example #4
0
func cmdExecRemote(sshc *ssh.Client, args ...string) {
	cmd := strings.Join(args, " ")
	log.Printf("Executing (remotely) %s", cmd)
	if DUMMY {
		return
	}
	sshs, err := sshc.NewSession()
	if err != nil {
		log.Fatalf("Could not create ssh session: %v", err)
	}
	defer sshs.Close()

	stdout, err := sshs.StdoutPipe()
	if err != nil {
		log.Fatalf("Could not get stdout of ssh session: %v", err)
	}
	stderr, err := sshs.StderrPipe()
	if err != nil {
		log.Fatalf("Could not get stderr of ssh session: %v", err)
	}

	err = sshs.Start(cmd)
	if err != nil {
		log.Fatalf("Could not execute command: %v", err)
	}

	go io.Copy(os.Stdout, stdout)
	go io.Copy(os.Stderr, stderr)
	err = sshs.Wait()
	if err != nil {
		log.Fatalf("Error executing (remote) command: %v", err)
	}
}
Example #5
0
func combined(c *ssh.Client, cmd string) ([]byte, error) {
	s, err := c.NewSession()
	if err != nil {
		return nil, err
	}
	defer s.Close()

	return s.CombinedOutput(cmd)
}
Example #6
0
//transfer a file to remote host,with single tcp and gz format
//Stdout will be ignore.
//Stderr will treat as an error from remote command
//TODO test
func CopyFile(client *ssh.Client, selfPath string, remotePath string) (err error) {
	session, err := client.NewSession()
	if err != nil {
		return fmt.Errorf("[CopyFile]Failed to create session: %s", err.Error())
	}
	defer session.Close()
	w, err := session.StdinPipe()
	if err != nil {
		return
	}
	defer w.Close()
	errReader, err := session.StderrPipe()
	if err != nil {
		return
	}
	escapedRemotePath := kmgCmd.BashEscape(remotePath)
	escapedRemoteDir := kmgCmd.BashEscape(path.Dir(remotePath))
	err = session.Start(fmt.Sprintf("mkdir -p %s;cat > %s", escapedRemoteDir, escapedRemotePath))
	if err != nil {
		return fmt.Errorf("[CopyFile] Failed to Start: %s", err.Error())
	}
	f, err := os.Open(selfPath)
	if err != nil {
		return
	}
	defer f.Close()
	//gzipW := gzip.NewWriter(w)
	//defer gzipW.Close()
	_, err = io.Copy(w, f)
	if err != nil {
		return fmt.Errorf("[CopyFile] io.Copy: %s", err)
	}
	//err = gzipW.Close()
	//if err!=nil{
	//	return
	//}
	err = w.Close()
	if err != nil {
		return
	}
	errBytes, err := ioutil.ReadAll(errReader)
	if err != nil {
		return
	}
	if len(errBytes) != 0 {
		return fmt.Errorf("[CopyFile] remote: %s", string(errBytes))
	}
	err = session.Wait()
	if err != nil {
		return fmt.Errorf("[CopyFile] session.Wait() err:%s", err.Error())
	}
	return nil
}
Example #7
0
func Hop(through *ssh.Client, toaddr string, c *ssh.ClientConfig) (*ssh.Client, error) {
	hopconn, err := through.Dial("tcp", toaddr)
	if err != nil {
		return nil, err
	}

	conn, chans, reqs, err := ssh.NewClientConn(hopconn, toaddr, c)
	if err != nil {
		return nil, err
	}

	return ssh.NewClient(conn, chans, reqs), nil
}
Example #8
0
func (v *vm) Run(command string, attempts attempt.Strategy, out io.Writer, stderr io.Writer) error {
	var sc *ssh.Client
	err := attempts.Run(func() (err error) {
		fmt.Fprintf(stderr, "Attempting to ssh to %s:22...\n", v.IP())
		sc, err = v.DialSSH()
		return
	})
	if err != nil {
		return err
	}
	defer sc.Close()
	sess, err := sc.NewSession()
	sess.Stdin = bytes.NewBufferString(command)
	sess.Stdout = out
	sess.Stderr = stderr
	if err := sess.Run("bash"); err != nil {
		return fmt.Errorf("failed to run command on %s: %s", v.IP(), err)
	}
	return nil
}
Example #9
0
func NewTunnelledSSHClient(user, tunaddr, tgtaddr string, checker *HostKeyChecker, agentForwarding bool, timeout time.Duration) (*SSHForwardingClient, error) {
	clientConfig, err := sshClientConfig(user, checker)
	if err != nil {
		return nil, err
	}

	tunaddr = maybeAddDefaultPort(tunaddr)
	tgtaddr = maybeAddDefaultPort(tgtaddr)

	var tunnelClient *gossh.Client
	dialFunc := func(echan chan error) {
		var err error
		tunnelClient, err = gossh.Dial("tcp", tunaddr, clientConfig)
		echan <- err
	}
	err = timeoutSSHDial(dialFunc, timeout)
	if err != nil {
		return nil, err
	}

	var targetConn net.Conn
	dialFunc = func(echan chan error) {
		tgtTCPAddr, err := net.ResolveTCPAddr("tcp", tgtaddr)
		if err != nil {
			echan <- err
			return
		}
		targetConn, err = tunnelClient.DialTCP("tcp", nil, tgtTCPAddr)
		echan <- err
	}
	err = timeoutSSHDial(dialFunc, timeout)
	if err != nil {
		return nil, err
	}

	c, chans, reqs, err := gossh.NewClientConn(targetConn, tgtaddr, clientConfig)
	if err != nil {
		return nil, err
	}
	return newSSHForwardingClient(gossh.NewClient(c, chans, reqs), agentForwarding)
}
Example #10
0
// ForwardToAgent routes authentication requests to the given keyring.
func ForwardToAgent(client *ssh.Client, keyring Agent) error {
	channels := client.HandleChannelOpen(channelType)
	if channels == nil {
		return errors.New("agent: already have handler for " + channelType)
	}

	go func() {
		for ch := range channels {
			channel, reqs, err := ch.Accept()
			if err != nil {
				continue
			}
			go ssh.DiscardRequests(reqs)
			go func() {
				ServeAgent(keyring, channel)
				channel.Close()
			}()
		}
	}()
	return nil
}
Example #11
0
func copyFile(c *ssh.Client, r io.Reader, path string) error {
	s, err := c.NewSession()
	if err != nil {
		return err
	}
	defer s.Close()

	w, err := s.StdinPipe()
	if err != nil {
		return err
	}

	s.Start("tee " + path)

	_, err = io.Copy(w, r)
	if err != nil {
		return err
	}
	w.Close()

	return s.Wait()
}
Example #12
0
//run sudo a command in remote and ask password in current console,
//Stdout will goto current console too.
//Stderr will treat as an error from remote command
func SudoCommand(client *ssh.Client, cmd string) (err error) {
	session, err := client.NewSession()
	if err != nil {
		return fmt.Errorf("[SudoCommand] Failed to create session: %s", err.Error())
	}
	defer session.Close()
	w, err := session.StdinPipe()
	if err != nil {
		return
	}
	session.Stdout = os.Stdout
	errBuf := &bytes.Buffer{}
	session.Stderr = errBuf
	// Set up terminal modes
	modes := ssh.TerminalModes{
		ssh.ECHO:          0,     // disable echoing
		ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
	}
	// Request pseudo terminal
	if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
		return fmt.Errorf("[SudoCommand] request for pseudo terminal failed: %s", err)
	}
	err = session.Start(cmd)
	if err != nil {
		return fmt.Errorf("[SudoCommand] Failed to Start: %s", err.Error())
	}
	pass := gopass.GetPasswd()
	w.Write(append(pass, byte('\n')))
	err = session.Wait()
	if err != nil {
		return fmt.Errorf("[SudoCommand] session.Wait err: %s", err.Error())
	}
	if errBuf.Len() != 0 {
		return fmt.Errorf("[SudoCommand] remote err: %s", err.Error())
	}
	return nil
}
Example #13
0
// ForwardToRemote routes authentication requests to the ssh-agent
// process serving on the given unix socket.
func ForwardToRemote(client *ssh.Client, addr string) error {
	channels := client.HandleChannelOpen(channelType)
	if channels == nil {
		return errors.New("agent: already have handler for " + channelType)
	}
	conn, err := net.Dial("unix", addr)
	if err != nil {
		return err
	}
	conn.Close()

	go func() {
		for ch := range channels {
			channel, reqs, err := ch.Accept()
			if err != nil {
				continue
			}
			go ssh.DiscardRequests(reqs)
			go forwardUnixSocket(channel, addr)
		}
	}()
	return nil
}
Example #14
0
func createPipeNet(client *ssh.Client, cmd string) (pn *PipeNet, err error) {
	session, err := client.NewSession()
	if err != nil {
		return
	}

	pn = &PipeNet{
		wa:   session,
		c:    client,
		name: "ssh",
	}

	pn.w, err = session.StdinPipe()
	if err != nil {
		return
	}
	pn.r, err = session.StdoutPipe()
	if err != nil {
		return
	}

	err = session.Start(cmd)
	return
}
Example #15
0
// Start port forwarding for the given SSH client:
func loop(sshClient *ssh.Client, localToRemote, remoteToLocal []PortForward) {
	done := make(chan bool, 1)

	// Intercept termination signals:
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGQUIT)

	go func() {
		sig := <-sigc
		log.Printf("Caught signal: %s\n", sig)
		done <- true
	}()

	// Forward all the local-to-remote ports:
	for _, fwd := range localToRemote {
		// Set up forwarding addresses:
		localAddr := fwd.LocalAddr
		remoteAddr := fwd.RemoteAddr

		log.Printf("Forwarding connections from local %s to remote %s\n", localAddr, remoteAddr)

		go func() {
			localListener, err := net.Listen("tcp", localAddr)
			if err != nil {
				log.Printf("unable to listen: %s\n", err)
				done <- true
				return
			}
			defer localListener.Close()
			log.Printf("Listening...\n")

			// Begin accepting new connections from the SSH tunnel:
			for {
				// Accept a new local connection:
				local, err := localListener.Accept()
				if err != nil {
					log.Printf("Accept: %s\n", err)
					break
				}
				logContext := local.RemoteAddr().String()
				log.Printf("%s: Accepted local connection.\n", logContext)

				// Connect to the remote RDP service:
				remote, err := sshClient.Dial("tcp", remoteAddr)
				if err != nil {
					log.Printf("%s: Unable to connect via SSH: %s\n", logContext, err)
					local.Close()
					continue
				}
				defer remote.Close()

				// Start forwarding data back 'n forth:
				go forward(local, remote, logContext)
			}
		}()
	}

	// Forward all remote-to-local ports:
	for _, fwd := range remoteToLocal {
		// Set up forwarding addresses:
		localAddr := fwd.LocalAddr
		remoteAddr := fwd.RemoteAddr

		// Resolve local address:
		var err error
		localTCPAddr, err := net.ResolveTCPAddr("tcp", localAddr)
		if err != nil {
			log.Printf("unable to resolve local address: %s\n", err)
			done <- true
			return
		}

		log.Printf("Forwarding connections from remote %s to local %s\n", remoteAddr, localAddr)

		go func() {
			// Request the remote side to open a port for forwarding:
			l, err := sshClient.Listen("tcp", remoteAddr)
			if err != nil {
				log.Printf("unable to register tcp forward: %s\n", err)
				return
			}
			log.Printf("Listening...\n")
			defer l.Close()

			// Begin accepting new connections from the SSH tunnel:
			for {
				// Accept a new remote connection from SSH:
				remote, err := l.Accept()
				if err != nil {
					log.Printf("Accept: %s\n", err)
					done <- true
					break
				}
				logContext := remote.RemoteAddr().String()
				log.Printf("%s: Accepted new SSH tunnel connection.\n", logContext)

				// Connect to the local RDP service:
				local, err := net.DialTCP("tcp", nil, localTCPAddr)
				if err != nil {
					log.Printf("%s: Could not open local connection to: %s\n", logContext, localTCPAddr)
					remote.Close()
					continue
				}

				// Start forwarding data back 'n forth:
				go forward(local, remote, logContext)
			}
		}()
	}

	<-done
}