grpc.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package auth
  2. import (
  3. "context"
  4. "time"
  5. "github.com/drakkan/sftpgo/v2/sdk/plugin/auth/proto"
  6. )
  7. const (
  8. rpcTimeout = 20 * time.Second
  9. )
  10. // GRPCClient is an implementation of Authenticator interface that talks over RPC.
  11. type GRPCClient struct {
  12. client proto.AuthClient
  13. }
  14. // CheckUserAndPass implements the Authenticator interface
  15. func (c *GRPCClient) CheckUserAndPass(username, password, ip, protocol string, userAsJSON []byte) ([]byte, error) {
  16. ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
  17. defer cancel()
  18. resp, err := c.client.CheckUserAndPass(ctx, &proto.CheckUserAndPassRequest{
  19. Username: username,
  20. Password: password,
  21. Ip: ip,
  22. Protocol: protocol,
  23. User: userAsJSON,
  24. })
  25. if err != nil {
  26. return nil, err
  27. }
  28. return resp.User, nil
  29. }
  30. // CheckUserAndTLSCert implements the Authenticator interface
  31. func (c *GRPCClient) CheckUserAndTLSCert(username, tlsCert, ip, protocol string, userAsJSON []byte) ([]byte, error) {
  32. ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
  33. defer cancel()
  34. resp, err := c.client.CheckUserAndTLSCert(ctx, &proto.CheckUserAndTLSCertRequest{
  35. Username: username,
  36. TlsCert: tlsCert,
  37. Ip: ip,
  38. Protocol: protocol,
  39. User: userAsJSON,
  40. })
  41. if err != nil {
  42. return nil, err
  43. }
  44. return resp.User, nil
  45. }
  46. // CheckUserAndPublicKey implements the Authenticator interface
  47. func (c *GRPCClient) CheckUserAndPublicKey(username, pubKey, ip, protocol string, userAsJSON []byte) ([]byte, error) {
  48. ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
  49. defer cancel()
  50. resp, err := c.client.CheckUserAndPublicKey(ctx, &proto.CheckUserAndPublicKeyRequest{
  51. Username: username,
  52. PubKey: pubKey,
  53. Ip: ip,
  54. Protocol: protocol,
  55. User: userAsJSON,
  56. })
  57. if err != nil {
  58. return nil, err
  59. }
  60. return resp.User, nil
  61. }
  62. // CheckUserAndKeyboardInteractive implements the Authenticator interface
  63. func (c *GRPCClient) CheckUserAndKeyboardInteractive(username, ip, protocol string, userAsJSON []byte) ([]byte, error) {
  64. ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
  65. defer cancel()
  66. resp, err := c.client.CheckUserAndKeyboardInteractive(ctx, &proto.CheckUserAndKeyboardInteractiveRequest{
  67. Username: username,
  68. Ip: ip,
  69. Protocol: protocol,
  70. User: userAsJSON,
  71. })
  72. if err != nil {
  73. return nil, err
  74. }
  75. return resp.User, nil
  76. }
  77. // SendKeyboardAuthRequest implements the Authenticator interface
  78. func (c *GRPCClient) SendKeyboardAuthRequest(requestID, username, password, ip string, answers, questions []string, step int32) (string, []string, []bool, int, int, error) {
  79. ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
  80. defer cancel()
  81. resp, err := c.client.SendKeyboardAuthRequest(ctx, &proto.KeyboardAuthRequest{
  82. RequestID: requestID,
  83. Username: username,
  84. Password: password,
  85. Ip: ip,
  86. Answers: answers,
  87. Questions: questions,
  88. Step: step,
  89. })
  90. if err != nil {
  91. return "", nil, nil, 0, 0, err
  92. }
  93. return resp.Instructions, resp.Questions, resp.Echos, int(resp.AuthResult), int(resp.CheckPassword), err
  94. }
  95. // GRPCServer defines the gRPC server that GRPCClient talks to.
  96. type GRPCServer struct {
  97. Impl Authenticator
  98. }
  99. // CheckUserAndPass implements the server side check user and password method
  100. func (s *GRPCServer) CheckUserAndPass(ctx context.Context, req *proto.CheckUserAndPassRequest) (*proto.AuthResponse, error) {
  101. user, err := s.Impl.CheckUserAndPass(req.Username, req.Password, req.Ip, req.Protocol, req.User)
  102. if err != nil {
  103. return nil, err
  104. }
  105. return &proto.AuthResponse{User: user}, nil
  106. }
  107. // CheckUserAndTLSCert implements the server side check user and tls certificate method
  108. func (s *GRPCServer) CheckUserAndTLSCert(ctx context.Context, req *proto.CheckUserAndTLSCertRequest) (*proto.AuthResponse, error) {
  109. user, err := s.Impl.CheckUserAndTLSCert(req.Username, req.TlsCert, req.Ip, req.Protocol, req.User)
  110. if err != nil {
  111. return nil, err
  112. }
  113. return &proto.AuthResponse{User: user}, nil
  114. }
  115. // CheckUserAndPublicKey implements the server side check user and public key method
  116. func (s *GRPCServer) CheckUserAndPublicKey(ctx context.Context, req *proto.CheckUserAndPublicKeyRequest) (*proto.AuthResponse, error) {
  117. user, err := s.Impl.CheckUserAndPublicKey(req.Username, req.PubKey, req.Ip, req.Protocol, req.User)
  118. if err != nil {
  119. return nil, err
  120. }
  121. return &proto.AuthResponse{User: user}, nil
  122. }
  123. // CheckUserAndKeyboardInteractive implements the server side check user and keyboard interactive method
  124. func (s *GRPCServer) CheckUserAndKeyboardInteractive(ctx context.Context, req *proto.CheckUserAndKeyboardInteractiveRequest) (*proto.AuthResponse, error) {
  125. user, err := s.Impl.CheckUserAndKeyboardInteractive(req.Username, req.Ip, req.Protocol, req.User)
  126. if err != nil {
  127. return nil, err
  128. }
  129. return &proto.AuthResponse{User: user}, nil
  130. }
  131. // SendKeyboardAuthRequest implements the server side method to send a keyboard interactive authentication request
  132. func (s *GRPCServer) SendKeyboardAuthRequest(ctx context.Context, req *proto.KeyboardAuthRequest) (*proto.KeyboardAuthResponse, error) {
  133. instructions, questions, echos, authResult, checkPwd, err := s.Impl.SendKeyboardAuthRequest(req.RequestID, req.Username,
  134. req.Password, req.Ip, req.Answers, req.Questions, req.Step)
  135. if err != nil {
  136. return nil, err
  137. }
  138. return &proto.KeyboardAuthResponse{
  139. Instructions: instructions,
  140. Questions: questions,
  141. Echos: echos,
  142. AuthResult: int32(authResult),
  143. CheckPassword: int32(checkPwd),
  144. }, nil
  145. }