handler.go 8.0 KB

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