Skip to content

Commit

Permalink
initial impl skeleton for acl
Browse files Browse the repository at this point in the history
  • Loading branch information
dkhalife committed Dec 29, 2024
1 parent c437fbe commit 498a226
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 2 deletions.
9 changes: 9 additions & 0 deletions src/backends/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ class IBackend
* @return True if the reload was successful
*/
virtual bool reload(const std::map<std::string, std::string>& options) = 0;

/**
* Checks if a client has access to a topic
* @param client_id The id associated with the mosquitto client making the connection
* @param topic The topic the client is trying to access
* @param access The access level requested
* @return True if the client should be granted access by the broker
*/
virtual bool checkAcl(const std::string& client_id, const std::string& topic, int access) = 0;
};

/**
Expand Down
5 changes: 5 additions & 0 deletions src/backends/file/be_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,8 @@ bool BE_File::reload(const std::map<std::string, std::string>& options)
{
return initialize(options);
}

bool BE_File::checkAcl(const std::string& /*client_id*/, const std::string& /*topic*/, int /*access*/)
{
return false;
}
9 changes: 9 additions & 0 deletions src/backends/file/be_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ class BE_File: public IBackend
*/
bool reload(const std::map<std::string, std::string>& options);

/**
* Checks if a client has access to a topic
* @param client_id The id associated with the mosquitto client making the connection
* @param topic The topic the client is trying to access
* @param access The access level requested
* @return True if the client should be granted access by the broker
*/
bool checkAcl(const std::string& client_id, const std::string& topic, int access);

/**
* Identifier to use in the broker configuration to use a file-backed list
* of credentials
Expand Down
5 changes: 5 additions & 0 deletions src/backends/http/be_http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,8 @@ bool BE_Http::reload(const std::map<std::string, std::string>& options)

return true;
}

bool BE_Http::checkAcl(const std::string& /*client_id*/, const std::string& /*topic*/, int /*access*/)
{
return false;
}
9 changes: 9 additions & 0 deletions src/backends/http/be_http.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ class BE_Http: public IBackend
*/
bool reload(const std::map<std::string, std::string>& options);

/**
* Checks if a client has access to a topic
* @param client_id The id associated with the mosquitto client making the connection
* @param topic The topic the client is trying to access
* @param access The access level requested
* @return True if the client should be granted access by the broker
*/
bool checkAcl(const std::string& client_id, const std::string& topic, int access);

/**
* Identifier to use in the broker configuration to connect to an Http backend
*/
Expand Down
5 changes: 5 additions & 0 deletions src/backends/mysql/be_mysql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ bool BE_Mysql::reload(const std::map<std::string, std::string>& options)
{
return true;
}

bool BE_Mysql::checkAcl(const std::string& /*client_id*/, const std::string& /*topic*/, int /*access*/)
{
return false;
}
9 changes: 9 additions & 0 deletions src/backends/mysql/be_mysql.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ class BE_Mysql: public IBackend
*/
bool reload(const std::map<std::string, std::string>& options);

/**
* Checks if a client has access to a topic
* @param client_id The id associated with the mosquitto client making the connection
* @param topic The topic the client is trying to access
* @param access The access level requested
* @return True if the client should be granted access by the broker
*/
bool checkAcl(const std::string& client_id, const std::string& topic, int access);

/**
* Identifier to use in the broker configuration to connect to a MySQL service
*/
Expand Down
5 changes: 5 additions & 0 deletions src/backends/sqlite/be_sqlite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ bool BE_Sqlite::reload(const std::map<std::string, std::string>& options)
{
return true;
}

bool BE_Sqlite::checkAcl(const std::string& /*client_id*/, const std::string& /*topic*/, int /*access*/)
{
return false;
}
9 changes: 9 additions & 0 deletions src/backends/sqlite/be_sqlite.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ class BE_Sqlite: public IBackend
*/
bool reload(const std::map<std::string, std::string>& options);

/**
* Checks if a client has access to a topic
* @param client_id The id associated with the mosquitto client making the connection
* @param topic The topic the client is trying to access
* @param access The access level requested
* @return True if the client should be granted access by the broker
*/
bool checkAcl(const std::string& client_id, const std::string& topic, int access);

/**
* Identifier to use in the broker configuration to connect to a SQLite database
*/
Expand Down
36 changes: 34 additions & 2 deletions src/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ void Plugin::registerEvents() noexcept
{
mosquitto_log_printf(MOSQ_LOG_ERR, "*** auth-plugin: unable to register for basic auth events, hr = %s", hr);
}

hr = mosquitto_callback_register(m_identifier, MOSQ_EVT_ACL_CHECK, Plugin::onEvent, nullptr, this);
if (hr != MOSQ_ERR_SUCCESS)
{
mosquitto_log_printf(MOSQ_LOG_ERR, "*** auth-plugin: unable to register for ACL check events, hr = %s", hr);
}
}

void Plugin::unregisterEvents() noexcept
Expand All @@ -83,13 +89,19 @@ void Plugin::unregisterEvents() noexcept
{
mosquitto_log_printf(MOSQ_LOG_ERR, "*** auth-plugin: unable to unregister basic auth callback");
}

hr = mosquitto_callback_unregister(m_identifier, MOSQ_EVT_ACL_CHECK, Plugin::onEvent, nullptr);
if (hr != MOSQ_ERR_SUCCESS)
{
mosquitto_log_printf(MOSQ_LOG_ERR, "*** auth-plugin: unable to unregister ACL check callback");
}
}

int Plugin::onEvent(int event_id, void* event_data, void* user_data) noexcept
{
Plugin* self = reinterpret_cast<Plugin*>(user_data);

if (event_id == MOSQ_EVT_BASIC_AUTH)
if (event_id == MOSQ_EVT_RELOAD)
{
mosquitto_log_printf(MOSQ_LOG_DEBUG, "*** auth-plugin: received a reload event");
mosquitto_evt_reload* ed = reinterpret_cast<mosquitto_evt_reload*>(event_data);
Expand All @@ -98,9 +110,15 @@ int Plugin::onEvent(int event_id, void* event_data, void* user_data) noexcept
else if (event_id == MOSQ_EVT_BASIC_AUTH)
{
mosquitto_log_printf(MOSQ_LOG_DEBUG, "*** auth-plugin: received a basic auth event");
mosquitto_evt_basic_auth* ed = reinterpret_cast<mosquitto_evt_basic_auth*>(event_data);
mosquitto_evt_basic_auth* ed = reinterpret_cast<mosquitto_evt_basic_auth*>(event_data);
return self->onBasicAuth(*ed);
}
else if (event_id == MOSQ_EVT_ACL_CHECK)
{
mosquitto_log_printf(MOSQ_LOG_DEBUG, "*** auth-plugin: received an ACL check event");
mosquitto_evt_acl_check* ed = reinterpret_cast<mosquitto_evt_acl_check*>(event_data);
return self->onAclCheck(*ed);
}
else
{
mosquitto_log_printf(MOSQ_LOG_ERR, "*** auth-plugin: received an unexpected event, event_id = %i", event_id);
Expand All @@ -110,6 +128,20 @@ int Plugin::onEvent(int event_id, void* event_data, void* user_data) noexcept
return MOSQ_ERR_SUCCESS;
}

int Plugin::onAclCheck(const mosquitto_evt_acl_check& event_data) noexcept
{
for (auto& backend: m_backends)
{
std::string client_id = mosquitto_client_id(event_data.client);
if (backend->checkAcl(client_id, event_data.topic, event_data.access))
{
return MOSQ_ERR_SUCCESS;
}
}

return MOSQ_ERR_ACL_DENIED;
}

int Plugin::onBasicAuth(const mosquitto_evt_basic_auth& event_data) noexcept
{
for (auto& backend: m_backends)
Expand Down
7 changes: 7 additions & 0 deletions src/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ class Plugin
*/
int onReload(const mosquitto_evt_reload& event_data) noexcept;

/**
* Handles the ACL check event by allowing each registered backend to check if a client has access to a
* @param event_data The raw data packet sent from the broker
* @return MOSQ_ERR_SUCCESS for successful access, MOSQ_ERR_ACL_DENIED otherwise
*/
int onAclCheck(const mosquitto_evt_acl_check& event_data) noexcept;

/**
* Handles the broker events by dispatching them to the appropriate event handler
* @param event_id The event id
Expand Down

0 comments on commit 498a226

Please sign in to comment.