Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[issue-328]: Add option to use clientid instead of username when running checks. #329

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,19 @@ auth_opt_backends files, postgres, jwt

Set all other plugin options below in the same file.

#### Using clientid as username

You may choose to override chedk against `username` to be done against `clientid` by setting this option:

```
auth_opt_use_clientid_as_username true
```

Notice this will effectively change `username` to be the same as `clientid` at the top level, so every check,
including cached ones, will drop Mosquitto's passed `username` and use `clientid` instead.

This option default to false if not given or anything but `true` is set to its value.

#### Cache

There are 2 types of caches supported: an in memory one using [go-cache](https://github.com/patrickmn/go-cache), or a Redis backed one.
Expand Down
8 changes: 4 additions & 4 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (s *goStore) CheckAuthRecord(ctx context.Context, username, password string
return s.checkRecord(ctx, record, expirationWithJitter(s.authExpiration, s.authJitter))
}

//CheckAclCache checks if the username/topic/clientid/acc mix is present in the cache. Return if it's present and, if so, if it was granted privileges.
// CheckAclCache checks if the username/topic/clientid/acc mix is present in the cache. Return if it's present and, if so, if it was granted privileges.
func (s *goStore) CheckACLRecord(ctx context.Context, username, topic, clientid string, acc int) (bool, bool) {
record := toACLRecord(username, topic, clientid, acc, s.h)
return s.checkRecord(ctx, record, expirationWithJitter(s.aclExpiration, s.aclJitter))
Expand Down Expand Up @@ -211,7 +211,7 @@ func (s *redisStore) CheckAuthRecord(ctx context.Context, username, password str
return s.checkRecord(ctx, record, s.authExpiration)
}

//CheckAclCache checks if the username/topic/clientid/acc mix is present in the cache. Return if it's present and, if so, if it was granted privileges.
// CheckAclCache checks if the username/topic/clientid/acc mix is present in the cache. Return if it's present and, if so, if it was granted privileges.
func (s *redisStore) CheckACLRecord(ctx context.Context, username, topic, clientid string, acc int) (bool, bool) {
record := toACLRecord(username, topic, clientid, acc, s.h)
return s.checkRecord(ctx, record, s.aclExpiration)
Expand Down Expand Up @@ -266,7 +266,7 @@ func (s *goStore) SetAuthRecord(ctx context.Context, username, password string,
return nil
}

//SetAclCache sets a mix, granted option and expiration time.
// SetAclCache sets a mix, granted option and expiration time.
func (s *goStore) SetACLRecord(ctx context.Context, username, topic, clientid string, acc int, granted string) error {
record := toACLRecord(username, topic, clientid, acc, s.h)
s.client.Set(record, granted, expirationWithJitter(s.aclExpiration, s.aclJitter))
Expand All @@ -280,7 +280,7 @@ func (s *redisStore) SetAuthRecord(ctx context.Context, username, password strin
return s.setRecord(ctx, record, granted, expirationWithJitter(s.authExpiration, s.authJitter))
}

//SetAclCache sets a mix, granted option and expiration time.
// SetAclCache sets a mix, granted option and expiration time.
func (s *redisStore) SetACLRecord(ctx context.Context, username, topic, clientid string, acc int, granted string) error {
record := toACLRecord(username, topic, clientid, acc, s.h)
return s.setRecord(ctx, record, granted, expirationWithJitter(s.aclExpiration, s.aclJitter))
Expand Down
40 changes: 31 additions & 9 deletions go-auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ import (
)

type AuthPlugin struct {
backends *bes.Backends
useCache bool
logLevel log.Level
logDest string
logFile string
ctx context.Context
cache cache.Store
hasher hashing.HashComparer
retryCount int
backends *bes.Backends
useCache bool
logLevel log.Level
logDest string
logFile string
ctx context.Context
cache cache.Store
hasher hashing.HashComparer
retryCount int
useClientidAsUsername bool
}

// errors to signal mosquitto
Expand Down Expand Up @@ -63,6 +64,13 @@ func AuthPluginInit(keys []*C.char, values []*C.char, authOptsNum int, version *
}
}

if useClientidAsUsername, ok := authOpts["use_clientid_as_username"]; ok && strings.Replace(useClientidAsUsername, " ", "", -1) == "true" {
log.Info("clientid will be used as username on checks")
authPlugin.useClientidAsUsername = true
} else {
authPlugin.useClientidAsUsername = false
}

//Check if log level is given. Set level if any valid option is given.
if logLevel, ok := authOpts["log_level"]; ok {
logLevel = strings.Replace(logLevel, " ", "", -1)
Expand Down Expand Up @@ -304,6 +312,9 @@ func authUnpwdCheck(username, password, clientid string) (bool, error) {
var cached bool
var granted bool
var err error

username = setUsername(username, clientid)

if authPlugin.useCache {
log.Debugf("checking auth cache for %s", username)
cached, granted = authPlugin.cache.CheckAuthRecord(authPlugin.ctx, username, password)
Expand Down Expand Up @@ -358,6 +369,9 @@ func authAclCheck(clientid, username, topic string, acc int) (bool, error) {
var cached bool
var granted bool
var err error

username = setUsername(username, clientid)

if authPlugin.useCache {
log.Debugf("checking acl cache for %s", username)
cached, granted = authPlugin.cache.CheckACLRecord(authPlugin.ctx, username, topic, clientid, acc)
Expand Down Expand Up @@ -401,4 +415,12 @@ func AuthPluginCleanup() {
authPlugin.backends.Halt()
}

func setUsername(username, clientid string) string {
if authPlugin.useClientidAsUsername {
return clientid
}

return username
}

func main() {}
Loading