handler.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package main
  2. import (
  3. "bufio"
  4. "bytes"
  5. "crypto/tls"
  6. "encoding/json"
  7. "fmt"
  8. "io/ioutil"
  9. "log"
  10. "net/http"
  11. "net/url"
  12. "os"
  13. "regexp"
  14. "strings"
  15. "github.com/dgrijalva/jwt-go"
  16. "github.com/labstack/echo"
  17. "golang.org/x/crypto/ssh"
  18. )
  19. type handler struct{}
  20. type userInfo struct {
  21. Result struct {
  22. Result struct {
  23. Sshpubkeyfp []string `json:"sshpubkeyfp"`
  24. HasKeytab bool `json:"has_keytab"`
  25. Ipasshpubkey []string `json:"ipasshpubkey"`
  26. Cn []string `json:"cn"`
  27. Krbcanonicalname []string `json:"krbcanonicalname"`
  28. Krbticketflags []string `json:"krbticketflags"`
  29. MemberofGroup []string `json:"memberof_group"`
  30. HasPassword bool `json:"has_password"`
  31. Homedirectory []string `json:"homedirectory"`
  32. Nsaccountlock bool `json:"nsaccountlock"`
  33. UID []string `json:"uid"`
  34. Title []string `json:"title"`
  35. Loginshell []string `json:"loginshell"`
  36. Uidnumber []string `json:"uidnumber"`
  37. Preserved bool `json:"preserved"`
  38. Krbextradata []struct {
  39. Base64 string `json:"__base64__"`
  40. } `json:"krbextradata"`
  41. Mail []string `json:"mail"`
  42. MemberofindirectHbacrule []string `json:"memberofindirect_hbacrule"`
  43. Dn string `json:"dn"`
  44. Displayname []string `json:"displayname"`
  45. Mepmanagedentry []string `json:"mepmanagedentry"`
  46. Ipauniqueid []string `json:"ipauniqueid"`
  47. Krbloginfailedcount []string `json:"krbloginfailedcount"`
  48. Krbpwdpolicyreference []string `json:"krbpwdpolicyreference"`
  49. Krbprincipalname []string `json:"krbprincipalname"`
  50. Givenname []string `json:"givenname"`
  51. Krblastadminunlock []struct {
  52. Datetime string `json:"__datetime__"`
  53. } `json:"krblastadminunlock"`
  54. Krbpasswordexpiration []struct {
  55. Datetime string `json:"__datetime__"`
  56. } `json:"krbpasswordexpiration"`
  57. Krblastfailedauth []struct {
  58. Datetime string `json:"__datetime__"`
  59. } `json:"krblastfailedauth"`
  60. Objectclass []string `json:"objectclass"`
  61. Gidnumber []string `json:"gidnumber"`
  62. Gecos []string `json:"gecos"`
  63. Sn []string `json:"sn"`
  64. MemberofSudorule []string `json:"memberof_sudorule"`
  65. Krblastpwdchange []struct {
  66. Datetime string `json:"__datetime__"`
  67. } `json:"krblastpwdchange"`
  68. Initials []string `json:"initials"`
  69. } `json:"result"`
  70. Value string `json:"value"`
  71. Summary interface{} `json:"summary"`
  72. } `json:"result"`
  73. Version string `json:"version"`
  74. Error interface{} `json:"error"`
  75. ID int `json:"id"`
  76. Principal string `json:"principal"`
  77. }
  78. // Most of the code is taken from the echo guide
  79. // https://echo.labstack.com/cookbook/jwt
  80. func (h *handler) login(c echo.Context) error {
  81. username := c.FormValue("username")
  82. password := c.FormValue("password")
  83. _url := "https://ipa.sf.faraborddi.dc/ipa/session/login_password"
  84. method := "POST"
  85. params := url.Values{}
  86. params.Add("user", username)
  87. params.Add("password", password)
  88. payload := strings.NewReader(params.Encode())
  89. tr := &http.Transport{
  90. TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
  91. }
  92. client := &http.Client{Transport: tr}
  93. req, err := http.NewRequest(method, _url, payload)
  94. audit("Recieved Login request from: " + RealIP)
  95. if err != nil {
  96. fmt.Println(err)
  97. }
  98. req.Header.Add("Referer", "https://ipa.sf.faraborddi.dc/ipa")
  99. req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  100. req.Header.Add("Accept", "text/plain")
  101. res, err := client.Do(req)
  102. cockie := res.Cookies()
  103. defer res.Body.Close()
  104. //fmt.Println(res.StatusCode)
  105. if res.StatusCode == 200 {
  106. user := getUserInfo(cockie, username)
  107. //fmt.Println(user.Result.Value)
  108. tokens, err := generateTokenPair(user)
  109. if err != nil {
  110. return err
  111. }
  112. return c.JSON(http.StatusOK, tokens)
  113. }
  114. return echo.ErrUnauthorized
  115. }
  116. func getUserInfo(cockie []*http.Cookie, username string) userInfo {
  117. url := "https://ipa.sf.faraborddi.dc/ipa/session/json"
  118. method := "POST"
  119. _json := fmt.Sprintf(`
  120. {
  121. "method": "user_show",
  122. "params": [
  123. [
  124. "%s"
  125. ],
  126. {
  127. "all": true,
  128. "version": "2.215"
  129. }
  130. ],
  131. "id": 0
  132. }
  133. `, username)
  134. payload := strings.NewReader(_json)
  135. tr := &http.Transport{
  136. TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
  137. }
  138. client := &http.Client{Transport: tr}
  139. req, err := http.NewRequest(method, url, payload)
  140. if err != nil {
  141. fmt.Println(err)
  142. }
  143. req.Header.Add("Referer", "https://ipa.sf.faraborddi.dc/ipa")
  144. req.Header.Add("Content-Type", "application/json")
  145. req.Header.Add("Accept", "text/plain")
  146. req.Header.Add("Cookie", cockie[0].Raw)
  147. res, err := client.Do(req)
  148. defer res.Body.Close()
  149. body, err := ioutil.ReadAll(res.Body)
  150. user := userInfo{}
  151. json.Unmarshal(body, &user)
  152. //fmt.Println(user.Result.Value)
  153. //fmt.Println(user.Result.Result.MemberofGroup)
  154. return user
  155. }
  156. // This is the api to refresh tokens
  157. // Most of the code is taken from the jwt-go package's sample codes
  158. // https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac
  159. //func (h *handler) token(c echo.Context) error {
  160. // type tokenReqBody struct {
  161. // RefreshToken string `json:"refresh_token"`
  162. // }
  163. // tokenReq := tokenReqBody{}
  164. // c.Bind(&tokenReq)
  165. //
  166. // // Parse takes the token string and a function for looking up the key.
  167. // // The latter is especially useful if you use multiple keys for your application.
  168. // // The standard is to use 'kid' in the head of the token to identify
  169. // // which key to use, but the parsed token (head and claims) is provided
  170. // // to the callback, providing flexibility.
  171. // token, err := jwt.Parse(tokenReq.RefreshToken, func(token *jwt.Token) (interface{}, error) {
  172. // // Don't forget to validate the alg is what you expect:
  173. // if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  174. // return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
  175. // }
  176. //
  177. // // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
  178. // return []byte("secret"), nil
  179. // })
  180. //
  181. // if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
  182. // // Get the user record from database or
  183. // // run through your business logic to verify if the user can log in
  184. // if int(claims["sub"].(float64)) == 1 {
  185. //
  186. // newTokenPair, err := generateTokenPair()
  187. // if err != nil {
  188. // return err
  189. // }
  190. //
  191. // return c.JSON(http.StatusOK, newTokenPair)
  192. // }
  193. //
  194. // return echo.ErrUnauthorized
  195. // }
  196. //
  197. // return err
  198. //}
  199. // Most of the code is taken from the echo guide
  200. // https://echo.labstack.com/cookbook/jwt
  201. func (h *handler) private(c echo.Context) error {
  202. user := c.Get("user").(*jwt.Token)
  203. claims := user.Claims.(jwt.MapClaims)
  204. name := claims["name"].(string)
  205. return c.String(http.StatusOK, "Welcome "+name+"!")
  206. }
  207. func Connect(user, pass, host string, cmd string) bytes.Buffer {
  208. cipher := ssh.Config{
  209. Ciphers: []string{"aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"},
  210. }
  211. config := &ssh.ClientConfig{
  212. User: user,
  213. Auth: []ssh.AuthMethod{
  214. ssh.Password(pass),
  215. },
  216. HostKeyCallback: ssh.InsecureIgnoreHostKey(),
  217. Config: cipher,
  218. }
  219. conn, err := ssh.Dial("tcp", host, config)
  220. // time.Sleep(1)
  221. if err != nil {
  222. log.Fatal("Failed to dial: ", err)
  223. }
  224. sess, err := conn.NewSession()
  225. if err != nil {
  226. log.Fatal("Failed to create session: ", err)
  227. }
  228. stdin, err := sess.StdinPipe()
  229. if err != nil {
  230. log.Fatal("Failed to create session: ", err)
  231. }
  232. var bout bytes.Buffer
  233. var berr bytes.Buffer
  234. sess.Stdout = &bout
  235. sess.Stderr = &berr
  236. sess.Shell()
  237. fmt.Fprintf(stdin, "%s\n", "terminal length 0")
  238. fmt.Fprintf(stdin, "%s\n", cmd)
  239. fmt.Fprintf(stdin, "\nexit\n")
  240. fmt.Fprintf(stdin, "exit\n")
  241. sess.Wait()
  242. sess.Close()
  243. // scanner := bufio.NewScanner(&bout)
  244. // for scanner.Scan() {
  245. // fmt.Println(scanner.Text())
  246. // }
  247. // fmt.Println(bout.String())
  248. return bout
  249. }
  250. func (h *handler) findMAC(c echo.Context) error {
  251. user := c.Get("user").(*jwt.Token)
  252. claims := user.Claims.(jwt.MapClaims)
  253. name := claims["name"].(string)
  254. result1 := Connect("rancid", "JDACy6wK*yW%meQ", os.Args[1], os.Args[2])
  255. intDesc := os.Args[3]
  256. var IntString string
  257. scanner := bufio.NewScanner(&result1)
  258. var IntName string
  259. var IntMAC string
  260. // var IntName, IntStatus, IntVLAN, IntDuplex, IntSpeed, IntType string
  261. for scanner.Scan() {
  262. // fmt.Println("Text: " + scanner.Text())
  263. if strings.Contains(scanner.Text(), intDesc) {
  264. // fmt.Println("Text: " + scanner.Text())
  265. IntString = scanner.Text()
  266. IntName = IntStringParser(IntString)[0]
  267. break
  268. }
  269. }
  270. // fmt.Println(IntName)
  271. result1 = Connect("rancid", "JDACy6wK*yW%meQ", os.Args[1], "sh mac address-table int "+IntName)
  272. scanner = bufio.NewScanner(&result1)
  273. for scanner.Scan() {
  274. // fmt.Println("Text: " + scanner.Text())
  275. if strings.Contains(scanner.Text(), IntName) {
  276. if strings.Contains(scanner.Text(), "mac") {
  277. continue
  278. }
  279. // fmt.Println(scanner.Text())
  280. IntString = scanner.Text()
  281. IntMAC = IntStringParser(IntString)[2]
  282. // fmt.Println(IntMAC)
  283. // break
  284. }
  285. }
  286. fmt.Println(IntMAC)
  287. return c.String(http.StatusOK, "Welcome "+IntMAC+"!")
  288. }
  289. func IntStringParser(str string) []string {
  290. re := regexp.MustCompile(`\s{1,}`)
  291. return strings.Split(re.ReplaceAllString(str, ","), ",")
  292. }