예제 #1
1
// sendSshKeepAlive is a helper which sends a [email protected] request
// on the specified SSH connections and returns true of the request succeeds
// within a specified timeout.
func sendSshKeepAlive(
	sshClient *ssh.Client, conn net.Conn, timeout time.Duration) error {

	errChannel := make(chan error, 2)
	if timeout > 0 {
		time.AfterFunc(timeout, func() {
			errChannel <- TimeoutError{}
		})
	}

	go func() {
		// Random padding to frustrate fingerprinting
		_, _, err := sshClient.SendRequest(
			"*****@*****.**", true,
			MakeSecureRandomPadding(0, TUNNEL_SSH_KEEP_ALIVE_PAYLOAD_MAX_BYTES))
		errChannel <- err
	}()

	err := <-errChannel
	if err != nil {
		sshClient.Close()
		conn.Close()
	}

	return ContextError(err)
}
예제 #2
0
func (n *SSHNode) getClientAndSession() (*ssh.Client, *ssh.Session, error) {
	var client *ssh.Client
	var s *ssh.Session
	var err error

	// Retry few times if ssh connection fails
	for i := 0; i < MaxSSHRetries; i++ {
		client, err = n.dial()
		if err != nil {
			time.Sleep(SSHRetryDelay)
			continue
		}

		s, err = client.NewSession()
		if err != nil {
			client.Close()
			time.Sleep(SSHRetryDelay)
			continue
		}

		return client, s, nil
	}

	return nil, nil, err
}
예제 #3
0
func NewClient(conn *ssh.Client, readLimitBytesPerSecond, writeLimitBytesPerSecond int64, opts ...func(*sftp.Client) error) (*sftp.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
	}

	if readLimitBytesPerSecond > 0 {
		pr = flowrate.NewReader(pr, readLimitBytesPerSecond)
	}
	if writeLimitBytesPerSecond > 0 {
		pw = flowrate.NewWriter(pw, writeLimitBytesPerSecond)
	}
	return sftp.NewClientPipe(pr, pw, opts...)
}
예제 #4
0
func CopyLocalFileToRemote(client *ssh.Client, localFilePath string, filename string) error {
	// Each ClientConn can support multiple interactive sessions,
	// represented by a Session.
	session, err := client.NewSession()
	if err != nil {
		log.Fatal("Failed to create session: " + err.Error())
	}
	defer session.Close()

	writer, err := session.StdinPipe()
	if err != nil {
		return err
	}
	defer writer.Close()

	go func() {
		fileContents, _ := ioutil.ReadFile(localFilePath + "/" + filename)
		content := string(fileContents)
		fmt.Fprintln(writer, "C0644", len(content), filename)
		fmt.Fprint(writer, content)
		fmt.Fprintln(writer, "\x00") // transfer end with \x00\
	}()

	session.Run("/usr/bin/scp -t ./")
	return nil
}
예제 #5
0
func handleLocalSshConn(lnConn net.Conn) {
	defer func() {
		if Config.Ssh_Reverse_Proxy.Exit_On_Panic {
			return
		}
		if r := recover(); r != nil {
			Log.Error("Recovered from panic in connection from "+
				lnConn.RemoteAddr().String()+":", r)
		}
	}()

	Log.Info("Received connection from", lnConn.RemoteAddr())

	var sClient *ssh.Client
	psConfig := getProxyServerSshConfig(&sClient)
	psConn, psChans, psReqs, err := ssh.NewServerConn(lnConn, psConfig)
	if err != nil {
		Log.Info("Could not establish connection with " + lnConn.RemoteAddr().String() + ": " + err.Error())
		return
	}
	defer psConn.Close()
	defer sClient.Close()

	go ssh.DiscardRequests(psReqs)

	for newChannel := range psChans {
		handleChannel(newChannel, sClient)
	}

	Log.Info("Lost connection with", lnConn.RemoteAddr())
}
예제 #6
0
파일: client.go 프로젝트: newxan/gopistrano
func ExecuteCmd(client *ssh.Client, command string, stdout *string, stderr *string) error {
	session, err := client.NewSession()
	if err != nil {
		panic("Failed to create session: " + err.Error())
	}
	defer session.Close()
	//session.Setenv("PATH", "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin") //apparently needs serverside support
	// Once a Session is created, you can execute a single command on
	// the remote side using the Run method.
	var b bytes.Buffer
	var a bytes.Buffer
	session.Stdout = &b
	session.Stderr = &a
	log.Printf("CMD: %s\n", command)
	if err := session.Run(command); err != nil {
		return err
	}

	if stdout != nil {
		*stdout = b.String()
	}
	if stderr != nil {
		*stderr = a.String()
	}

	return err
}
예제 #7
0
파일: tunnel.go 프로젝트: kristoiv/nfssh
func tunnelConnectionToPortUsingClient(localConn net.Conn, rport int, client *ssh.Client) {
	addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:"+strconv.Itoa(rport))
	if err != nil {
		panic(err)
	}

	remoteConn, err := client.DialTCP("tcp", nil, addr)
	if err != nil {
		panic(err)
	}

	wg := sync.WaitGroup{}
	wg.Add(2)

	copyConn := func(writer, reader net.Conn) {
		defer wg.Done()
		CopyAndMeasureThroughput(writer, reader)
	}

	go copyConn(localConn, remoteConn)
	go copyConn(remoteConn, localConn)
	go func() {
		wg.Wait()
		localConn.Close()
		remoteConn.Close()
	}()
}
예제 #8
0
파일: sshnode.go 프로젝트: contiv/remotessh
func (n *SSHNode) getClientAndSession() (*ssh.Client, *ssh.Session, error) {
	var client *ssh.Client
	var s *ssh.Session
	var err error

	// Retry few times if ssh connection fails
	for i := 0; i < MaxSSHRetries; i++ {
		client, err = n.dial()
		if err != nil {
			time.Sleep(SSHRetryDelay)
			continue
		}

		s, err = client.NewSession()
		if err != nil {
			client.Close()
			time.Sleep(SSHRetryDelay)
			continue
		}
		modes := ssh.TerminalModes{
			ssh.ECHO:          0,
			ssh.TTY_OP_ISPEED: 14400,
			ssh.TTY_OP_OSPEED: 14400,
		}
		// Request pseudo terminal
		if err := s.RequestPty("xterm", 40, 80, modes); err != nil {
			return nil, nil, fmt.Errorf("failed to get pseudo-terminal: %v", err)
		}

		return client, s, nil
	}

	return nil, nil, err
}
예제 #9
0
func CopyFile(conn *ssh.Client, FileName, DirectoryPath string) bool {
	defer conn.Close()
	if !strings.HasSuffix(DirectoryPath, "/") {
		DirectoryPath = DirectoryPath + "/"
	}
	con, err := sftp.NewClient(conn, sftp.MaxPacket(5e9))
	if err != nil {
		color.Red("%s传输文件新建会话错误: %s\n", conn.RemoteAddr(), err)
		return false
	}
	sFile, _ := os.Open(FileName)
	defer sFile.Close()
	dFile := DirectoryPath + FileName
	fmt.Printf("%s 目标路径:%s\n", conn.RemoteAddr(), dFile)
	File, err := con.OpenFile(dFile, os.O_CREATE|os.O_TRUNC|os.O_RDWR)
	if err != nil {
		color.Red("%s 创建文件%s错误: %s \n", conn.RemoteAddr(), dFile, err)
		return false
	}
	defer File.Close()
	for {
		buf := make([]byte, 1024)
		n, err := sFile.Read(buf)
		if err != nil {
			if err.Error() == "EOF" {
				break
			}
			return false
		}
		File.Write(buf[:n])
	}
	Result <- fmt.Sprintf("上传%s到%s成功.\n", FileName, conn.RemoteAddr())
	return true
}
예제 #10
0
func tailFilesOnClient(client *ssh.Client, files []string, sudo bool, linec chan<- string, errc chan<- error) {
	var sessions []*ssh.Session
	closeSessions := func() {
		for _, session := range sessions {
			_ = session.Signal(ssh.SIGKILL)
			_ = session.Close()
		}
	}

	var wg sync.WaitGroup
	for _, file := range files {
		session, err := client.NewSession()
		if err != nil {
			closeSessions()
			errc <- fmt.Errorf("can't open session: %v", err)
			return
		}
		sessions = append(sessions, session)

		wg.Add(1)
		go func(file string) {
			defer wg.Done()
			err := tailFile(session, file, sudo, linec)
			if err != nil {
				errc <- err
			}
		}(file)

	}

	wg.Wait()
}
예제 #11
0
파일: shell.go 프로젝트: rosenhouse/proctor
func scpAndRun(client ssh.Client) {
	scpSession, err := client.NewSession()
	if err != nil {
		panic("Failed to create SCP session: " + err.Error())
	}
	defer scpSession.Close()

	scriptContents := `#!/bin/bash

echo "this script is located at $dirname $0"
`
	scriptReader := strings.NewReader(scriptContents)
	scpError := copy(int64(len(scriptContents)), os.FileMode(0777), "test-script", scriptReader, "/tmp/scripts/", scpSession)
	if scpError != nil {
		panic(scpError)
	}

	execSession, err := client.NewSession()
	if err != nil {
		panic("Failed to create session: " + err.Error())
	}
	defer execSession.Close()

	var stdoutBytes bytes.Buffer
	execSession.Stdout = &stdoutBytes
	if err := execSession.Run("/tmp/scripts/test-script"); err != nil {
		panic("Failed to run: " + err.Error())
	}
}
예제 #12
0
func (p *Project) installOnRemote(step int, conn *ssh.Client) {

	// Git and some other programs can send us an unsuccessful exit (< 0)
	// even if the command was successfully executed on the remote shell.
	// On these cases, we want to ignore those errors and move onto the next step.
	ignoredError := "Reason was:  ()"

	// Creates a session over the ssh connection to execute the commands
	session, err := conn.NewSession()
	if err != nil {
		log.Fatal("Failed to build session: ", err)
	}

	defer session.Close()

	var stdoutBuf bytes.Buffer
	session.Stdout = &stdoutBuf

	fmt.Println(p.typ.program.setup[step])

	err = session.Run(p.typ.program.setup[step])

	if err != nil && !strings.Contains(err.Error(), ignoredError) {
		log.Printf("Command '%s' failed on execution", p.typ.program.setup[step])
		log.Fatal("Error on command execution: ", err.Error())
	}
}
예제 #13
0
//Execute ssh commands until "exit" is entered
func runCommands(client *ssh.Client) {
	var cmd string
	for strings.ToLower(cmd) != "exit" {
		//Creates a new session.  Only one command per session
		session, err := client.NewSession()
		if err != nil {
			panic("Failed to create session: " + err.Error())
		}

		defer session.Close()

		fmt.Scanf("%s", &cmd)

		var b bytes.Buffer
		session.Stdout = &b
		err1 := session.Run(cmd)
		if err1 != nil {
			fmt.Print("You used an invalid command.")
			err1 = nil
		}
		fmt.Println(b.String())
	}
	//clear the terminal and display conn closed
	clear := exec.Command("clear")
	clear.Stdout = os.Stdout
	clear.Run()
	fmt.Println("\n\nConnection Closed")
}
예제 #14
0
func sshExec(client *ssh.Client, cmd string) (string, string, int, error) {
	framework.Logf("Executing '%s' on %v", cmd, client.RemoteAddr())
	session, err := client.NewSession()
	if err != nil {
		return "", "", 0, fmt.Errorf("error creating session to host %s: '%v'", client.RemoteAddr(), err)
	}
	defer session.Close()

	// Run the command.
	code := 0
	var bout, berr bytes.Buffer

	session.Stdout, session.Stderr = &bout, &berr
	err = session.Run(cmd)
	if err != nil {
		// Check whether the command failed to run or didn't complete.
		if exiterr, ok := err.(*ssh.ExitError); ok {
			// If we got an ExitError and the exit code is nonzero, we'll
			// consider the SSH itself successful (just that the command run
			// errored on the host).
			if code = exiterr.ExitStatus(); code != 0 {
				err = nil
			}
		} else {
			// Some other kind of error happened (e.g. an IOError); consider the
			// SSH unsuccessful.
			err = fmt.Errorf("failed running `%s` on %s: '%v'", cmd, client.RemoteAddr(), err)
		}
	}
	return bout.String(), berr.String(), code, err
}
예제 #15
0
파일: http.go 프로젝트: cmikk/sshttp
func connectProxy(sshc *ssh.Client, h http.Handler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "CONNECT" {
			h.ServeHTTP(w, r)
			return
		}
		host := r.URL.Host
		if strings.Index(host, ":") < 0 {
			host += ":80"
		}
		sconn, err := sshc.Dial("tcp", host)
		if err != nil {
			w.Header().Set("Content-Type", "text/plain")
			w.WriteHeader(http.StatusBadGateway)
			w.Write([]byte(err.Error()))
			return
		}

		w.WriteHeader(http.StatusOK)
		cconn, _, err := w.(http.Hijacker).Hijack()
		if err != nil {
			cconn.Close()
			sconn.Close()
			log.Print("CONNECT hijack error: ", err)
			return
		}
		go proxyconn(cconn, sconn)
		go proxyconn(sconn, cconn)
	}
}
예제 #16
0
func newSSHListener(sshClient *ssh.Client, exposedBind string, exposedPort int) (net.Listener, error) {
	sshListener, err := sshClient.Listen("tcp", joinHostPort(exposedBind, exposedPort))
	if err != nil {
		return nil, err
	}

	return sshListener, nil
}
예제 #17
0
파일: sshutil.go 프로젝트: ymomoi/vuls
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result execResult) {
	result.Servername = c.ServerName
	result.Host = c.Host
	result.Port = c.Port

	var client *ssh.Client
	var err error
	if client, err = sshConnect(c); err != nil {
		result.Error = err
		result.ExitStatus = 999
		return
	}
	defer client.Close()

	var session *ssh.Session
	if session, err = client.NewSession(); err != nil {
		result.Error = fmt.Errorf(
			"Failed to create a new session. servername: %s, err: %s",
			c.ServerName, err)
		result.ExitStatus = 999
		return
	}
	defer session.Close()

	// http://blog.ralch.com/tutorial/golang-ssh-connection/
	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
	}
	if err = session.RequestPty("xterm", 400, 256, modes); err != nil {
		result.Error = fmt.Errorf(
			"Failed to request for pseudo terminal. servername: %s, err: %s",
			c.ServerName, err)
		result.ExitStatus = 999
		return
	}

	var stdoutBuf, stderrBuf bytes.Buffer
	session.Stdout = &stdoutBuf
	session.Stderr = &stderrBuf

	cmd = decolateCmd(c, cmd, sudo)
	if err := session.Run(cmd); err != nil {
		if exitErr, ok := err.(*ssh.ExitError); ok {
			result.ExitStatus = exitErr.ExitStatus()
		} else {
			result.ExitStatus = 999
		}
	} else {
		result.ExitStatus = 0
	}

	result.Stdout = stdoutBuf.String()
	result.Stderr = stderrBuf.String()
	result.Cmd = strings.Replace(cmd, "\n", "", -1)
	return
}
예제 #18
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)
}
예제 #19
0
func RunCommand(c *ssh.Client, cmd string) error {
	s, err := c.NewSession()
	defer s.Close()
	if err != nil {
		return errors.Wrap(err, "Error creating new session for ssh client")
	}

	return s.Run(cmd)
}
예제 #20
0
func RunCommand(c *ssh.Client, cmd string) error {
	s, err := c.NewSession()
	defer s.Close()
	if err != nil {
		return err
	}

	return s.Run(cmd)
}
예제 #21
0
func createSession(client *ssh.Client) (*ssh.Session, error) {
	fmt.Println("Creating new session")
	session, err := client.NewSession()
	if err != nil {
		fmt.Println("Failed to create session")
		fmt.Println("Error : ", err.Error())
		return nil, err
	}

	return session, nil
}
예제 #22
0
파일: shell.go 프로젝트: juztin/shelli
// NewPty creates a new SSH session to the client using inCh as stdin, and quiting on a receive to quit.
// Returns stdout, stderr channels and error channel
func NewPty(client *ssh.Client, inCh <-chan []byte, quit <-chan struct{}) (<-chan []byte, <-chan []byte, <-chan error) {
	errCh := make(chan error, 1)
	// Create a new session from the given configuration func.
	session, err := client.NewSession()
	if err != nil {
		errCh <- err
		return nil, nil, nil
	}
	// Get session std in/out/err
	stdin, stdout, stderr, err := sessionStreams(session)
	if err != nil {
		errCh <- err
		return nil, nil, nil
	}
	// Stream from readers to channels
	stdoutCh := make(chan []byte)
	stderrCh := make(chan []byte)
	go streamToChan(stdout, stdoutCh, errCh)
	go streamToChan(stderr, stderrCh, errCh)
	// Set terminal modes
	modes := ssh.TerminalModes{
		ssh.VREPRINT: 0,
		ssh.CS8:      1,
		ssh.ECHOE:    1,
		ssh.ECHOCTL:  0,
	}
	// Request pseudo terminal
	err = session.RequestPty("xterm", 24, 80, modes)
	//err = session.RequestPty("vt100", 24, 80, modes)
	if err != nil {
		errCh <- err
		return nil, nil, nil
	}
	// Invoke SSH shell
	err = session.Shell()
	if err != nil {
		errCh <- err
		return nil, nil, nil
	}
	// Listen for input/quit
	go func() {
		for {
			select {
			case b := <-inCh:
				stdin.Write(b)
			case <-quit:
				session.Close()
				return
			}
		}
	}()
	return stdoutCh, stderrCh, errCh
}
예제 #23
0
파일: ssh.go 프로젝트: ahjdzx/dis
func ChangeDir(client *ssh.Client, dir string) error {
	session, err := client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	err = session.Run(`bash -c "cd ` + dir + `"`)
	if err != nil {
		return err
	}
	return nil
}
예제 #24
0
파일: ssh.go 프로젝트: ahjdzx/dis
func Mkdir(client *ssh.Client, destDir string) error {
	session, err := client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	err = session.Run(`bash -c "mkdir -p ` + destDir + `"`)
	if err != nil {
		return err
	}
	return nil
}
예제 #25
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
}
예제 #26
0
func NewSession(conn *ssh.Client, deadline *time.Time, idleTimeout int) (ss *SshSession, err error) {
	session, err := conn.NewSession()
	if err != nil {
		return nil, err
	}
	sshSession := new(SshSession)
	sshSession.session = session
	sshSession.deadline = deadline
	sshSession.idleTimeout = idleTimeout
	sshSession.id = Rand().Hex()
	//check session timeout
	go sshSession.checkSessionTimeout()
	return sshSession, nil
}
예제 #27
0
파일: ssh.go 프로젝트: ahjdzx/dis
func Pwd(client *ssh.Client) (string, error) {
	session, err := client.NewSession()
	if err != nil {
		return "", err
	}
	defer session.Close()

	output, err := session.CombinedOutput(`bash -c "pwd"`)
	if err != nil {
		return "", err
	}

	return string(output), nil
}
예제 #28
0
파일: remote.go 프로젝트: rainycape/browser
func runRemoteCmd(client *ssh.Client, cmd string, args ...string) (string, error) {
	session, err := client.NewSession()
	if err != nil {
		return "", fmt.Errorf("failed to create session: %s", err)
	}
	defer session.Close()
	var out bytes.Buffer
	session.Stdout = &out
	session.Stderr = &out
	fullCmd := shellJoin(cmd, args)
	if err := session.Run(fullCmd); err != nil {
		return "", fmt.Errorf("failed to run %s: %s", fullCmd, err)
	}
	return out.String(), nil
}
예제 #29
0
파일: secret.go 프로젝트: xperimental/yovpn
func readSecret(client *ssh.Client) (string, error) {
	session, err := client.NewSession()
	if err != nil {
		return "", err
	}
	defer session.Close()

	var b bytes.Buffer
	session.Stdout = &b
	if err := session.Run("cat /etc/openvpn/secret.key"); err != nil {
		return "", err
	}

	return b.String(), nil
}
예제 #30
0
파일: main.go 프로젝트: gooops/goscp
func sendFileToRemoteHost(client *ssh.Client, limit int64, sourceFile, targetUser, targetHost, targetFile string) {
	session, err := client.NewSession()
	if err != nil {
		log.Fatalln("Failed to create session: " + err.Error())
	}
	defer session.Close()

	go func() {
		iw, err := session.StdinPipe()
		if err != nil {
			log.Fatalln("Failed to create input pipe: " + err.Error())
		}

		w := flowrate.NewWriter(iw, limit)
		src, srcErr := os.Open(sourceFile)
		if srcErr != nil {
			log.Fatalln("Failed to open source file: " + srcErr.Error())
		}
		srcStat, statErr := src.Stat()
		if statErr != nil {
			log.Fatalln("Failed to stat file: " + statErr.Error())
		}

		fmt.Fprintln(w, "C0644", srcStat.Size(), filepath.Base(sourceFile))
		if srcStat.Size() > 0 {
			bar := pb.New(int(srcStat.Size()))
			bar.Units = pb.U_BYTES
			bar.ShowSpeed = true
			bar.Start()
			wp := io.MultiWriter(w, bar)

			fmt.Printf("Transferring %s to %s@%s:%s\n", sourceFile, targetUser, targetHost, targetFile)
			fmt.Printf("Speed limited to %d bytes/sec\n", limit)

			io.Copy(wp, src)
			bar.Finish()
			fmt.Fprint(w, "\x00")
			w.Close()
		} else {
			fmt.Printf("Transferred empty file %s to %s@%s:%s\n", sourceFile, targetUser, targetHost, targetFile)
			fmt.Fprint(w, "\x00")
			w.Close()
		}
	}()
	if err := session.Run(fmt.Sprintf("scp -t %s", targetFile)); err != nil {
		log.Fatalln("Failed to run: " + err.Error())
	}
}