package grpcserver import ( "context" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" "git.wntrmute.dev/kyle/metacrypt/internal/crypto" "git.wntrmute.dev/kyle/metacrypt/internal/seal" ) type systemServer struct { pb.UnimplementedSystemServiceServer s *GRPCServer } func (ss *systemServer) Status(_ context.Context, _ *pb.StatusRequest) (*pb.StatusResponse, error) { return &pb.StatusResponse{State: ss.s.sealMgr.State().String()}, nil } func (ss *systemServer) Init(ctx context.Context, req *pb.InitRequest) (*pb.InitResponse, error) { if req.Password == "" { return nil, status.Error(codes.InvalidArgument, "password is required") } params := crypto.Argon2Params{ Time: ss.s.cfg.Seal.Argon2Time, Memory: ss.s.cfg.Seal.Argon2Memory, Threads: ss.s.cfg.Seal.Argon2Threads, } if err := ss.s.sealMgr.Initialize(ctx, []byte(req.Password), params); err != nil { switch err { case seal.ErrAlreadyInitialized: return nil, status.Error(codes.AlreadyExists, "already initialized") default: ss.s.logger.Error("grpc: init failed", "error", err) return nil, status.Error(codes.Internal, "initialization failed") } } return &pb.InitResponse{State: ss.s.sealMgr.State().String()}, nil } func (ss *systemServer) Unseal(ctx context.Context, req *pb.UnsealRequest) (*pb.UnsealResponse, error) { if err := ss.s.sealMgr.Unseal([]byte(req.Password)); err != nil { switch err { case seal.ErrNotInitialized: return nil, status.Error(codes.FailedPrecondition, "not initialized") case seal.ErrInvalidPassword: return nil, status.Error(codes.Unauthenticated, "invalid password") case seal.ErrRateLimited: return nil, status.Error(codes.ResourceExhausted, "too many attempts, try again later") case seal.ErrNotSealed: return nil, status.Error(codes.FailedPrecondition, "already unsealed") default: ss.s.logger.Error("grpc: unseal failed", "error", err) return nil, status.Error(codes.Internal, "unseal failed") } } if err := ss.s.engines.UnsealAll(ctx); err != nil { ss.s.logger.Error("grpc: engine unseal failed", "error", err) return nil, status.Error(codes.Internal, "engine unseal failed") } return &pb.UnsealResponse{State: ss.s.sealMgr.State().String()}, nil } func (ss *systemServer) Seal(_ context.Context, _ *pb.SealRequest) (*pb.SealResponse, error) { if err := ss.s.engines.SealAll(); err != nil { ss.s.logger.Error("grpc: seal engines failed", "error", err) } if err := ss.s.sealMgr.Seal(); err != nil { ss.s.logger.Error("grpc: seal failed", "error", err) return nil, status.Error(codes.Internal, "seal failed") } ss.s.auth.ClearCache() return &pb.SealResponse{State: ss.s.sealMgr.State().String()}, nil }