mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-09 01:49:40 -10:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3429f5f88 | ||
|
|
04d8d2aac7 | ||
|
|
b71759f3b2 | ||
|
|
13c68a7f50 | ||
|
|
1f894f50ff | ||
|
|
33ea66de58 | ||
|
|
9a432f583d | ||
|
|
cbcd948c83 | ||
|
|
2ada8bf8ed |
No files matched your search
+44
-1
@@ -1,3 +1,12 @@
|
||||
#
|
||||
# For production:
|
||||
# docker build --target production -t sliver .
|
||||
# docker run -it --rm -v $HOME/.sliver:/home/sliver/.sliver sliver
|
||||
#
|
||||
# For unit testing:
|
||||
# docker build --target test .
|
||||
#
|
||||
|
||||
# STAGE: base
|
||||
## Compiles Sliver for use
|
||||
FROM --platform=linux/amd64 golang:1.21.4 as base
|
||||
@@ -25,7 +34,7 @@ FROM --platform=linux/amd64 base as test
|
||||
RUN apt-get update --fix-missing \
|
||||
&& apt-get -y upgrade \
|
||||
&& apt-get -y install \
|
||||
curl mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
curl gcc-multilib build-essential mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
|
||||
RUN /opt/sliver-server unpack --force
|
||||
|
||||
@@ -80,3 +89,37 @@ RUN /opt/sliver-server unpack --force
|
||||
WORKDIR /home/sliver/
|
||||
VOLUME [ "/home/sliver/.sliver" ]
|
||||
ENTRYPOINT [ "/opt/sliver-server" ]
|
||||
|
||||
|
||||
# STAGE: production-slim (about 1Gb smaller)
|
||||
### Slim production image, i.e. without MSF and assoicated libraries
|
||||
### Still include GCC and MinGW for cross-platform generation
|
||||
FROM --platform=linux/amd64 debian:bookworm-slim as production-slim
|
||||
|
||||
### Install production packages
|
||||
RUN apt-get update --fix-missing \
|
||||
&& apt-get -y upgrade \
|
||||
&& apt-get -y install \
|
||||
build-essential mingw-w64 binutils-mingw-w64 g++-mingw-w64 gcc-multilib
|
||||
|
||||
### Cleanup unneeded packages
|
||||
RUN apt-get autoremove -y \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
### Add sliver user
|
||||
RUN groupadd -g 999 sliver \
|
||||
&& useradd -r -u 999 -g sliver sliver \
|
||||
&& mkdir -p /home/sliver/ \
|
||||
&& chown -R sliver:sliver /home/sliver
|
||||
|
||||
### Copy compiled binary
|
||||
COPY --from=base /opt/sliver-server /opt/sliver-server
|
||||
|
||||
### Unpack Sliver:
|
||||
USER sliver
|
||||
RUN /opt/sliver-server unpack --force
|
||||
|
||||
WORKDIR /home/sliver/
|
||||
VOLUME [ "/home/sliver/.sliver" ]
|
||||
ENTRYPOINT [ "/opt/sliver-server" ]
|
||||
+1
-1
@@ -272,7 +272,7 @@ func listenAndServeTLS(srv *http.Server, certPEMBlock, keyPEMBlock []byte) error
|
||||
}
|
||||
config := &tls.Config{}
|
||||
if srv.TLSConfig != nil {
|
||||
*config = *srv.TLSConfig
|
||||
config = srv.TLSConfig
|
||||
}
|
||||
if certs.TLSKeyLogger != nil {
|
||||
config.KeyLogWriter = certs.TLSKeyLogger
|
||||
|
||||
+5
-4
@@ -44,10 +44,11 @@ const (
|
||||
forceFlagStr = "force"
|
||||
|
||||
// Operator flags
|
||||
nameFlagStr = "name"
|
||||
lhostFlagStr = "lhost"
|
||||
lportFlagStr = "lport"
|
||||
saveFlagStr = "save"
|
||||
nameFlagStr = "name"
|
||||
lhostFlagStr = "lhost"
|
||||
lportFlagStr = "lport"
|
||||
saveFlagStr = "save"
|
||||
permissionsFlagStr = "permissions"
|
||||
|
||||
// Cert flags
|
||||
caTypeFlagStr = "type"
|
||||
|
||||
@@ -71,10 +71,10 @@ var daemonCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func StartPersistentJobs(listenerJobs *[]clientpb.ListenerJob) error {
|
||||
if len(*listenerJobs) > 0 {
|
||||
func StartPersistentJobs(listenerJobs []*clientpb.ListenerJob) error {
|
||||
if len(listenerJobs) > 0 {
|
||||
// StartPersistentJobs - Start persistent jobs
|
||||
for _, j := range *listenerJobs {
|
||||
for _, j := range listenerJobs {
|
||||
listenerJob, err := db.ListenerByJobID(j.JobID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -117,7 +117,7 @@ func StartPersistentJobs(listenerJobs *[]clientpb.ListenerJob) error {
|
||||
}
|
||||
j.JobID = uint32(id)
|
||||
}
|
||||
db.UpdateHTTPC2Listener(&j)
|
||||
db.UpdateHTTPC2Listener(j)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-11
@@ -33,54 +33,63 @@ var operatorCmd = &cobra.Command{
|
||||
Short: "Generate operator configuration files",
|
||||
Long: ``,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
name, err := cmd.Flags().GetString(nameFlagStr)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to parse --%s flag %s", nameFlagStr, err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
if name == "" {
|
||||
fmt.Printf("Must specify --%s", nameFlagStr)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
|
||||
lhost, err := cmd.Flags().GetString(lhostFlagStr)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to parse --%s flag %s", lhostFlagStr, err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
if lhost == "" {
|
||||
fmt.Printf("Must specify --%s", lhostFlagStr)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
|
||||
lport, err := cmd.Flags().GetUint16(lportFlagStr)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to parse --%s flag %s", lportFlagStr, err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
|
||||
save, err := cmd.Flags().GetString(saveFlagStr)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to parse --%s flag %s", saveFlagStr, err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
if save == "" {
|
||||
save, _ = os.Getwd()
|
||||
}
|
||||
|
||||
permissions, err := cmd.Flags().GetStringSlice(permissionsFlagStr)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to parse --%s flag %s", permissionsFlagStr, err)
|
||||
return
|
||||
}
|
||||
if len(permissions) == 0 {
|
||||
fmt.Printf("Must specify --%s", permissionsFlagStr)
|
||||
return
|
||||
}
|
||||
|
||||
certs.SetupCAs()
|
||||
configJSON, err := console.NewOperatorConfig(name, lhost, lport)
|
||||
configJSON, err := console.NewOperatorConfig(name, lhost, lport, permissions)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed: %s\n", err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
|
||||
saveTo, _ := filepath.Abs(save)
|
||||
fi, err := os.Stat(saveTo)
|
||||
if !os.IsNotExist(err) && !fi.IsDir() {
|
||||
fmt.Printf("File already exists: %s\n", err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
if !os.IsNotExist(err) && fi.IsDir() {
|
||||
filename := fmt.Sprintf("%s_%s.cfg", filepath.Base(name), filepath.Base(lhost))
|
||||
@@ -89,7 +98,7 @@ var operatorCmd = &cobra.Command{
|
||||
err = os.WriteFile(saveTo, configJSON, 0600)
|
||||
if err != nil {
|
||||
fmt.Printf("Write failed: %s (%s)\n", saveTo, err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -86,13 +85,14 @@ func newOperatorCmd(cmd *cobra.Command, _ []string) {
|
||||
lhost, _ := cmd.Flags().GetString("lhost")
|
||||
lport, _ := cmd.Flags().GetUint16("lport")
|
||||
save, _ := cmd.Flags().GetString("save")
|
||||
permissions, _ := cmd.Flags().GetStringSlice("permissions")
|
||||
|
||||
if save == "" {
|
||||
save, _ = os.Getwd()
|
||||
}
|
||||
|
||||
fmt.Printf(Info + "Generating new client certificate, please wait ... \n")
|
||||
configJSON, err := NewOperatorConfig(name, lhost, lport)
|
||||
configJSON, err := NewOperatorConfig(name, lhost, lport, permissions)
|
||||
if err != nil {
|
||||
fmt.Printf(Warn+"%s\n", err)
|
||||
return
|
||||
@@ -108,7 +108,7 @@ func newOperatorCmd(cmd *cobra.Command, _ []string) {
|
||||
filename := fmt.Sprintf("%s_%s.cfg", filepath.Base(name), filepath.Base(lhost))
|
||||
saveTo = filepath.Join(saveTo, filename)
|
||||
}
|
||||
err = ioutil.WriteFile(saveTo, configJSON, 0o600)
|
||||
err = os.WriteFile(saveTo, configJSON, 0o600)
|
||||
if err != nil {
|
||||
fmt.Printf(Warn+"Failed to write config to: %s (%s) \n", saveTo, err)
|
||||
return
|
||||
@@ -117,7 +117,7 @@ func newOperatorCmd(cmd *cobra.Command, _ []string) {
|
||||
}
|
||||
|
||||
// NewOperatorConfig - Generate a new player/client/operator configuration
|
||||
func NewOperatorConfig(operatorName string, lhost string, lport uint16) ([]byte, error) {
|
||||
func NewOperatorConfig(operatorName string, lhost string, lport uint16, permissions []string) ([]byte, error) {
|
||||
if !namePattern.MatchString(operatorName) {
|
||||
return nil, errors.New("invalid operator name (alphanumerics only)")
|
||||
}
|
||||
@@ -127,6 +127,9 @@ func NewOperatorConfig(operatorName string, lhost string, lport uint16) ([]byte,
|
||||
if lhost == "" {
|
||||
return nil, errors.New("invalid lhost")
|
||||
}
|
||||
if len(permissions) == 0 {
|
||||
return nil, errors.New("must specify at least one permission")
|
||||
}
|
||||
|
||||
rawToken := models.GenerateOperatorToken()
|
||||
digest := sha256.Sum256([]byte(rawToken))
|
||||
@@ -134,6 +137,19 @@ func NewOperatorConfig(operatorName string, lhost string, lport uint16) ([]byte,
|
||||
Name: operatorName,
|
||||
Token: hex.EncodeToString(digest[:]),
|
||||
}
|
||||
for _, permission := range permissions {
|
||||
switch permission {
|
||||
case "all":
|
||||
dbOperator.PermissionAll = true
|
||||
break
|
||||
case "builder":
|
||||
dbOperator.PermissionBuilder = true
|
||||
case "crackstation":
|
||||
dbOperator.PermissionCrackstation = true
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid permission: %s", permission)
|
||||
}
|
||||
}
|
||||
err := db.Session().Save(dbOperator).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
func TestRootOnlyVerifyCertificate(t *testing.T) {
|
||||
certs.SetupCAs()
|
||||
|
||||
data, err := NewOperatorConfig("zerocool", "localhost", uint16(1337))
|
||||
data, err := NewOperatorConfig("zerocool", "localhost", uint16(1337), []string{"all"})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to generate test player profile %s", err)
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func serverOnlyCmds() (commands []*cobra.Command) {
|
||||
newOperator := &cobra.Command{
|
||||
Use: consts.NewOperatorStr,
|
||||
Short: "Create a new operator config file",
|
||||
Long: help.GetHelpFor([]string{consts.NewOperatorStr}),
|
||||
Long: newOperatorLongHelp,
|
||||
Run: newOperatorCmd,
|
||||
GroupID: consts.MultiplayerHelpGroup,
|
||||
}
|
||||
@@ -94,6 +94,7 @@ func serverOnlyCmds() (commands []*cobra.Command) {
|
||||
f.Uint16P("lport", "p", 31337, "listen port")
|
||||
f.StringP("save", "s", "", "directory/file in which to save config")
|
||||
f.StringP("name", "n", "", "operator name")
|
||||
f.StringSliceP("permissions", "P", []string{}, "grant permissions to the operator profile (all, builder, crackstation)")
|
||||
})
|
||||
command.FlagComps(newOperator, func(comp *carapace.ActionMap) {
|
||||
(*comp)["save"] = carapace.ActionDirectories()
|
||||
@@ -115,3 +116,23 @@ func serverOnlyCmds() (commands []*cobra.Command) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const newOperatorLongHelp = `
|
||||
Create a new operator config file, operator configuration files allow
|
||||
remote machines to connect to the Sliver server. They are most commonly
|
||||
used for allowing remote operators to connect in "Multiplayer Mode."
|
||||
|
||||
To generate a profile for a remote operator, you need to specify the
|
||||
the "all" permission to grant the profile access to all gRPC APIs:
|
||||
|
||||
new-operator --name <operator name> --lhost <sliver server> --permissions all
|
||||
|
||||
Operator profiles can also be used to allow remote machines to connect to
|
||||
the Sliver server for other purposes, such as a "Remote Builder" or a
|
||||
"Crackstation."
|
||||
|
||||
You can restrict profiles' permissions by using the --permissions flag, for
|
||||
example, to create a profile that can only be used as a "Remote Builder":
|
||||
|
||||
new-operator --name <operator name> --lhost <sliver server> --permissions builder
|
||||
`
|
||||
@@ -31,11 +31,11 @@ type ImplantConnection struct {
|
||||
ID string
|
||||
Send chan *sliverpb.Envelope
|
||||
RespMutex *sync.RWMutex
|
||||
LastMessageMutex *sync.RWMutex
|
||||
Resp map[int64]chan *sliverpb.Envelope
|
||||
Transport string
|
||||
RemoteAddress string
|
||||
LastMessage time.Time
|
||||
LastMessageMutex *sync.RWMutex
|
||||
Cleanup func()
|
||||
}
|
||||
|
||||
|
||||
@@ -525,15 +525,15 @@ func ListenerByJobID(JobID uint32) (*clientpb.ListenerJob, error) {
|
||||
return listenerJob.ToProtobuf(), err
|
||||
}
|
||||
|
||||
func ListenerJobs() (*[]clientpb.ListenerJob, error) {
|
||||
func ListenerJobs() ([]*clientpb.ListenerJob, error) {
|
||||
listenerJobs := []models.ListenerJob{}
|
||||
err := Session().Where(&models.ListenerJob{}).Find(&listenerJobs).Error
|
||||
pbListenerJobs := []clientpb.ListenerJob{}
|
||||
pbListenerJobs := []*clientpb.ListenerJob{}
|
||||
for _, listenerJob := range listenerJobs {
|
||||
pbListenerJobs = append(pbListenerJobs, *listenerJob.ToProtobuf())
|
||||
pbListenerJobs = append(pbListenerJobs, listenerJob.ToProtobuf())
|
||||
}
|
||||
|
||||
return &pbListenerJobs, err
|
||||
return pbListenerJobs, err
|
||||
}
|
||||
|
||||
func DeleteListener(JobID uint32) error {
|
||||
|
||||
@@ -28,12 +28,15 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Operator - Colletions of content to serve from HTTP(S)
|
||||
// Operator - Collections of content to serve from HTTP(S)
|
||||
type Operator struct {
|
||||
ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"`
|
||||
CreatedAt time.Time `gorm:"->;<-:create;"`
|
||||
Name string
|
||||
Token string `gorm:"uniqueIndex"`
|
||||
ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"`
|
||||
CreatedAt time.Time `gorm:"->;<-:create;"`
|
||||
Name string
|
||||
Token string `gorm:"uniqueIndex"` // NOTE: This is the SHA256 of the token
|
||||
PermissionAll bool `gorm:"default:false"` // Access all gRPC APIs
|
||||
PermissionBuilder bool `gorm:"default:false"` // Access Builder gRPC APIs
|
||||
PermissionCrackstation bool `gorm:"default:false"` // Access Crackstation gRPC APIs
|
||||
}
|
||||
|
||||
// BeforeCreate - GORM hook
|
||||
|
||||
@@ -283,7 +283,7 @@ func PortInUse(newPort uint32) error {
|
||||
return err
|
||||
}
|
||||
var port uint32
|
||||
for _, job := range *listenerJobs {
|
||||
for _, job := range listenerJobs {
|
||||
listener, err := db.ListenerByJobID(job.JobID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/bishopfox/sliver/server/configs"
|
||||
"github.com/bishopfox/sliver/server/core"
|
||||
"github.com/bishopfox/sliver/server/db"
|
||||
"github.com/bishopfox/sliver/server/db/models"
|
||||
"github.com/bishopfox/sliver/server/log"
|
||||
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
|
||||
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
|
||||
@@ -64,6 +65,7 @@ func initMiddleware(remoteAuth bool) []grpc.ServerOption {
|
||||
return []grpc.ServerOption{
|
||||
grpc.ChainUnaryInterceptor(
|
||||
grpc_auth.UnaryServerInterceptor(tokenAuthFunc),
|
||||
permissionsUnaryServerInterceptor(),
|
||||
auditLogUnaryServerInterceptor(),
|
||||
grpc_tags.UnaryServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
|
||||
grpc_logrus.UnaryServerInterceptor(logrusEntry, logrusOpts...),
|
||||
@@ -71,6 +73,7 @@ func initMiddleware(remoteAuth bool) []grpc.ServerOption {
|
||||
),
|
||||
grpc.ChainStreamInterceptor(
|
||||
grpc_auth.StreamServerInterceptor(tokenAuthFunc),
|
||||
permissionsStreamServerInterceptor(),
|
||||
grpc_tags.StreamServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
|
||||
grpc_logrus.StreamServerInterceptor(logrusEntry, logrusOpts...),
|
||||
grpc_logrus.PayloadStreamServerInterceptor(logrusEntry, deciderStream),
|
||||
@@ -123,23 +126,93 @@ func tokenAuthFunc(ctx context.Context) (context.Context, error) {
|
||||
digest := sha256.Sum256([]byte(rawToken))
|
||||
token := hex.EncodeToString(digest[:])
|
||||
newCtx := context.WithValue(ctx, Transport, "mtls")
|
||||
if name, ok := tokenCache.Load(token); ok {
|
||||
if op, ok := tokenCache.Load(token); ok {
|
||||
mtlsLog.Debugf("Token in cache!")
|
||||
newCtx = context.WithValue(newCtx, Operator, name.(string))
|
||||
newCtx = context.WithValue(newCtx, Operator, op.(*models.Operator))
|
||||
return newCtx, nil
|
||||
}
|
||||
operator, err := db.OperatorByToken(token)
|
||||
if err != nil || operator == nil {
|
||||
mtlsLog.Errorf("Authentication failure: %s", err)
|
||||
mtlsLog.Errorf("Authentication failure: %v", err)
|
||||
return nil, status.Error(codes.Unauthenticated, "Authentication failure")
|
||||
}
|
||||
mtlsLog.Debugf("Valid user token for %s", operator.Name)
|
||||
tokenCache.Store(token, operator.Name)
|
||||
mtlsLog.Debugf("Valid token for %s", operator.Name)
|
||||
tokenCache.Store(token, operator)
|
||||
|
||||
newCtx = context.WithValue(newCtx, Operator, operator.Name)
|
||||
newCtx = context.WithValue(newCtx, Operator, operator)
|
||||
return newCtx, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// Builder - Allowed methods
|
||||
builderMethods = map[string]bool{
|
||||
"/rpcpb.SliverRPC/GetVersion": true,
|
||||
"/rpcpb.SliverRPC/GenerateExternalGetBuildConfig": true,
|
||||
"/rpcpb.SliverRPC/GenerateExternalSaveBuild": true,
|
||||
"/rpcpb.SliverRPC/BuilderRegister": true,
|
||||
"/rpcpb.SliverRPC/BuilderTrigger": true,
|
||||
"/rpcpb.SliverRPC/Builders": true,
|
||||
}
|
||||
// Crackstation - Allowed methods
|
||||
crackstationMethods = map[string]bool{
|
||||
"/rpcpb.SliverRPC/GetVersion": true,
|
||||
"/rpcpb.SliverRPC/CrackstationRegister": true,
|
||||
"/rpcpb.SliverRPC/CrackstationTrigger": true,
|
||||
"/rpcpb.SliverRPC/CrackstationBenchmark": true,
|
||||
"/rpcpb.SliverRPC/Crackstations": true,
|
||||
"/rpcpb.SliverRPC/CrackTaskByID": true,
|
||||
"/rpcpb.SliverRPC/CrackTaskUpdate": true,
|
||||
"/rpcpb.SliverRPC/CrackFilesList": true,
|
||||
"/rpcpb.SliverRPC/CrackFileCreate": true,
|
||||
"/rpcpb.SliverRPC/CrackFileChunkUpload": true,
|
||||
"/rpcpb.SliverRPC/CrackFileChunkDownload": true,
|
||||
"/rpcpb.SliverRPC/CrackFileComplete": true,
|
||||
"/rpcpb.SliverRPC/CrackFileDelete": true,
|
||||
}
|
||||
)
|
||||
|
||||
func permissionsUnaryServerInterceptor() grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) {
|
||||
operator := ctx.Value(Operator).(*models.Operator)
|
||||
if operator.PermissionAll {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
if operator.PermissionBuilder {
|
||||
if ok, _ := builderMethods[info.FullMethod]; ok {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
||||
if operator.PermissionCrackstation {
|
||||
if ok, _ := crackstationMethods[info.FullMethod]; ok {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
||||
mtlsLog.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
|
||||
return nil, status.Error(codes.PermissionDenied, "Permission denied")
|
||||
}
|
||||
}
|
||||
|
||||
func permissionsStreamServerInterceptor() grpc.StreamServerInterceptor {
|
||||
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||
operator := ss.Context().Value(Operator).(*models.Operator)
|
||||
if operator.PermissionAll {
|
||||
return handler(srv, ss)
|
||||
}
|
||||
if operator.PermissionBuilder {
|
||||
if ok, _ := builderMethods[info.FullMethod]; ok {
|
||||
return handler(srv, ss)
|
||||
}
|
||||
}
|
||||
if operator.PermissionCrackstation {
|
||||
if ok, _ := crackstationMethods[info.FullMethod]; ok {
|
||||
return handler(srv, ss)
|
||||
}
|
||||
}
|
||||
mtlsLog.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
|
||||
return status.Error(codes.PermissionDenied, "Permission denied")
|
||||
}
|
||||
}
|
||||
|
||||
func deciderUnary(_ context.Context, _ string, _ interface{}) bool {
|
||||
return serverConfig.Logs.GRPCUnaryPayloads
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user