mosquitto/src/security.c

258 lines
8.0 KiB
C
Raw Normal View History

2014-05-07 22:27:00 +00:00
/*
Copyright (c) 2011-2015 Roger Light <roger@atchoo.org>
2014-05-07 22:27:00 +00:00
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
2015-04-29 20:37:47 +00:00
#include "config.h"
2014-05-07 22:27:00 +00:00
#include <stdio.h>
#include <string.h>
2015-04-29 20:37:47 +00:00
#include "mosquitto_broker.h"
2014-05-07 22:27:00 +00:00
#include "mosquitto_plugin.h"
2015-04-29 20:37:47 +00:00
#include "memory_mosq.h"
2014-05-07 22:27:00 +00:00
#include "lib_load.h"
typedef int (*FUNC_auth_plugin_version)(void);
typedef int (*FUNC_auth_plugin_init)(void **, struct mosquitto_auth_opt *, int);
typedef int (*FUNC_auth_plugin_cleanup)(void *, struct mosquitto_auth_opt *, int);
typedef int (*FUNC_auth_plugin_security_init)(void *, struct mosquitto_auth_opt *, int, bool);
typedef int (*FUNC_auth_plugin_security_cleanup)(void *, struct mosquitto_auth_opt *, int, bool);
typedef int (*FUNC_auth_plugin_acl_check)(void *, const char *, const char *, const char *, int);
typedef int (*FUNC_auth_plugin_unpwd_check)(void *, const char *, const char *);
typedef int (*FUNC_auth_plugin_psk_key_get)(void *, const char *, const char *, char *, int);
void LIB_ERROR(void)
{
#ifdef WIN32
char *buf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
NULL, GetLastError(), LANG_NEUTRAL, &buf, 0, NULL);
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Load error: %s", buf);
LocalFree(buf);
#else
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Load error: %s", dlerror());
#endif
}
2014-05-07 22:27:00 +00:00
int mosquitto_security_module_init(struct mosquitto_db *db)
{
void *lib;
int (*plugin_version)(void) = NULL;
int version;
int rc;
if(db->config->auth_plugin){
lib = LIB_LOAD(db->config->auth_plugin);
if(!lib){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin \"%s\".", db->config->auth_plugin);
LIB_ERROR();
2014-05-07 22:27:00 +00:00
return 1;
}
db->auth_plugin.lib = NULL;
if(!(plugin_version = (FUNC_auth_plugin_version)LIB_SYM(lib, "mosquitto_auth_plugin_version"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_plugin_version().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
version = plugin_version();
if(version != MOSQ_AUTH_PLUGIN_VERSION){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Incorrect auth plugin version (got %d, expected %d).",
version, MOSQ_AUTH_PLUGIN_VERSION);
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
if(!(db->auth_plugin.plugin_init = (FUNC_auth_plugin_init)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
if(!(db->auth_plugin.plugin_cleanup = (FUNC_auth_plugin_cleanup)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
if(!(db->auth_plugin.security_init = (FUNC_auth_plugin_security_init)LIB_SYM(lib, "mosquitto_auth_security_init"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_security_init().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
if(!(db->auth_plugin.security_cleanup = (FUNC_auth_plugin_security_cleanup)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
if(!(db->auth_plugin.acl_check = (FUNC_auth_plugin_acl_check)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
if(!(db->auth_plugin.unpwd_check = (FUNC_auth_plugin_unpwd_check)LIB_SYM(lib, "mosquitto_auth_unpwd_check"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_unpwd_check().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
if(!(db->auth_plugin.psk_key_get = (FUNC_auth_plugin_psk_key_get)LIB_SYM(lib, "mosquitto_auth_psk_key_get"))){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Unable to load auth plugin function mosquitto_auth_psk_key_get().");
LIB_ERROR();
2014-05-07 22:27:00 +00:00
LIB_CLOSE(lib);
return 1;
}
db->auth_plugin.lib = lib;
db->auth_plugin.user_data = NULL;
if(db->auth_plugin.plugin_init){
rc = db->auth_plugin.plugin_init(&db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count);
if(rc){
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR,
2014-05-07 22:27:00 +00:00
"Error: Authentication plugin returned %d when initialising.", rc);
}
return rc;
}
}else{
db->auth_plugin.lib = NULL;
db->auth_plugin.plugin_init = NULL;
db->auth_plugin.plugin_cleanup = NULL;
db->auth_plugin.security_init = NULL;
db->auth_plugin.security_cleanup = NULL;
db->auth_plugin.acl_check = NULL;
db->auth_plugin.unpwd_check = NULL;
db->auth_plugin.psk_key_get = NULL;
}
return MOSQ_ERR_SUCCESS;
}
int mosquitto_security_module_cleanup(struct mosquitto_db *db)
{
mosquitto_security_cleanup(db, false);
if(db->auth_plugin.plugin_cleanup){
db->auth_plugin.plugin_cleanup(db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count);
}
if(db->config->auth_plugin){
if(db->auth_plugin.lib){
LIB_CLOSE(db->auth_plugin.lib);
}
}
db->auth_plugin.lib = NULL;
db->auth_plugin.plugin_init = NULL;
db->auth_plugin.plugin_cleanup = NULL;
db->auth_plugin.security_init = NULL;
db->auth_plugin.security_cleanup = NULL;
db->auth_plugin.acl_check = NULL;
db->auth_plugin.unpwd_check = NULL;
db->auth_plugin.psk_key_get = NULL;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_security_init(struct mosquitto_db *db, bool reload)
{
if(!db->auth_plugin.lib){
return mosquitto_security_init_default(db, reload);
}else{
return db->auth_plugin.security_init(db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count, reload);
}
}
/* Apply security settings after a reload.
* Includes:
* - Disconnecting anonymous users if appropriate
* - Disconnecting users with invalid passwords
* - Reapplying ACLs
*/
int mosquitto_security_apply(struct mosquitto_db *db)
{
if(!db->auth_plugin.lib){
return mosquitto_security_apply_default(db);
}
return MOSQ_ERR_SUCCESS;
}
int mosquitto_security_cleanup(struct mosquitto_db *db, bool reload)
{
if(!db->auth_plugin.lib){
return mosquitto_security_cleanup_default(db, reload);
}else{
return db->auth_plugin.security_cleanup(db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count, reload);
}
}
int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, const char *topic, int access)
{
char *username;
2014-07-08 22:07:19 +00:00
if(!context->id){
return MOSQ_ERR_ACL_DENIED;
}
2014-05-07 22:27:00 +00:00
if(!db->auth_plugin.lib){
return mosquitto_acl_check_default(db, context, topic, access);
}else{
#ifdef WITH_BRIDGE
if(context->bridge){
username = context->bridge->local_username;
}else
#endif
{
username = context->username;
}
return db->auth_plugin.acl_check(db->auth_plugin.user_data, context->id, username, topic, access);
2014-05-07 22:27:00 +00:00
}
}
int mosquitto_unpwd_check(struct mosquitto_db *db, const char *username, const char *password)
{
if(!db->auth_plugin.lib){
return mosquitto_unpwd_check_default(db, username, password);
}else{
return db->auth_plugin.unpwd_check(db->auth_plugin.user_data, username, password);
}
}
int mosquitto_psk_key_get(struct mosquitto_db *db, const char *hint, const char *identity, char *key, int max_key_len)
{
if(!db->auth_plugin.lib){
return mosquitto_psk_key_get_default(db, hint, identity, key, max_key_len);
}else{
return db->auth_plugin.psk_key_get(db->auth_plugin.user_data, hint, identity, key, max_key_len);
}
}