-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.go
128 lines (124 loc) · 4.2 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"flag"
"fmt"
"golang.org/x/crypto/ssh"
"io"
"log"
"strings"
"time"
)
var ip = flag.String("ip", "", "location of the switch to manage")
var userName = flag.String("userName", "", "username to connect to switch")
var normalPw = flag.String("normalPW", "", "the standard switch ssh password")
var enablePw = flag.String("enablePW", "", "the enable password for esculated priv")
var tftpServer = flag.String("tftpServer", "", "the tftp server ip address")
func readBuffForString(whattoexpect string, sshOut io.Reader, buffRead chan<- string) {
buf := make([]byte, 1000)
n, err := sshOut.Read(buf) //this reads the ssh terminal
waitingString := ""
if err == nil {
waitingString = string(buf[:n])
}
for (err == nil) && (!strings.Contains(waitingString, whattoexpect)) {
n, err = sshOut.Read(buf)
waitingString += string(buf[:n])
//fmt.Println(waitingString) //uncommenting this might help you debug if you are coming into errors with timeouts when correct details entered
}
buffRead <- waitingString
}
func readBuff(whattoexpect string, sshOut io.Reader, timeoutSeconds int) string {
ch := make(chan string)
go func(whattoexpect string, sshOut io.Reader) {
buffRead := make(chan string)
go readBuffForString(whattoexpect, sshOut, buffRead)
select {
case ret := <-buffRead:
ch <- ret
case <-time.After(time.Duration(timeoutSeconds) * time.Second):
handleError(fmt.Errorf("%d", timeoutSeconds), true, "Waiting for \""+whattoexpect+"\" took longer than %s seconds, perhaps you've entered incorrect details?")
}
}(whattoexpect, sshOut)
return <-ch
}
func writeBuff(command string, sshIn io.WriteCloser) (int, error) {
returnCode, err := sshIn.Write([]byte(command + "\r"))
return returnCode, err
}
func handleError(e error, fatal bool, customMessage ...string) {
var errorMessage string
if e != nil {
if len(customMessage) > 0 {
errorMessage = strings.Join(customMessage, " ")
} else {
errorMessage = "%s"
}
if fatal == true {
log.Fatalf(errorMessage, e)
} else {
log.Print(errorMessage, e)
}
}
}
func main() {
flag.Parse()
/*
fmt.Println("IP Chosen: ", *ip)
fmt.Println("Username", *userName)
fmt.Println("Normal PW", *normalPw)
fmt.Println("Enable PW", *enablePw)
fmt.Println("TFTP Server", *tftpServer)
*/
sshConfig := &ssh.ClientConfig{
User: *userName,
Auth: []ssh.AuthMethod{
ssh.Password(*normalPw),
},
}
sshConfig.Config.Ciphers = append(sshConfig.Config.Ciphers, "aes128-cbc")
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
}
connection, err := ssh.Dial("tcp", *ip+":22", sshConfig)
if err != nil {
log.Fatalf("Failed to dial: %s", err)
}
session, err := connection.NewSession()
handleError(err, true, "Failed to create session: %s")
sshOut, err := session.StdoutPipe()
handleError(err, true, "Unable to setup stdin for session: %v")
sshIn, err := session.StdinPipe()
handleError(err, true, "Unable to setup stdout for session: %v")
if err := session.RequestPty("xterm", 0, 200, modes); err != nil {
session.Close()
handleError(err, true, "request for pseudo terminal failed: %s")
}
if err := session.Shell(); err != nil {
session.Close()
handleError(err, true, "request for shell failed: %s")
}
readBuff(">", sshOut, 2)
if _, err := writeBuff("enable", sshIn); err != nil {
handleError(err, true, "Failed to run: %s")
}
if _, err := writeBuff(*enablePw, sshIn); err != nil {
handleError(err, true, "Failed to run: %s")
}
readBuff("#", sshOut, 2)
if _, err := writeBuff("copy running-config tftp", sshIn); err != nil {
handleError(err, true, "Failed to run: %s")
}
readBuff("Address or name of remote host []?", sshOut, 2)
if _, err := writeBuff(*tftpServer, sshIn); err != nil {
handleError(err, true, "Failed to run: %s")
}
readBuff("confg]?", sshOut, 2)
filename := []string{"switchBackup-", strings.Replace(*ip, ".", "-", -1), "_", strings.Replace(time.Now().Format(time.RFC3339), ":", "", -1)}
if _, err := writeBuff(strings.Join(filename, ""), sshIn); err != nil {
handleError(err, true, "Failed to run: %s")
}
fmt.Println(readBuff("bytes/sec)", sshOut, 60))
session.Close()
}