/src/mosquitto/plugins/dynamic-security/clientlist.c
Line | Count | Source (jump to first uncovered line) |
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 | | static int dynsec_clientlist__cmp(void *a, void *b) |
54 | 771k | { |
55 | 771k | struct dynsec__clientlist *clientlist_a = a; |
56 | 771k | struct dynsec__clientlist *clientlist_b = b; |
57 | | |
58 | 771k | return strcmp(clientlist_a->client->username, clientlist_b->client->username); |
59 | 771k | } |
60 | | |
61 | | |
62 | | void dynsec_clientlist__kick_all(struct dynsec__data *data, struct dynsec__clientlist *base_clientlist) |
63 | 0 | { |
64 | 0 | struct dynsec__clientlist *clientlist, *clientlist_tmp; |
65 | |
|
66 | 0 | HASH_ITER(hh, base_clientlist, clientlist, clientlist_tmp){ |
67 | 0 | dynsec_kicklist__add(data, clientlist->client->username); |
68 | 0 | } |
69 | 0 | } |
70 | | |
71 | | cJSON *dynsec_clientlist__all_to_json(struct dynsec__clientlist *base_clientlist) |
72 | 0 | { |
73 | 0 | struct dynsec__clientlist *clientlist, *clientlist_tmp; |
74 | 0 | cJSON *j_clients, *j_client; |
75 | |
|
76 | 0 | j_clients = cJSON_CreateArray(); |
77 | 0 | if(j_clients == NULL) return NULL; |
78 | | |
79 | 0 | HASH_ITER(hh, base_clientlist, clientlist, clientlist_tmp){ |
80 | 0 | j_client = cJSON_CreateObject(); |
81 | 0 | if(j_client == NULL){ |
82 | 0 | cJSON_Delete(j_clients); |
83 | 0 | return NULL; |
84 | 0 | } |
85 | 0 | cJSON_AddItemToArray(j_clients, j_client); |
86 | |
|
87 | 0 | if(cJSON_AddStringToObject(j_client, "username", clientlist->client->username) == NULL |
88 | 0 | || (clientlist->priority != -1 && cJSON_AddIntToObject(j_client, "priority", clientlist->priority) == NULL) |
89 | 0 | ){ |
90 | |
|
91 | 0 | cJSON_Delete(j_clients); |
92 | 0 | return NULL; |
93 | 0 | } |
94 | 0 | } |
95 | 0 | return j_clients; |
96 | 0 | } |
97 | | |
98 | | |
99 | | int dynsec_clientlist__add(struct dynsec__clientlist **base_clientlist, struct dynsec__client *client, int priority) |
100 | 53.1k | { |
101 | 53.1k | struct dynsec__clientlist *clientlist; |
102 | | |
103 | 53.1k | HASH_FIND(hh, *base_clientlist, client->username, strlen(client->username), clientlist); |
104 | 53.1k | if(clientlist != NULL){ |
105 | | /* Client is already in the group */ |
106 | 0 | return MOSQ_ERR_SUCCESS; |
107 | 0 | } |
108 | | |
109 | 53.1k | clientlist = mosquitto_malloc(sizeof(struct dynsec__clientlist)); |
110 | 53.1k | if(clientlist == NULL){ |
111 | 0 | return MOSQ_ERR_NOMEM; |
112 | 0 | } |
113 | | |
114 | 53.1k | clientlist->client = client; |
115 | 53.1k | clientlist->priority = priority; |
116 | 53.1k | HASH_ADD_KEYPTR_INORDER(hh, *base_clientlist, client->username, strlen(client->username), clientlist, dynsec_clientlist__cmp); |
117 | | |
118 | 53.1k | return MOSQ_ERR_SUCCESS; |
119 | 53.1k | } |
120 | | |
121 | | |
122 | | void dynsec_clientlist__cleanup(struct dynsec__clientlist **base_clientlist) |
123 | 44.7k | { |
124 | 44.7k | struct dynsec__clientlist *clientlist, *clientlist_tmp; |
125 | | |
126 | 44.7k | HASH_ITER(hh, *base_clientlist, clientlist, clientlist_tmp){ |
127 | 30.4k | HASH_DELETE(hh, *base_clientlist, clientlist); |
128 | 30.4k | mosquitto_free(clientlist); |
129 | 30.4k | } |
130 | 44.7k | } |
131 | | |
132 | | |
133 | | void dynsec_clientlist__remove(struct dynsec__clientlist **base_clientlist, struct dynsec__client *client) |
134 | 0 | { |
135 | 0 | struct dynsec__clientlist *clientlist; |
136 | |
|
137 | 0 | HASH_FIND(hh, *base_clientlist, client->username, strlen(client->username), clientlist); |
138 | 0 | if(clientlist){ |
139 | 0 | HASH_DELETE(hh, *base_clientlist, clientlist); |
140 | 0 | mosquitto_free(clientlist); |
141 | 0 | } |
142 | 0 | } |