/src/mosquitto/plugins/dynamic-security/clientlist.c
Line | Count | Source |
1 | | /* |
2 | | Copyright (c) 2020-2021 Roger Light <roger@atchoo.org> |
3 | | |
4 | | All rights reserved. This program and the accompanying materials |
5 | | are made available under the terms of the Eclipse Public License 2.0 |
6 | | and Eclipse Distribution License v1.0 which accompany this distribution. |
7 | | |
8 | | The Eclipse Public License is available at |
9 | | https://www.eclipse.org/legal/epl-2.0/ |
10 | | and the Eclipse Distribution License is available at |
11 | | http://www.eclipse.org/org/documents/edl-v10.php. |
12 | | |
13 | | SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
14 | | |
15 | | Contributors: |
16 | | Roger Light - initial implementation and documentation. |
17 | | */ |
18 | | |
19 | | #include "config.h" |
20 | | |
21 | | #include <cjson/cJSON.h> |
22 | | #include <stdio.h> |
23 | | #include <uthash.h> |
24 | | |
25 | | #include "dynamic_security.h" |
26 | | #include "json_help.h" |
27 | | |
28 | | /* ################################################################ |
29 | | * # |
30 | | * # Plugin global variables |
31 | | * # |
32 | | * ################################################################ */ |
33 | | |
34 | | /* ################################################################ |
35 | | * # |
36 | | * # Function declarations |
37 | | * # |
38 | | * ################################################################ */ |
39 | | |
40 | | /* ################################################################ |
41 | | * # |
42 | | * # Local variables |
43 | | * # |
44 | | * ################################################################ */ |
45 | | |
46 | | |
47 | | /* ################################################################ |
48 | | * # |
49 | | * # Utility functions |
50 | | * # |
51 | | * ################################################################ */ |
52 | | |
53 | | |
54 | | static int dynsec_clientlist__cmp(void *a, void *b) |
55 | 550k | { |
56 | 550k | struct dynsec__clientlist *clientlist_a = a; |
57 | 550k | struct dynsec__clientlist *clientlist_b = b; |
58 | | |
59 | 550k | return strcmp(clientlist_a->client->username, clientlist_b->client->username); |
60 | 550k | } |
61 | | |
62 | | |
63 | | void dynsec_clientlist__kick_all(struct dynsec__data *data, struct dynsec__clientlist *base_clientlist) |
64 | 0 | { |
65 | 0 | struct dynsec__clientlist *clientlist, *clientlist_tmp; |
66 | |
|
67 | 0 | HASH_ITER(hh, base_clientlist, clientlist, clientlist_tmp){ |
68 | 0 | dynsec_kicklist__add(data, clientlist->client->username); |
69 | 0 | } |
70 | 0 | } |
71 | | |
72 | | |
73 | | cJSON *dynsec_clientlist__all_to_json(struct dynsec__clientlist *base_clientlist) |
74 | 0 | { |
75 | 0 | struct dynsec__clientlist *clientlist, *clientlist_tmp; |
76 | 0 | cJSON *j_clients, *j_client; |
77 | |
|
78 | 0 | j_clients = cJSON_CreateArray(); |
79 | 0 | if(j_clients == NULL){ |
80 | 0 | return NULL; |
81 | 0 | } |
82 | | |
83 | 0 | HASH_ITER(hh, base_clientlist, clientlist, clientlist_tmp){ |
84 | 0 | j_client = cJSON_CreateObject(); |
85 | 0 | if(j_client == NULL){ |
86 | 0 | cJSON_Delete(j_clients); |
87 | 0 | return NULL; |
88 | 0 | } |
89 | 0 | cJSON_AddItemToArray(j_clients, j_client); |
90 | |
|
91 | 0 | if(cJSON_AddStringToObject(j_client, "username", clientlist->client->username) == NULL |
92 | 0 | || (clientlist->priority != -1 && cJSON_AddIntToObject(j_client, "priority", clientlist->priority) == NULL) |
93 | 0 | ){ |
94 | |
|
95 | 0 | cJSON_Delete(j_clients); |
96 | 0 | return NULL; |
97 | 0 | } |
98 | 0 | } |
99 | 0 | return j_clients; |
100 | 0 | } |
101 | | |
102 | | |
103 | | int dynsec_clientlist__add(struct dynsec__clientlist **base_clientlist, struct dynsec__client *client, int priority) |
104 | 48.6k | { |
105 | 48.6k | struct dynsec__clientlist *clientlist; |
106 | | |
107 | 48.6k | HASH_FIND(hh, *base_clientlist, client->username, strlen(client->username), clientlist); |
108 | 48.6k | if(clientlist != NULL){ |
109 | | /* Client is already in the group */ |
110 | 0 | return MOSQ_ERR_SUCCESS; |
111 | 0 | } |
112 | | |
113 | 48.6k | clientlist = mosquitto_malloc(sizeof(struct dynsec__clientlist)); |
114 | 48.6k | if(clientlist == NULL){ |
115 | 0 | return MOSQ_ERR_NOMEM; |
116 | 0 | } |
117 | | |
118 | 48.6k | clientlist->client = client; |
119 | 48.6k | clientlist->priority = priority; |
120 | 48.6k | HASH_ADD_KEYPTR_INORDER(hh, *base_clientlist, client->username, strlen(client->username), clientlist, dynsec_clientlist__cmp); |
121 | | |
122 | 48.6k | return MOSQ_ERR_SUCCESS; |
123 | 48.6k | } |
124 | | |
125 | | |
126 | | void dynsec_clientlist__cleanup(struct dynsec__clientlist **base_clientlist) |
127 | 41.8k | { |
128 | 41.8k | struct dynsec__clientlist *clientlist, *clientlist_tmp; |
129 | | |
130 | 41.8k | HASH_ITER(hh, *base_clientlist, clientlist, clientlist_tmp){ |
131 | 27.5k | HASH_DELETE(hh, *base_clientlist, clientlist); |
132 | 27.5k | mosquitto_free(clientlist); |
133 | 27.5k | } |
134 | 41.8k | } |
135 | | |
136 | | |
137 | | void dynsec_clientlist__remove(struct dynsec__clientlist **base_clientlist, struct dynsec__client *client) |
138 | 0 | { |
139 | 0 | struct dynsec__clientlist *clientlist; |
140 | |
|
141 | 0 | HASH_FIND(hh, *base_clientlist, client->username, strlen(client->username), clientlist); |
142 | 0 | if(clientlist){ |
143 | | HASH_DELETE(hh, *base_clientlist, clientlist); |
144 | 0 | mosquitto_free(clientlist); |
145 | 0 | } |
146 | 0 | } |