socks5_read_access_handle.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package socks5
  2. import (
  3. "context"
  4. "ehang.io/nps/core"
  5. "errors"
  6. "io"
  7. "net"
  8. )
  9. const (
  10. UserPassAuth = uint8(2)
  11. userAuthVersion = uint8(1)
  12. authSuccess = uint8(0)
  13. authFailure = uint8(1)
  14. UserNoAuth = uint8(0)
  15. )
  16. type Access struct {
  17. core.NpsPlugin
  18. }
  19. func (access *Access) GetConfigName() *core.NpsConfigs {
  20. return core.NewNpsConfigs("socks5_check_access", "need check the permission simply", core.CONFIG_LEVEL_PLUGIN)
  21. }
  22. func (access *Access) Run(ctx context.Context) (context.Context, error) {
  23. clientConn := access.GetClientConn(ctx)
  24. if access.Configs["socks5_check_access"] != "true" {
  25. return ctx, access.sendAccessMsgToClient(clientConn, UserNoAuth)
  26. }
  27. // need auth
  28. if err := access.sendAccessMsgToClient(clientConn, UserPassAuth); err != nil {
  29. return ctx, err
  30. }
  31. // send auth reply to client ,and get the auth information
  32. username, password, err := access.getAuthInfoFromClient(clientConn)
  33. if err != nil {
  34. return ctx, err
  35. }
  36. ctx = context.WithValue(ctx, "socks_client_username", username)
  37. ctx = context.WithValue(ctx, "socks_client_password", password)
  38. // check
  39. return ctx, nil
  40. }
  41. func (access *Access) sendAccessMsgToClient(clientConn net.Conn, auth uint8) error {
  42. buf := make([]byte, 2)
  43. buf[0] = 5
  44. buf[1] = auth
  45. n, err := clientConn.Write(buf)
  46. if err != nil || n != 2 {
  47. return errors.New("write access message to client error " + err.Error())
  48. }
  49. return nil
  50. }
  51. func (access *Access) getAuthInfoFromClient(clientConn net.Conn) (username string, password string, err error) {
  52. header := []byte{0, 0}
  53. if _, err = io.ReadAtLeast(clientConn, header, 2); err != nil {
  54. return
  55. }
  56. if header[0] != userAuthVersion {
  57. err = errors.New("authentication method is not supported")
  58. return
  59. }
  60. userLen := int(header[1])
  61. user := make([]byte, userLen)
  62. if _, err = io.ReadAtLeast(clientConn, user, userLen); err != nil {
  63. return
  64. }
  65. if _, err = clientConn.Read(header[:1]); err != nil {
  66. err = errors.New("get password length error" + err.Error())
  67. return
  68. }
  69. passLen := int(header[0])
  70. pass := make([]byte, passLen)
  71. if _, err = io.ReadAtLeast(clientConn, pass, passLen); err != nil {
  72. err = errors.New("get password error" + err.Error())
  73. return
  74. }
  75. username = string(user)
  76. password = string(pass)
  77. return
  78. }