Verify certificate when authenticating

This commit is contained in:
Torjus Håkestad 2021-12-06 18:04:51 +01:00
parent feb76ff890
commit 79b80772c7
2 changed files with 17 additions and 4 deletions

View File

@ -136,7 +136,7 @@ func ActionServe(c *cli.Context) error {
grpcServer := grpc.NewServer( grpcServer := grpc.NewServer(
grpc.Creds(creds), grpc.Creds(creds),
grpc.ChainUnaryInterceptor(interceptors.NewAuthInterceptor(userStore, authLogger)), grpc.ChainUnaryInterceptor(interceptors.NewAuthInterceptor(userStore, certSvc, authLogger)),
) )
pb.RegisterFileServiceServer(grpcServer, grpcFileServer) pb.RegisterFileServiceServer(grpcServer, grpcFileServer)
pb.RegisterUserServiceServer(grpcServer, grpcUserServer) pb.RegisterUserServiceServer(grpcServer, grpcUserServer)

View File

@ -3,12 +3,15 @@ package interceptors
import ( import (
"context" "context"
"gitea.benny.dog/torjus/ezshare/certs"
"gitea.benny.dog/torjus/ezshare/pb" "gitea.benny.dog/torjus/ezshare/pb"
"gitea.benny.dog/torjus/ezshare/store" "gitea.benny.dog/torjus/ezshare/store"
"go.uber.org/zap" "go.uber.org/zap"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/peer" "google.golang.org/grpc/peer"
"google.golang.org/grpc/status"
) )
type ContextKey string type ContextKey string
@ -16,9 +19,14 @@ type ContextKey string
var ContextKeyRole ContextKey = "role" var ContextKeyRole ContextKey = "role"
var ContextKeyUserID ContextKey = "userid" var ContextKeyUserID ContextKey = "userid"
func NewAuthInterceptor(s store.UserStore, logger *zap.SugaredLogger) grpc.UnaryServerInterceptor { func NewAuthInterceptor(s store.UserStore, certSvc *certs.CertService, logger *zap.SugaredLogger) grpc.UnaryServerInterceptor {
// TODO: Verify that cert is signed by our ca // TODO: Verify that cert is signed by our ca
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
// Login doesn't need valid cert
if info.FullMethod == "/ezshare.UserService/Login" {
return handler(ctx, req)
}
p, ok := peer.FromContext(ctx) p, ok := peer.FromContext(ctx)
if ok { if ok {
tlsInfo, ok := p.AuthInfo.(credentials.TLSInfo) tlsInfo, ok := p.AuthInfo.(credentials.TLSInfo)
@ -26,13 +34,18 @@ func NewAuthInterceptor(s store.UserStore, logger *zap.SugaredLogger) grpc.Unary
if len(tlsInfo.State.PeerCertificates) == 1 { if len(tlsInfo.State.PeerCertificates) == 1 {
cert := tlsInfo.State.PeerCertificates[0] cert := tlsInfo.State.PeerCertificates[0]
id := cert.Subject.CommonName // Check if valid
id, err := certSvc.VerifyClient(cert.Raw)
if err != nil {
logger.Infow("Rejected client due to invalid cert", "error", "err", "remote_addr", p.Addr.String(), "method", info.FullMethod)
return nil, status.Error(codes.Unauthenticated, "invalid client certificate")
}
user, err := s.GetUser(id) user, err := s.GetUser(id)
if err == nil { if err == nil {
newCtx := context.WithValue(ctx, ContextKeyRole, user.UserRole) newCtx := context.WithValue(ctx, ContextKeyRole, user.UserRole)
newCtx = context.WithValue(newCtx, ContextKeyUserID, user.Id) newCtx = context.WithValue(newCtx, ContextKeyUserID, user.Id)
logger.Debugw("Authenticated user.", "username", user.Username, "role", user.UserRole.String()) logger.Debugw("Authenticated user.", "username", user.Username, "role", user.UserRole.String(), "method", info.FullMethod)
return handler(newCtx, req) return handler(newCtx, req)
} }
} }