예제 #1
0
파일: ssh.go 프로젝트: qjpcpu/sexy-ssh
func (s3h *Sssh) Login() {
	ssh_agent := func() AuthMethod {
		if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
			return PublicKeysCallback(agent.NewClient(sshAgent).Signers)
		}
		return nil
	}
	auths := []AuthMethod{
		Password(s3h.Password),
	}
	if os.Getenv("SSH_AUTH_SOCK") != "" {
		auths = append(auths, ssh_agent())
	}
	if s3h.Keyfile != "" {
		if key, err := getkey(s3h.Keyfile); err == nil {
			auths = append(auths, PublicKeys(key))
		}
	}
	config := &ClientConfig{
		User: s3h.User,
		Auth: auths,
	}
	conn, err := Dial("tcp", s3h.Host+":22", config)
	if err != nil {
		fmt.Fprintln(s3h.Errout, "unable to connect: ", err.Error())
		return
	}
	defer conn.Close()
	session, err := conn.NewSession()
	if err != nil {
		fmt.Fprintln(s3h.Errout, "Failed to create session: "+err.Error())
		return
	}
	defer session.Close()
	// Set IO
	session.Stdout = os.Stdout
	session.Stderr = os.Stderr
	in, _ := session.StdinPipe()

	// Set up terminal modes
	modes := TerminalModes{
		ECHO:          0,     // disable echoing
		TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
	}

	// Request pseudo terminal
	if err := session.RequestPty("xterm", 80, 200, modes); err != nil {
		fmt.Fprintln(s3h.Errout, "request for pseudo terminal failed: %s", err)
		return
	}

	// Start remote shell
	if err := session.Shell(); err != nil {
		fmt.Fprintln(s3h.Errout, "failed to start shell: %s", err)
		return
	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	qc := make(chan string)
	go func() {
	Loop:
		for {
			select {
			case <-c:
				session.Signal(SIGINT)
				fmt.Println("")
			case <-qc:
				signal.Stop(c)
				break Loop
			}
		}
	}()
	// Accepting commands
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		fmt.Fprint(in, scanner.Text()+"\n")
	}
	qc <- "Quit signal monitor"
}
예제 #2
0
파일: ssh.go 프로젝트: qjpcpu/sexy-ssh
func (s3h *Sssh) Work() {
	if s3h.Member != nil {
		s3h.Send(job.MASTER_ID, map[string]interface{}{"FROM": s3h.Host, "BODY": "BEGIN", "TAG": s3h})
		defer func() {
			s3h.Send(job.MASTER_ID, map[string]interface{}{"FROM": s3h.Host, "BODY": "END"})
		}()
		// Wait for master's reply
		data, _ := s3h.Receive(-1)
		info, _ := data.(map[string]interface{})
		if info["FROM"].(string) != job.MASTER_ID || info["BODY"].(string) != "CONTINUE" {
			return
		}
	}
	ssh_agent := func() AuthMethod {
		if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
			return PublicKeysCallback(agent.NewClient(sshAgent).Signers)
		}
		return nil
	}
	auths := []AuthMethod{
		Password(s3h.Password),
	}
	if os.Getenv("SSH_AUTH_SOCK") != "" {
		auths = append(auths, ssh_agent())
	}
	if s3h.Keyfile != "" {
		if key, err := getkey(s3h.Keyfile); err == nil {
			auths = append(auths, PublicKeys(key))
		}
	}
	config := &ClientConfig{
		User: s3h.User,
		Auth: auths,
	}
	conn, err := Dial("tcp", s3h.Host+":22", config)
	if err != nil {
		if s3h.Password != "" && strings.Contains(err.Error(), "unable to authenticate, attempted methods [none publickey]") {
			config = &ClientConfig{
				User: s3h.User,
				Auth: []AuthMethod{Password(s3h.Password)},
			}
			conn, err = Dial("tcp", s3h.Host+":22", config)
			if err != nil {
				fmt.Fprintln(s3h.Errout, "unable to connect: ", err.Error())
				return
			}
		} else {
			fmt.Fprintln(s3h.Errout, "unable to connect: ", err.Error())
			return
		}
	}
	defer conn.Close()
	session, err := conn.NewSession()
	if err != nil {
		fmt.Fprintln(s3h.Errout, "Failed to create session: "+err.Error())
		return
	}
	defer session.Close()

	session.Stdout = s3h.Output
	session.Stderr = s3h.Output
	session.Run(s3h.Cmd)
}
예제 #3
0
파일: scp.go 프로젝트: qjpcpu/sexy-ssh
func (scp *Scp) Work() {
	res := map[string]interface{}{"FROM": scp.Host, "BODY": "END"}
	if scp.Member != nil {
		scp.Send(job.MASTER_ID, map[string]interface{}{"FROM": scp.Host, "BODY": "BEGIN", "TAG": scp})
		defer func() {
			scp.Send(job.MASTER_ID, res)
		}()
		// Wait for master's reply
		data, _ := scp.Receive(-1)
		info, _ := data.(map[string]interface{})
		if info["FROM"].(string) != job.MASTER_ID && info["BODY"].(string) != "CONTINUE" {
			return
		}
	}
	ssh_agent := func() AuthMethod {
		if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
			return PublicKeysCallback(agent.NewClient(sshAgent).Signers)
		}
		return nil
	}
	auths := []AuthMethod{
		Password(scp.Password),
	}
	if os.Getenv("SSH_AUTH_SOCK") != "" {
		auths = append(auths, ssh_agent())
	}
	if scp.Keyfile != "" {
		if key, err := getkey(scp.Keyfile); err == nil {
			auths = append(auths, PublicKeys(key))
		}
	}
	config := &ClientConfig{
		User: scp.User,
		Auth: auths,
	}
	conn, err := Dial("tcp", scp.Host+":22", config)
	if err != nil {
		if scp.Password != "" && strings.Contains(err.Error(), "unable to authenticate, attempted methods [none publickey]") {
			config = &ClientConfig{
				User: scp.User,
				Auth: []AuthMethod{Password(scp.Password)},
			}
			conn, err = Dial("tcp", scp.Host+":22", config)
			if err != nil {
				res["RES"] = fmt.Sprintf("Unable to connect \033[31m%v\033[0m %v\n", scp.Host, err)
				return
			}
		} else {
			res["RES"] = fmt.Sprintf("Unable to connect \033[31m%v\033[0m %v\n", scp.Host, err)
			return
		}
	}
	defer conn.Close()
	session, err := conn.NewSession()
	if err != nil {
		res["RES"] = fmt.Sprintf("\033[31m%v\033[0m %v\n", scp.Host, err)
		return
	}
	defer session.Close()
	go func() {
		w, _ := session.StdinPipe()
		defer w.Close()
		fmt.Fprintf(w, "C%v %v %v\n", scp.Perm, len(scp.Data), filepath.Base(scp.Destfile))
		w.Write(scp.Data)
		fmt.Fprint(w, "\x00")
	}()
	if err := session.Run("/usr/bin/scp -qrt " + filepath.Dir(scp.Destfile)); err != nil {
		res["RES"] = fmt.Sprintf("\033[31mFailed to copy to %v!\033[0m\n", scp.Host)
	} else {
		res["RES"] = fmt.Sprintf("\033[33m%v\033[0m OK!\n", scp.Host)
	}
}