version 0.2

This commit is contained in:
Feng_Qi 2018-01-19 17:54:08 +08:00
parent c1c790e653
commit 87e207932f
13 changed files with 638 additions and 316 deletions

79
funcs/ssh_test.go Normal file
View file

@ -0,0 +1,79 @@
package funcs
import (
"bytes"
// "os"
//"strings"
"testing"
)
const (
username = "root"
password = ""
ip = "192.168.80.131"
port = 22
cmd = "cd /opt;pwd;exit"
key = "../server.key"
)
/*
func Test_SSH(t *testing.T) {
var cipherList []string
session, err := connect(username, password, ip, key, port, cipherList)
if err != nil {
t.Error(err)
return
}
defer session.Close()
cmdlist := strings.Split(cmd, ";")
stdinBuf, err := session.StdinPipe()
if err != nil {
t.Error(err)
return
}
var outbt, errbt bytes.Buffer
session.Stdout = &outbt
session.Stderr = &errbt
err = session.Shell()
if err != nil {
t.Error(err)
return
}
for _, c := range cmdlist {
c = c + "\n"
stdinBuf.Write([]byte(c))
}
session.Wait()
t.Log((outbt.String() + errbt.String()))
return
}
*/
func Test_SSH_run(t *testing.T) {
var cipherList []string
session, err := connect(username, password, ip, key, port, cipherList)
if err != nil {
t.Error(err)
return
}
defer session.Close()
//cmdlist := strings.Split(cmd, ";")
//newcmd := strings.Join(cmdlist, "&&")
var outbt, errbt bytes.Buffer
session.Stdout = &outbt
session.Stderr = &errbt
err = session.Run(cmd)
if err != nil {
t.Error(err)
return
}
t.Log((outbt.String() + errbt.String()))
return
}

200
funcs/sshconnect.go Normal file
View file

@ -0,0 +1,200 @@
package funcs
import (
"bytes"
"fmt"
"io/ioutil"
"net"
"strconv"
"strings"
"time"
"github.com/shanghai-edu/multissh/g"
"golang.org/x/crypto/ssh"
)
func connect(user, password, host, key string, port int, cipherList []string) (*ssh.Session, error) {
var (
auth []ssh.AuthMethod
addr string
clientConfig *ssh.ClientConfig
client *ssh.Client
config ssh.Config
session *ssh.Session
err error
)
// get auth method
auth = make([]ssh.AuthMethod, 0)
if key == "" {
auth = append(auth, ssh.Password(password))
} else {
pemBytes, err := ioutil.ReadFile(key)
if err != nil {
return nil, err
}
var signer ssh.Signer
if password == "" {
signer, err = ssh.ParsePrivateKey(pemBytes)
} else {
signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(password))
}
if err != nil {
return nil, err
}
auth = append(auth, ssh.PublicKeys(signer))
}
if len(cipherList) == 0 {
config = ssh.Config{
Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"},
}
} else {
config = ssh.Config{
Ciphers: cipherList,
}
}
clientConfig = &ssh.ClientConfig{
User: user,
Auth: auth,
Timeout: 30 * time.Second,
Config: config,
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
// connet to ssh
addr = fmt.Sprintf("%s:%d", host, port)
if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
return nil, err
}
// create session
if session, err = client.NewSession(); err != nil {
return nil, err
}
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", 80, 40, modes); err != nil {
return nil, err
}
return session, nil
}
func Dossh(username, password, host, key string, cmdlist []string, port, timeout int, cipherList []string, linuxMode bool, ch chan g.SSHResult) {
chSSH := make(chan g.SSHResult)
if linuxMode {
go dossh_run(username, password, host, key, cmdlist, port, cipherList, chSSH)
} else {
go dossh_session(username, password, host, key, cmdlist, port, cipherList, chSSH)
}
var res g.SSHResult
select {
case <-time.After(time.Duration(timeout) * time.Second):
res.Host = host
res.Success = false
res.Result = ("SSH run timeout" + strconv.Itoa(timeout) + " second.")
ch <- res
case res = <-chSSH:
ch <- res
}
return
}
func dossh_session(username, password, host, key string, cmdlist []string, port int, cipherList []string, ch chan g.SSHResult) {
session, err := connect(username, password, host, key, port, cipherList)
var sshResult g.SSHResult
sshResult.Host = host
if err != nil {
sshResult.Success = false
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
ch <- sshResult
return
}
defer session.Close()
cmdlist = append(cmdlist, "exit")
stdinBuf, _ := session.StdinPipe()
var outbt, errbt bytes.Buffer
session.Stdout = &outbt
session.Stderr = &errbt
err = session.Shell()
if err != nil {
sshResult.Success = false
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
ch <- sshResult
return
}
for _, c := range cmdlist {
c = c + "\n"
stdinBuf.Write([]byte(c))
}
session.Wait()
if errbt.String() != "" {
sshResult.Success = false
sshResult.Result = errbt.String()
ch <- sshResult
} else {
sshResult.Success = true
sshResult.Result = outbt.String()
ch <- sshResult
}
return
}
func dossh_run(username, password, host, key string, cmdlist []string, port int, cipherList []string, ch chan g.SSHResult) {
session, err := connect(username, password, host, key, port, cipherList)
var sshResult g.SSHResult
sshResult.Host = host
if err != nil {
sshResult.Success = false
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
ch <- sshResult
return
}
defer session.Close()
cmdlist = append(cmdlist, "exit")
newcmd := strings.Join(cmdlist, "&&")
var outbt, errbt bytes.Buffer
session.Stdout = &outbt
session.Stderr = &errbt
err = session.Run(newcmd)
if err != nil {
sshResult.Success = false
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
ch <- sshResult
return
}
if errbt.String() != "" {
sshResult.Success = false
sshResult.Result = errbt.String()
ch <- sshResult
} else {
sshResult.Success = true
sshResult.Result = outbt.String()
ch <- sshResult
}
return
}