Skip to content

Commit

Permalink
Pass char* to Go and convert with C.GoString, avoiding unsafe use
Browse files Browse the repository at this point in the history
Using the char* passed by Mosquitto in a GoString struct is unsafe.
The memory it points to is managed by Mosquitto, but Go will keep the
pointer around for an indefinite duration, even when Mosquitto might
free the memory.

By passing the actual char* to Go, we can use C.GoString to convert it,
which copies the bytes into a buffer managed by Go. That way we can use
it safely at any time in the future.
  • Loading branch information
ssiegel committed Jun 11, 2023
1 parent 807e8f2 commit d74392c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 26 deletions.
26 changes: 7 additions & 19 deletions auth-plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@ int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_auth_opt *auth

GoInt32 opts_count = auth_opt_count;

GoString keys[auth_opt_count];
GoString values[auth_opt_count];
char *keys[auth_opt_count];
char *values[auth_opt_count];
int i;
struct mosquitto_auth_opt *o;
for (i = 0, o = auth_opts; i < auth_opt_count; i++, o++) {
GoString opt_key = {o->key, strlen(o->key)};
GoString opt_value = {o->value, strlen(o->value)};
keys[i] = opt_key;
values[i] = opt_value;
keys[i] = o->key;
values[i] = o->value;
}

GoSlice keysSlice = {keys, auth_opt_count, auth_opt_count};
Expand All @@ -55,9 +53,8 @@ int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_auth_opt *auth
char versionArray[10];
sprintf(versionArray, "%i.%i.%i", LIBMOSQUITTO_MAJOR, LIBMOSQUITTO_MINOR, LIBMOSQUITTO_REVISION);

GoString version = {versionArray, strlen(versionArray)};

AuthPluginInit(keysSlice, valuesSlice, opts_count, version);
AuthPluginInit(keysSlice, valuesSlice, opts_count, versionArray);
return MOSQ_ERR_SUCCESS;
}

Expand Down Expand Up @@ -93,11 +90,7 @@ int mosquitto_auth_unpwd_check(void *userdata, const char *username, const char
return MOSQ_ERR_AUTH;
}

GoString go_username = {username, strlen(username)};
GoString go_password = {password, strlen(password)};
GoString go_clientid = {clientid, strlen(clientid)};

GoUint8 ret = AuthUnpwdCheck(go_username, go_password, go_clientid);
GoUint8 ret = AuthUnpwdCheck((char *)username, (char *)password, (char *)clientid);

switch (ret)
{
Expand Down Expand Up @@ -135,12 +128,7 @@ int mosquitto_auth_acl_check(void *userdata, const char *clientid, const char *u
return MOSQ_ERR_ACL_DENIED;
}

GoString go_clientid = {clientid, strlen(clientid)};
GoString go_username = {username, strlen(username)};
GoString go_topic = {topic, strlen(topic)};
GoInt32 go_access = access;

GoUint8 ret = AuthAclCheck(go_clientid, go_username, go_topic, go_access);
GoUint8 ret = AuthAclCheck((char *)clientid, (char *)username, (char *)topic, access);

switch (ret)
{
Expand Down
14 changes: 7 additions & 7 deletions go-auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var authOpts map[string]string //Options passed by mosquitto.
var authPlugin AuthPlugin //General struct with options and conf.

//export AuthPluginInit
func AuthPluginInit(keys []string, values []string, authOptsNum int, version string) {
func AuthPluginInit(keys []*C.char, values []*C.char, authOptsNum int, version *C.char) {
log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
})
Expand All @@ -51,7 +51,7 @@ func AuthPluginInit(keys []string, values []string, authOptsNum int, version str

authOpts = make(map[string]string)
for i := 0; i < authOptsNum; i++ {
authOpts[keys[i]] = values[i]
authOpts[C.GoString(keys[i])] = C.GoString(values[i])
}

if retryCount, ok := authOpts["retry_count"]; ok {
Expand Down Expand Up @@ -104,7 +104,7 @@ func AuthPluginInit(keys []string, values []string, authOptsNum int, version str

var err error

authPlugin.backends, err = bes.Initialize(authOpts, authPlugin.logLevel, version)
authPlugin.backends, err = bes.Initialize(authOpts, authPlugin.logLevel, C.GoString(version))
if err != nil {
log.Fatalf("error initializing backends: %s", err)
}
Expand Down Expand Up @@ -276,12 +276,12 @@ func setCache(authOpts map[string]string) {
}

//export AuthUnpwdCheck
func AuthUnpwdCheck(username, password, clientid string) uint8 {
func AuthUnpwdCheck(username, password, clientid *C.char) uint8 {
var ok bool
var err error

for try := 0; try <= authPlugin.retryCount; try++ {
ok, err = authUnpwdCheck(username, password, clientid)
ok, err = authUnpwdCheck(C.GoString(username), C.GoString(password), C.GoString(clientid))
if err == nil {
break
}
Expand Down Expand Up @@ -330,12 +330,12 @@ func authUnpwdCheck(username, password, clientid string) (bool, error) {
}

//export AuthAclCheck
func AuthAclCheck(clientid, username, topic string, acc int) uint8 {
func AuthAclCheck(clientid, username, topic *C.char, acc C.int) uint8 {
var ok bool
var err error

for try := 0; try <= authPlugin.retryCount; try++ {
ok, err = authAclCheck(clientid, username, topic, acc)
ok, err = authAclCheck(C.GoString(clientid), C.GoString(username), C.GoString(topic), int(acc))
if err == nil {
break
}
Expand Down

0 comments on commit d74392c

Please sign in to comment.