Skip to content

Commit

Permalink
Merge pull request #7 from ljun20160606/client
Browse files Browse the repository at this point in the history
refactor: hide password when it's right, thanks @ljun20160606  close #6
  • Loading branch information
yinheli committed Jul 24, 2018
2 parents ffb16cb + 8098507 commit d5104a1
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 114 deletions.
123 changes: 123 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package sshw

import (
"fmt"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
"io/ioutil"
"os"
"os/user"
"path"
"time"
)

type Client interface {
Login()
}

type defaultClient struct {
clientConfig *ssh.ClientConfig
node *Node
}

func NewClient(node *Node) Client {
u, err := user.Current()
if err != nil {
l.Error(err)
return nil
}

var authMethods []ssh.AuthMethod

var pemBytes []byte
if node.KeyPath == "" {
pemBytes, err = ioutil.ReadFile(path.Join(u.HomeDir, ".ssh/id_rsa"))
} else {
pemBytes, err = ioutil.ReadFile(node.KeyPath)
}

if err == nil {
signer, err := ssh.ParsePrivateKey(pemBytes)
if err == nil {
authMethods = append(authMethods, ssh.PublicKeys(signer))
}
}

password := node.password()

if password != nil {
authMethods = append(authMethods, password)
}

config := &ssh.ClientConfig{
User: node.user(),
Auth: authMethods,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: time.Second * 10,
}

config.SetDefaults()
config.Ciphers = append(config.Ciphers, "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc")

return &defaultClient{
clientConfig: config,
node: node,
}
}

func (c *defaultClient) Login() {
host := c.node.Host
port := c.node.port()
client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, port), c.clientConfig)
if err != nil {
l.Error(err)
return
}
defer client.Close()

l.Infof("connect server ssh -p %d %s@%s version: %s\n", port, c.node.user(), host, string(client.ServerVersion()))

session, err := client.NewSession()
if err != nil {
l.Error(err)
return
}
defer session.Close()

fd := int(os.Stdin.Fd())
state, err := terminal.MakeRaw(fd)
if err != nil {
l.Error(err)
return
}
defer terminal.Restore(fd, state)

w, h, err := terminal.GetSize(fd)
if err != nil {
l.Error(err)
return
}

modes := ssh.TerminalModes{
ssh.ECHO: 1,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
}
err = session.RequestPty("xterm", h, w, modes)
if err != nil {
l.Error(err)
return
}

session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin

err = session.Shell()
if err != nil {
l.Error(err)
return
}

session.Wait()
}
117 changes: 5 additions & 112 deletions cmd/sshw/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@ import (
"fmt"
"github.com/manifoldco/promptui"
"github.com/yinheli/sshw"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
"io/ioutil"
"os"
"os/user"
"path"
"runtime"
"strings"
"time"
)

const prev = "-parent-"
Expand Down Expand Up @@ -62,7 +56,8 @@ func main() {
return
}

login(node)
client := sshw.NewClient(node)
client.Login()
}

func choose(parent, trees []*sshw.Node) *sshw.Node {
Expand All @@ -84,10 +79,9 @@ func choose(parent, trees []*sshw.Node) *sshw.Node {
}
}
return true
} else {
if strings.Contains(content, input) {
return true
}
}
if strings.Contains(content, input) {
return true
}
return false
},
Expand All @@ -113,104 +107,3 @@ func choose(parent, trees []*sshw.Node) *sshw.Node {

return node
}

func login(node *sshw.Node) {
u, err := user.Current()
if err != nil {
log.Error(err)
return
}

var authMethods []ssh.AuthMethod

var b []byte
if node.KeyPath == "" {
b, err = ioutil.ReadFile(path.Join(u.HomeDir, ".ssh/id_rsa"))
} else {
b, err = ioutil.ReadFile(node.KeyPath)
}
if err == nil {
signer, err := ssh.ParsePrivateKey(b)
if err == nil {
authMethods = append(authMethods, ssh.PublicKeys(signer))
}
}

if node.Password != "" {
authMethods = append(authMethods, ssh.Password(node.Password))
}

username := node.User
host := node.Host
port := node.Port

if username == "" {
username = "root"
}
if port <= 0 {
port = 22
}

config := &ssh.ClientConfig{
User: username,
Auth: authMethods,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: time.Second * 10,
}

config.SetDefaults()
config.Ciphers = append(config.Ciphers, "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc")

client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, port), config)
if err != nil {
log.Error(err)
return
}
defer client.Close()

log.Infof("connect server ssh -p %d %s@%s password:%s version: %s\n", port, username, host, node.Password, string(client.ServerVersion()))

session, err := client.NewSession()
if err != nil {
log.Error(err)
return
}
defer session.Close()

fd := int(os.Stdin.Fd())
state, err := terminal.MakeRaw(fd)
if err != nil {
log.Error(err)
return
}
defer terminal.Restore(fd, state)

w, h, err := terminal.GetSize(fd)
if err != nil {
log.Error(err)
return
}

modes := ssh.TerminalModes{
ssh.ECHO: 1,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
}
err = session.RequestPty("xterm", h, w, modes)
if err != nil {
log.Error(err)
return
}

session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin

err = session.Shell()
if err != nil {
log.Error(err)
return
}

session.Wait()
}
26 changes: 24 additions & 2 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sshw

import (
"github.com/go-yaml/yaml"
"golang.org/x/crypto/ssh"
"io/ioutil"
"os/user"
"path"
Expand All @@ -17,8 +18,29 @@ type Node struct {
Children []*Node `json:"children"`
}

func (node *Node) String() string {
return node.Name
func (n *Node) String() string {
return n.Name
}

func (n *Node) user() string {
if n.User == "" {
return "root"
}
return n.User
}

func (n *Node) port() int {
if n.Port <= 0 {
return 22
}
return n.Port
}

func (n *Node) password() ssh.AuthMethod {
if n.Password == "" {
return nil
}
return ssh.Password(n.Password)
}

var (
Expand Down

0 comments on commit d5104a1

Please sign in to comment.