Add basic account security

This adds a secret token associated with each account

	The token must then be sent with follow-up requests to ensure they get accepted

	This is _very_ basic security, and without TLS is completely vulnerable to MITM attacks, as well as brute force guessing (though it'd take a while to guess the a correct UUID)
This commit is contained in:
Marc Di Luzio 2020-07-07 22:20:23 +01:00
parent df30a0d689
commit 92222127a6
7 changed files with 413 additions and 232 deletions

View file

@ -34,7 +34,7 @@ func (s *Server) Register(ctx context.Context, req *rove.RegisterRequest) (*rove
return nil, fmt.Errorf("empty account name")
}
if _, err := s.accountant.RegisterAccount(req.Name); err != nil {
if acc, err := s.accountant.RegisterAccount(req.Name); err != nil {
return nil, err
} else if _, err := s.SpawnRoverForAccount(req.Name); err != nil {
@ -42,17 +42,26 @@ func (s *Server) Register(ctx context.Context, req *rove.RegisterRequest) (*rove
} else if err := s.SaveWorld(); err != nil {
return nil, fmt.Errorf("internal server error when saving world: %s", err)
}
return &rove.RegisterResponse{}, nil
} else {
return &rove.RegisterResponse{
Account: &rove.Account{
Name: acc.Name,
Secret: acc.Data["secret"],
},
}, nil
}
}
// Status returns rover information for a gRPC request
func (s *Server) Status(ctx context.Context, req *rove.StatusRequest) (response *rove.StatusResponse, err error) {
if len(req.Account) == 0 {
return nil, fmt.Errorf("empty account name")
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
return nil, err
} else if resp, err := s.accountant.GetValue(req.Account, "rover"); err != nil {
} else if !valid {
return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name)
} else if resp, err := s.accountant.GetValue(req.Account.Name, "rover"); err != nil {
return nil, err
} else if rover, err := s.world.GetRover(resp); err != nil {
@ -101,13 +110,16 @@ func (s *Server) Status(ctx context.Context, req *rove.StatusRequest) (response
// Radar returns the radar information for a rover
func (s *Server) Radar(ctx context.Context, req *rove.RadarRequest) (*rove.RadarResponse, error) {
if len(req.Account) == 0 {
return nil, fmt.Errorf("empty account name")
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
return nil, err
} else if !valid {
return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name)
}
response := &rove.RadarResponse{}
resp, err := s.accountant.GetValue(req.Account, "rover")
resp, err := s.accountant.GetValue(req.Account.Name, "rover")
if err != nil {
return nil, err
@ -128,10 +140,14 @@ func (s *Server) Radar(ctx context.Context, req *rove.RadarRequest) (*rove.Radar
// Command issues commands to the world based on a gRPC request
func (s *Server) Command(ctx context.Context, req *rove.CommandRequest) (*rove.CommandResponse, error) {
if len(req.Account) == 0 {
return nil, fmt.Errorf("empty account")
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
return nil, err
} else if !valid {
return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name)
}
resp, err := s.accountant.GetValue(req.Account, "rover")
resp, err := s.accountant.GetValue(req.Account.Name, "rover")
if err != nil {
return nil, err
}