main.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package main
  2. import (
  3. "encoding/base64"
  4. "fmt"
  5. "os"
  6. "os/user"
  7. "regexp"
  8. "strings"
  9. "git.wecise.com/wecise/common/matrix/logger"
  10. "git.wecise.com/wecise/common/matrix/util"
  11. "gopkg.in/yaml.v2"
  12. )
  13. func init() {
  14. logger.SetConsole(true)
  15. logger.SetLevel(logger.TRACE)
  16. logger.SetFormat("yyyy-MM-dd HH:mm:ss.SSS [level] msg", "\n")
  17. }
  18. func uchi() (u, c, h string, i int) {
  19. if len(os.Args) < 2 {
  20. return
  21. }
  22. if msi := regexp.MustCompile(`^([^:]+):(.*)@([^@]*)$`).FindStringSubmatchIndex(os.Args[1]); msi != nil {
  23. u = os.Args[1][msi[2]:msi[3]]
  24. c = "=" + os.Args[1][msi[4]:msi[5]]
  25. h = os.Args[1][msi[6]:msi[7]]
  26. i = 2
  27. return
  28. }
  29. if msi := regexp.MustCompile(`^([^:]+)@([^@]*)$`).FindStringSubmatchIndex(os.Args[1]); msi != nil {
  30. u = os.Args[1][msi[2]:msi[3]]
  31. h = os.Args[1][msi[6]:msi[7]]
  32. i = 2
  33. } else if os.Args[1][0] != '-' && strings.Index(os.Args[1], "=") < 0 {
  34. h = os.Args[1]
  35. i = 2
  36. } else {
  37. i = 1
  38. }
  39. if u == "" {
  40. user, err := user.Current()
  41. if err != nil {
  42. logger.Error(util.ErrorWithSourceLine(err))
  43. return "", "", "", 0
  44. }
  45. u = user.Username
  46. }
  47. if h == "" {
  48. h = "127.0.0.1"
  49. }
  50. return
  51. }
  52. type KV struct{ Key, Val string }
  53. func parseArgs(args []string) (kvs []*KV) {
  54. argk := ""
  55. argv := ""
  56. for _, arg := range args {
  57. if argk != "" {
  58. argv = arg
  59. } else if regexp.MustCompile(`^\-\w+$`).MatchString(arg) {
  60. argk = arg[1:]
  61. continue
  62. } else {
  63. kv := strings.SplitN(arg, "=", 2)
  64. if len(kv) == 2 {
  65. argk = kv[0]
  66. argv = kv[1]
  67. } else {
  68. argk = ""
  69. argv = arg
  70. }
  71. }
  72. kvs = append(kvs, &KV{argk, argv})
  73. argk, argv = "", ""
  74. }
  75. if argk != "" {
  76. kvs = append(kvs, &KV{argk, argv})
  77. }
  78. return
  79. }
  80. func main() {
  81. u, c, h, i := uchi()
  82. if i == 0 {
  83. fmt.Println("usage:")
  84. fmt.Println(" msh user:password@host|p=password|a=passcode [[c=]command [p=password|a=passcode] [x=cmd-end-regexp] [[r=regexp] [o=output|n=outputline]]...]...")
  85. fmt.Println(" a=passcode should be base64 encoded, or use p=password")
  86. fmt.Println(" debug info include: p(progress) a(argments) m(match) 1(all)")
  87. return
  88. }
  89. kvs := parseArgs(os.Args[i:])
  90. if c == "" {
  91. for _, kv := range kvs {
  92. if kv.Key == "a" {
  93. c = kv.Val
  94. if c == "" {
  95. c = "="
  96. }
  97. break
  98. }
  99. if kv.Key == "p" {
  100. c = "=" + kv.Val
  101. break
  102. }
  103. }
  104. }
  105. p := c
  106. if len(p) > 0 && p[0:1] == "=" {
  107. p = p[1:]
  108. } else {
  109. x, e := base64.RawStdEncoding.DecodeString(p)
  110. if e == nil {
  111. p = string(x)
  112. }
  113. // else 不是Base64编码,保持原值
  114. }
  115. // explainArgs key, val
  116. cmds := []*Command{{Cmd: "ssh " + u + ":" + p + "@" + h, Password: c, Regexps: []*Matcher{{Regexp: nil, Output: ""}}, Endregx: regxprompt}}
  117. for _, kv := range kvs {
  118. key, val := kv.Key, kv.Val
  119. switch key {
  120. case "", "cmd", "command", "c":
  121. cmds = append(cmds, &Command{Cmd: val, Password: c, Regexps: []*Matcher{{Regexp: nil, Output: ""}}, Endregx: regxprompt})
  122. case "ry":
  123. re, err := regexp.Compile(val)
  124. if err != nil {
  125. logger.Error("arg", i, util.ErrorWithSourceLine(err))
  126. return
  127. } else {
  128. regxyesno = &Regexp{re}
  129. }
  130. case "rc":
  131. re, err := regexp.Compile(val)
  132. if err != nil {
  133. logger.Error("arg", i, util.ErrorWithSourceLine(err))
  134. return
  135. } else {
  136. regxpassword = &Regexp{re}
  137. }
  138. case "rp":
  139. re, err := regexp.Compile(val)
  140. if err != nil {
  141. logger.Error("arg", i, util.ErrorWithSourceLine(err))
  142. return
  143. } else {
  144. regxprompt = &Regexp{re}
  145. }
  146. case "password", "code", "pass", "p":
  147. cmds[len(cmds)-1].Password = "=" + val
  148. case "passcode", "b64code", "a":
  149. cmds[len(cmds)-1].Password = val
  150. case "re", "r", "regex":
  151. if val == "" {
  152. cmds[len(cmds)-1].Regexps = append(cmds[len(cmds)-1].Regexps, &Matcher{Regexp: nil})
  153. } else {
  154. re, err := regexp.Compile(val)
  155. if err != nil {
  156. logger.Error("arg", i, util.ErrorWithSourceLine(err))
  157. return
  158. } else {
  159. cmds[len(cmds)-1].Regexps = append(cmds[len(cmds)-1].Regexps, &Matcher{Regexp: &Regexp{re}})
  160. }
  161. }
  162. case "x", "end":
  163. if val == "" {
  164. cmds[len(cmds)-1].Endregx = regxprompt
  165. } else {
  166. re, err := regexp.Compile(val)
  167. if err != nil {
  168. logger.Error("arg", i, util.ErrorWithSourceLine(err))
  169. return
  170. } else {
  171. cmds[len(cmds)-1].Endregx = &Regexp{re}
  172. }
  173. }
  174. case "out", "o", "output":
  175. cmds[len(cmds)-1].Regexps[len(cmds[len(cmds)-1].Regexps)-1].Output += val
  176. case "outln", "n", "outputline":
  177. cmds[len(cmds)-1].Regexps[len(cmds[len(cmds)-1].Regexps)-1].Output += val + "\n"
  178. case "debug", "d":
  179. cmds[len(cmds)-1].Regexps[len(cmds[len(cmds)-1].Regexps)-1].Debug += val
  180. }
  181. }
  182. if strings.Index(cmds[0].Regexps[0].Debug, "a") >= 0 || strings.Index(cmds[0].Regexps[0].Debug, "1") >= 0 {
  183. //bs, _ := json.MarshalIndent(cmds, "", " ")
  184. bs, _ := yaml.Marshal(cmds)
  185. logger.Debug("arguments:\n" + string(bs))
  186. }
  187. node := &Node{
  188. Name: "x",
  189. Alias: "x",
  190. Host: h,
  191. User: u,
  192. Port: 22,
  193. KeyPath: "",
  194. Passphrase: "",
  195. Password: p,
  196. Commands: cmds,
  197. Children: []*Node{},
  198. Jump: []*Node{},
  199. }
  200. sshc := NewClient(node)
  201. sshc.Login()
  202. }