1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
|
#ifndef DYNAMIC_SECURITY_H
#define DYNAMIC_SECURITY_H
/*
Copyright (c) 2020 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
https://www.eclipse.org/legal/epl-2.0/
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/
#include <cjson/cJSON.h>
#include <uthash.h>
#include "mosquitto.h"
#include "password_mosq.h"
/* ################################################################
* #
* # ACL types
* #
* ################################################################ */
#define ACL_TYPE_PUB_C_RECV "publishClientReceive"
#define ACL_TYPE_PUB_C_SEND "publishClientSend"
#define ACL_TYPE_SUB_GENERIC "subscribe"
#define ACL_TYPE_SUB_LITERAL "subscribeLiteral"
#define ACL_TYPE_SUB_PATTERN "subscribePattern"
#define ACL_TYPE_UNSUB_GENERIC "unsubscribe"
#define ACL_TYPE_UNSUB_LITERAL "unsubscribeLiteral"
#define ACL_TYPE_UNSUB_PATTERN "unsubscribePattern"
/* ################################################################
* #
* # Error codes
* #
* ################################################################ */
#define ERR_USER_NOT_FOUND 10000
#define ERR_GROUP_NOT_FOUND 10001
#define ERR_LIST_NOT_FOUND 10002
/* ################################################################
* #
* # Datatypes
* #
* ################################################################ */
struct dynsec__clientlist{
UT_hash_handle hh;
struct dynsec__client *client;
int priority;
};
struct dynsec__grouplist{
UT_hash_handle hh;
struct dynsec__group *group;
int priority;
};
struct dynsec__rolelist{
UT_hash_handle hh;
char *rolename;
struct dynsec__role *role;
int priority;
};
struct dynsec__client{
UT_hash_handle hh;
struct mosquitto_pw pw;
struct dynsec__rolelist *rolelist;
struct dynsec__grouplist *grouplist;
char *username;
char *clientid;
char *text_name;
char *text_description;
bool disabled;
};
struct dynsec__group{
UT_hash_handle hh;
struct dynsec__rolelist *rolelist;
struct dynsec__clientlist *clientlist;
char *groupname;
char *text_name;
char *text_description;
};
struct dynsec__acl{
UT_hash_handle hh;
char *topic;
int priority;
bool allow;
};
struct dynsec__acls{
struct dynsec__acl *publish_c_send;
struct dynsec__acl *publish_c_recv;
struct dynsec__acl *subscribe_literal;
struct dynsec__acl *subscribe_pattern;
struct dynsec__acl *unsubscribe_literal;
struct dynsec__acl *unsubscribe_pattern;
};
struct dynsec__role{
UT_hash_handle hh;
struct dynsec__acls acls;
struct dynsec__clientlist *clientlist;
struct dynsec__grouplist *grouplist;
char *rolename;
char *text_name;
char *text_description;
};
struct dynsec__acl_default_access{
bool publish_c_send;
bool publish_c_recv;
bool subscribe;
bool unsubscribe;
};
extern struct dynsec__group *dynsec_anonymous_group;
extern struct dynsec__acl_default_access default_access;
/* ################################################################
* #
* # Plugin Functions
* #
* ################################################################ */
void dynsec__config_save(void);
int dynsec__handle_control(cJSON *j_responses, struct mosquitto *context, cJSON *commands);
void dynsec__command_reply(cJSON *j_responses, struct mosquitto *context, const char *command, const char *error, const char *correlation_data);
/* ################################################################
* #
* # ACL Functions
* #
* ################################################################ */
int dynsec__acl_check_callback(int event, void *event_data, void *userdata);
bool sub_acl_check(const char *acl, const char *sub);
/* ################################################################
* #
* # Auth Functions
* #
* ################################################################ */
int dynsec_auth__base64_encode(unsigned char *in, int in_len, char **encoded);
int dynsec_auth__base64_decode(char *in, unsigned char **decoded, int *decoded_len);
int dynsec_auth__pw_hash(struct dynsec__client *client, const char *password, unsigned char *password_hash, int password_hash_len, bool new_password);
int dynsec_auth__basic_auth_callback(int event, void *event_data, void *userdata);
/* ################################################################
* #
* # Client Functions
* #
* ################################################################ */
void dynsec_clients__cleanup(void);
int dynsec_clients__config_load(cJSON *tree);
int dynsec_clients__config_save(cJSON *tree);
int dynsec_clients__process_add_role(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_create(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_delete(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_disable(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_enable(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_get(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_list(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_modify(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_remove_role(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_set_id(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_clients__process_set_password(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
struct dynsec__client *dynsec_clients__find(const char *username);
/* ################################################################
* #
* # Client List Functions
* #
* ################################################################ */
cJSON *dynsec_clientlist__all_to_json(struct dynsec__clientlist *base_clientlist);
int dynsec_clientlist__add(struct dynsec__clientlist **base_clientlist, struct dynsec__client *client, int priority);
void dynsec_clientlist__cleanup(struct dynsec__clientlist **base_clientlist);
void dynsec_clientlist__remove(struct dynsec__clientlist **base_clientlist, struct dynsec__client *client);
void dynsec_clientlist__kick_all(struct dynsec__clientlist *base_clientlist);
/* ################################################################
* #
* # Group Functions
* #
* ################################################################ */
void dynsec_groups__cleanup(void);
int dynsec_groups__config_load(cJSON *tree);
int dynsec_groups__add_client(const char *username, const char *groupname, int priority, bool update_config);
int dynsec_groups__config_save(cJSON *tree);
int dynsec_groups__process_add_client(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_add_role(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_create(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_delete(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_get(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_list(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_modify(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_remove_client(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_remove_role(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_get_anonymous_group(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__process_set_anonymous_group(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_groups__remove_client(const char *username, const char *groupname, bool update_config);
struct dynsec__group *dynsec_groups__find(const char *groupname);
/* ################################################################
* #
* # Group List Functions
* #
* ################################################################ */
cJSON *dynsec_grouplist__all_to_json(struct dynsec__grouplist *base_grouplist);
int dynsec_grouplist__add(struct dynsec__grouplist **base_grouplist, struct dynsec__group *group, int priority);
void dynsec_grouplist__cleanup(struct dynsec__grouplist **base_grouplist);
void dynsec_grouplist__remove(struct dynsec__grouplist **base_grouplist, struct dynsec__group *group);
/* ################################################################
* #
* # Role Functions
* #
* ################################################################ */
void dynsec_roles__cleanup(void);
int dynsec_roles__config_load(cJSON *tree);
int dynsec_roles__config_save(cJSON *tree);
int dynsec_roles__process_add_acl(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_roles__process_create(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_roles__process_delete(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_roles__process_get(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_roles__process_list(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_roles__process_modify(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
int dynsec_roles__process_remove_acl(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
struct dynsec__role *dynsec_roles__find(const char *rolename);
/* ################################################################
* #
* # Role List Functions
* #
* ################################################################ */
int dynsec_rolelist__client_add(struct dynsec__client *client, struct dynsec__role *role, int priority);
int dynsec_rolelist__client_remove(struct dynsec__client *client, struct dynsec__role *role);
int dynsec_rolelist__group_add(struct dynsec__group *group, struct dynsec__role *role, int priority);
void dynsec_rolelist__group_remove(struct dynsec__group *group, struct dynsec__role *role);
int dynsec_rolelist__load_from_json(cJSON *command, struct dynsec__rolelist **rolelist);
void dynsec_rolelist__cleanup(struct dynsec__rolelist **base_rolelist);
cJSON *dynsec_rolelist__all_to_json(struct dynsec__rolelist *base_rolelist);
#endif
|