Coverage Report

Created: 2025-11-11 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}