-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathExecFunctions.go
384 lines (344 loc) · 10.6 KB
/
ExecFunctions.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
package main
import (
"encoding/base64"
log "glog"
"regexp"
"strings"
"time"
"golang.org/x/crypto/ssh"
)
// //H3c6800Exec 尝试netconf操作
// func H3c6800Exec(h3cStruct H3cCommand) int {
// var CMDRETNUM = 200 //默认执行返回值200,表示正常
//
// // base64解密交换机密码
// XXswitchRealPassword, _ := base64.URLEncoding.DecodeString(h3cStruct.SwitchPassword)
// // 解密后的密码除去前10位之后的才是真正的密码
// switchRealPassword := string(XXswitchRealPassword)[10:]
//
// //组装ssh的配置文件
//
// config := &ssh.ClientConfig{
// User: h3cStruct.SwitchUsername,
// Auth: []ssh.AuthMethod{
// ssh.Password(switchRealPassword),
// },
// Timeout: h3cStruct.SwitchTimeout * time.Second,
// Config: ssh.Config{
// Ciphers: []string{"aes128-cbc"},
// },
// }
// // config.Config.Ciphers = append(config.Config.Ciphers, "aes128-cbc")
// clinet, err := ssh.Dial("tcp", h3cStruct.SwitchIPAndPort, config)
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 303, err)
// return 303
// }
//
// session, err := clinet.NewSession()
// defer session.Close()
//
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 304, err)
// return 304
// }
//
// modes := ssh.TerminalModes{
// ssh.ECHO: 1, // disable echoing
// ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
// ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
// }
//
// if err := session.RequestPty("vt100", 80, 40, modes); err != nil {
//
// log.Errorf(" ErrorCode:%d , %s", 305, err)
// return 305
// }
//
// w, err := session.StdinPipe()
// if err != nil {
//
// log.Errorf(" ErrorCode:%d , %s", 306, err)
// return 306
// }
// r, err := session.StdoutPipe()
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 307, err)
// return 307
// }
// e, err := session.StderrPipe()
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 308, err)
// return 308
// }
//
// in, out := MuxShell(w, r, e)
//
// if err := session.Shell(); err != nil {
// log.Errorf(" ErrorCode:%d , %s", 309, err)
// return 309
// }
// <-out // 第一次输出为登陆后的设备提示信息, Copyright (c) 2004-2013 Hangzhou H3C Tech. Co., 可以不打印
// in <- "xml"
// //log.Infoln(<-out) //进入系统模式
// fmt.Println(<-out)
//
// in <- `
// <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
// <capabilities>
// <capability>
// urn:ietf:params:netconf:base:1.0
// </capability>
// </capabilities>
// </hello>]]>]]>
// `
//
// in <- `
// <rpc message-id="103" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
// <close-session/>
// </rpc>]]>]]>
// `
//
// in <- "quit"
//
// for resultStr := range out { // 循环从out管道中遍历出最后两条的输出结果
// log.Infoln(resultStr)
// fmt.Println(<-out)
// }
//
// session.Wait()
// log.Infof("%s\n", "<--ExecClose")
//
// return CMDRETNUM
//
// }
//H3cCommandViewRoute 本函数作用在于查看某条路由是否存在
// func H3cCommandViewRoute(h3cStruct H3cCommand) ([]string, int) {
//
// var routeSlice []string //准备存放过滤出来的静态路由
//
// var CMDRETNUM = 200 //默认执行返回值0,
//
// // base64解密交换机密码
// XXswitchRealPassword, _ := base64.URLEncoding.DecodeString(h3cStruct.SwitchPassword)
// // 解密后的密码除去前10位之后的才是真正的密码
// switchRealPassword := string(XXswitchRealPassword)[10:]
//
// //组装ssh的配置文件
//
// config := &ssh.ClientConfig{
// User: h3cStruct.SwitchUsername,
// Auth: []ssh.AuthMethod{
// ssh.Password(switchRealPassword),
// },
// Timeout: h3cStruct.SwitchTimeout * time.Second,
// Config: ssh.Config{
// Ciphers: []string{"aes128-cbc"},
// },
// }
// // config.Config.Ciphers = append(config.Config.Ciphers, "aes128-cbc")
// clinet, err := ssh.Dial("tcp", h3cStruct.SwitchIPAndPort, config)
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 303, err)
// return routeSlice, 303
// }
// defer clinet.Close()
//
// session, err := clinet.NewSession()
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 304, err)
// return routeSlice, 304
// }
// defer session.Close()
//
//
// modes := ssh.TerminalModes{
// ssh.ECHO: 1, // disable echoing
// ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
// ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
// }
//
// // 定义窗口
// if err := session.RequestPty("vt100", 80, 40, modes); err != nil {
//
// log.Errorf(" ErrorCode:%d , %s", 305, err)
// return routeSlice, 305
// }
//
// w, err := session.StdinPipe()
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 306, err)
// return routeSlice, 306
// }
// r, err := session.StdoutPipe()
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 307, err)
// return routeSlice, 307
// }
// e, err := session.StderrPipe()
// if err != nil {
// log.Errorf(" ErrorCode:%d , %s", 308, err)
// return routeSlice, 308
// }
//
// in, out := MuxShell(w, r, e)
//
// if err := session.Shell(); err != nil {
// log.Errorf(" ErrorCode:%d , %s", 309, err)
// return routeSlice, 309
// }
// <-out // 第一次输出为登陆后的设备提示信息, Copyright (c) 2004-2013 Hangzhou H3C Tech. Co., 丢弃显示
//
// in <- h3cStruct.SwitchCommand
//
// in <- "quit" // 这个一输入就断开连接了, 得不到out的输出
//
// for resultStr := range out { // 循环从out管道中便利出执行结果
// log.Infoln(resultStr)
//
// // 用于过滤的正则表达式也定制为只显示10.2XX类的路由,防止误伤到其他交换机路由。
// re, _ := regexp.Compile("ip route-static 10\\.2[0-9]{2}\\.[0-9]{1,3}\\.[0-9]{1,3} .* [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}")
//
// allinone := re.FindAll([]byte(resultStr), -1)
//
// for _, u := range allinone {
// routeSlice = append(routeSlice, string(u)) // 填充到事先准备好的slice中
//
// }
//
// if strings.Contains(resultStr, "^") { //如果有别的错误类型也可以在这里添加返回码
// CMDRETNUM = 400 // 命令不能识别
// }
//
// }
//
// session.Wait()
//
// log.Infof("%s\n", "<--ViewClose")
//
// return routeSlice, CMDRETNUM
//
// }
//H3cCommandExec 本函数作用执行一条添加路由的操作
func H3cCommandExec(h3cStruct H3cCommand) int {
var CMDRETNUM = 200 //默认执行返回值200,表示正常
// base64解密交换机密码
XXswitchRealPassword, _ := base64.URLEncoding.DecodeString(h3cStruct.SwitchPassword)
// 解密后的密码除去前10位之后的才是真正的密码
switchRealPassword := string(XXswitchRealPassword)
//组装ssh的配置文件
config := &ssh.ClientConfig{
User: h3cStruct.SwitchUsername,
Auth: []ssh.AuthMethod{
ssh.Password(switchRealPassword),
},
Timeout: h3cStruct.SwitchTimeout * time.Second,
Config: ssh.Config{
Ciphers: []string{"aes128-cbc"},
},
}
// config.Config.Ciphers = append(config.Config.Ciphers, "aes128-cbc")
clinet, err := ssh.Dial("tcp", h3cStruct.SwitchIPAndPort, config)
if err != nil {
log.Errorf(" ErrorCode:%d , %s", 303, err)
return 303
}
defer clinet.Close()
session, err := clinet.NewSession()
if err != nil {
log.Errorf(" ErrorCode:%d , %s", 304, err)
return 304
}
defer session.Close()
modes := ssh.TerminalModes{
ssh.ECHO: 1, // disable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
if err := session.RequestPty("vt100", 80, 40, modes); err != nil {
log.Errorf(" ErrorCode:%d , %s", 305, err)
return 305
}
w, err := session.StdinPipe()
if err != nil {
log.Errorf(" ErrorCode:%d , %s", 306, err)
return 306
}
r, err := session.StdoutPipe()
if err != nil {
log.Errorf(" ErrorCode:%d , %s", 307, err)
return 307
}
e, err := session.StderrPipe()
if err != nil {
log.Errorf(" ErrorCode:%d , %s", 308, err)
return 308
}
in, out := MuxShell(w, r, e)
if err := session.Shell(); err != nil {
log.Errorf(" ErrorCode:%d , %s", 309, err)
return 309
}
<-out // 第一次输出为登陆后的设备提示信息, Copyright (c) 2004-2013 Hangzhou H3C Tech. Co., 可以不打印
in <- "sy"
log.Infoln(<-out) //进入系统模式
for _, _u := range strings.Split(h3cStruct.SwitchCommand, ";") {
in <- _u //执行合规的那四种命令
resultStr := <-out
log.Infoln(resultStr)
if strings.Contains(resultStr, "Route doesn't exist") {
CMDRETNUM = 401 //操作的路由不存在
}
if strings.Contains(resultStr, "^") { //如果已经用正则表达式严谨的匹配过ip应该不会出现这里的错误
CMDRETNUM = 400 // 命令不能识别
}
}
//当执行的是多条命令时, 只有所有的命令都没有报错,才会执行save force ,只要有一条命令有问题,则不执行save动作。
if CMDRETNUM == 200 { // 如果之前的命令都没有执行错误,则保存配置,否则不保存直接退出。<
in <- "save force"
}
in <- "quit" //退出到普通用户模式。
in <- "quit" // 这个一输入就断开连接了, 得不到out的输出
for resultStr := range out { // 循环从out管道中遍历出最后两条的输出结果
log.Infoln(resultStr)
}
session.Wait()
log.Infof("%s\n", "<--ExecClose")
return CMDRETNUM
}
func checkCmd(cmdStr string, cmdLevel int) bool { //是否包含以下这些掩码,包含的话说明威胁不大,如果不包含则不运行这条命令;
InitStatus := true
for i, _u := range strings.Split(cmdStr, ";") {
// 如果命令行中有分号,则需要
log.Infof("chechcmd %d:%s\n", i, _u)
//如果行尾多加了一个分号
if len(_u) < 10 {
log.Warning("attention: len checkcmd < 10 ,too short")
}
//根据cmdlevel的不通,实施不同的匹配规则
switch {
case cmdLevel == 1:
if m, _ := regexp.MatchString("^display .*", _u); m {
//fmt.Println("---display----->", m, mm)
continue
}
// 一组命令中只要有一条命令不合规,则返回false,此处不做详细的提示。
log.Warning("checkcmd error," + _u)
InitStatus = false
break
case cmdLevel == 2:
if m, _ := regexp.MatchString("ip route-static 10\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3} 255\\.255\\.255\\.0 [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}", _u); m { //操作的路由是10.2XX.X.X/24,以防止增删不当
continue
}
// 一组命令中只要有一条命令不合规,则返回false,此处不做详细的提示。
log.Warning("checkcmd error," + _u)
InitStatus = false
break
default:
log.Warning("checkcmd error, unknown cmdLevel")
InitStatus = false
}
}
//fmt.Println("for oever")
return InitStatus
}