UNPKG

8.54 kBtext/x-cView Raw
1/*
2Copyright (c) 2011,2013 Roger Light <roger@atchoo.org>
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
81. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
102. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
133. Neither the name of mosquitto nor the names of its
14 contributors may be used to endorse or promote products derived from
15 this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <config.h>
31
32#include <stdio.h>
33#include <string.h>
34
35#include <mosquitto_broker.h>
36#include "mosquitto_plugin.h"
37#include <memory_mosq.h>
38#include "lib_load.h"
39
40typedef int (*FUNC_auth_plugin_version)(void);
41typedef int (*FUNC_auth_plugin_init)(void **, struct mosquitto_auth_opt *, int);
42typedef int (*FUNC_auth_plugin_cleanup)(void *, struct mosquitto_auth_opt *, int);
43typedef int (*FUNC_auth_plugin_security_init)(void *, struct mosquitto_auth_opt *, int, bool);
44typedef int (*FUNC_auth_plugin_security_cleanup)(void *, struct mosquitto_auth_opt *, int, bool);
45typedef int (*FUNC_auth_plugin_acl_check)(void *, const char *, const char *, const char *, int);
46typedef int (*FUNC_auth_plugin_unpwd_check)(void *, const char *, const char *);
47typedef int (*FUNC_auth_plugin_psk_key_get)(void *, const char *, const char *, char *, int);
48
49int mosquitto_security_module_init(struct mosquitto_db *db)
50{
51 void *lib;
52 int (*plugin_version)(void) = NULL;
53 int version;
54 int rc;
55 if(db->config->auth_plugin){
56 lib = LIB_LOAD(db->config->auth_plugin);
57 if(!lib){
58 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
59 "Error: Unable to load auth plugin \"%s\".", db->config->auth_plugin);
60 return 1;
61 }
62
63 db->auth_plugin.lib = NULL;
64 if(!(plugin_version = (FUNC_auth_plugin_version)LIB_SYM(lib, "mosquitto_auth_plugin_version"))){
65 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
66 "Error: Unable to load auth plugin function mosquitto_auth_plugin_version().");
67 LIB_CLOSE(lib);
68 return 1;
69 }
70 version = plugin_version();
71 if(version != MOSQ_AUTH_PLUGIN_VERSION){
72 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
73 "Error: Incorrect auth plugin version (got %d, expected %d).",
74 version, MOSQ_AUTH_PLUGIN_VERSION);
75
76 LIB_CLOSE(lib);
77 return 1;
78 }
79 if(!(db->auth_plugin.plugin_init = (FUNC_auth_plugin_init)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
80 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
81 "Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
82 LIB_CLOSE(lib);
83 return 1;
84 }
85 if(!(db->auth_plugin.plugin_cleanup = (FUNC_auth_plugin_cleanup)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
86 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
87 "Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
88 LIB_CLOSE(lib);
89 return 1;
90 }
91
92 if(!(db->auth_plugin.security_init = (FUNC_auth_plugin_security_init)LIB_SYM(lib, "mosquitto_auth_security_init"))){
93 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
94 "Error: Unable to load auth plugin function mosquitto_auth_security_init().");
95 LIB_CLOSE(lib);
96 return 1;
97 }
98
99 if(!(db->auth_plugin.security_cleanup = (FUNC_auth_plugin_security_cleanup)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
100 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
101 "Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
102 LIB_CLOSE(lib);
103 return 1;
104 }
105
106 if(!(db->auth_plugin.acl_check = (FUNC_auth_plugin_acl_check)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
107 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
108 "Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
109 LIB_CLOSE(lib);
110 return 1;
111 }
112
113 if(!(db->auth_plugin.unpwd_check = (FUNC_auth_plugin_unpwd_check)LIB_SYM(lib, "mosquitto_auth_unpwd_check"))){
114 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
115 "Error: Unable to load auth plugin function mosquitto_auth_unpwd_check().");
116 LIB_CLOSE(lib);
117 return 1;
118 }
119
120 if(!(db->auth_plugin.psk_key_get = (FUNC_auth_plugin_psk_key_get)LIB_SYM(lib, "mosquitto_auth_psk_key_get"))){
121 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
122 "Error: Unable to load auth plugin function mosquitto_auth_psk_key_get().");
123 LIB_CLOSE(lib);
124 return 1;
125 }
126
127 db->auth_plugin.lib = lib;
128 db->auth_plugin.user_data = NULL;
129 if(db->auth_plugin.plugin_init){
130 rc = db->auth_plugin.plugin_init(&db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count);
131 if(rc){
132 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR,
133 "Error: Authentication plugin returned %d when initialising.", rc);
134 }
135 return rc;
136 }
137 }else{
138 db->auth_plugin.lib = NULL;
139 db->auth_plugin.plugin_init = NULL;
140 db->auth_plugin.plugin_cleanup = NULL;
141 db->auth_plugin.security_init = NULL;
142 db->auth_plugin.security_cleanup = NULL;
143 db->auth_plugin.acl_check = NULL;
144 db->auth_plugin.unpwd_check = NULL;
145 db->auth_plugin.psk_key_get = NULL;
146 }
147
148 return MOSQ_ERR_SUCCESS;
149}
150
151int mosquitto_security_module_cleanup(struct mosquitto_db *db)
152{
153 mosquitto_security_cleanup(db, false);
154
155 if(db->auth_plugin.plugin_cleanup){
156 db->auth_plugin.plugin_cleanup(db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count);
157 }
158
159 if(db->config->auth_plugin){
160 if(db->auth_plugin.lib){
161 LIB_CLOSE(db->auth_plugin.lib);
162 }
163 }
164 db->auth_plugin.lib = NULL;
165 db->auth_plugin.plugin_init = NULL;
166 db->auth_plugin.plugin_cleanup = NULL;
167 db->auth_plugin.security_init = NULL;
168 db->auth_plugin.security_cleanup = NULL;
169 db->auth_plugin.acl_check = NULL;
170 db->auth_plugin.unpwd_check = NULL;
171 db->auth_plugin.psk_key_get = NULL;
172
173 return MOSQ_ERR_SUCCESS;
174}
175
176int mosquitto_security_init(struct mosquitto_db *db, bool reload)
177{
178 if(!db->auth_plugin.lib){
179 return mosquitto_security_init_default(db, reload);
180 }else{
181 return db->auth_plugin.security_init(db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count, reload);
182 }
183}
184
185/* Apply security settings after a reload.
186 * Includes:
187 * - Disconnecting anonymous users if appropriate
188 * - Disconnecting users with invalid passwords
189 * - Reapplying ACLs
190 */
191int mosquitto_security_apply(struct mosquitto_db *db)
192{
193 if(!db->auth_plugin.lib){
194 return mosquitto_security_apply_default(db);
195 }
196 return MOSQ_ERR_SUCCESS;
197}
198
199int mosquitto_security_cleanup(struct mosquitto_db *db, bool reload)
200{
201 if(!db->auth_plugin.lib){
202 return mosquitto_security_cleanup_default(db, reload);
203 }else{
204 return db->auth_plugin.security_cleanup(db->auth_plugin.user_data, db->config->auth_options, db->config->auth_option_count, reload);
205 }
206}
207
208int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, const char *topic, int access)
209{
210 if(!db->auth_plugin.lib){
211 return mosquitto_acl_check_default(db, context, topic, access);
212 }else{
213 return db->auth_plugin.acl_check(db->auth_plugin.user_data, context->id, context->username, topic, access);
214 }
215}
216
217int mosquitto_unpwd_check(struct mosquitto_db *db, const char *username, const char *password)
218{
219 if(!db->auth_plugin.lib){
220 return mosquitto_unpwd_check_default(db, username, password);
221 }else{
222 return db->auth_plugin.unpwd_check(db->auth_plugin.user_data, username, password);
223 }
224}
225
226int mosquitto_psk_key_get(struct mosquitto_db *db, const char *hint, const char *identity, char *key, int max_key_len)
227{
228 if(!db->auth_plugin.lib){
229 return mosquitto_psk_key_get_default(db, hint, identity, key, max_key_len);
230 }else{
231 return db->auth_plugin.psk_key_get(db->auth_plugin.user_data, hint, identity, key, max_key_len);
232 }
233}
234