Coverage Report

Created: 2024-07-27 06:05

/src/net-snmp/snmplib/snmp_service.c
Line
Count
Source (jump to first uncovered line)
1
#include <net-snmp/net-snmp-config.h>
2
3
#include <stdlib.h>
4
#include <string.h>
5
6
#include <net-snmp/net-snmp-includes.h>
7
#include <net-snmp/library/snmp_transport.h>
8
9
static char**
10
create_word_array_helper(const char* cptr, size_t idx, char* tmp, size_t tmplen)
11
0
{
12
0
    char* item;
13
0
    char** res;
14
0
    cptr = copy_nword_const(cptr, tmp, tmplen);
15
0
    item = strdup(tmp);
16
0
    if (cptr)
17
0
        res = create_word_array_helper(cptr, idx + 1, tmp, tmplen);
18
0
    else {
19
0
        res = (char**)malloc(sizeof(char*) * (idx + 2));
20
0
        res[idx + 1] = NULL;
21
0
    }
22
0
    res[idx] = item;
23
0
    return res;
24
0
}
25
26
static char**
27
create_word_array(const char* cptr)
28
0
{
29
0
    size_t tmplen = strlen(cptr);
30
0
    char* tmp = (char*)malloc(tmplen + 1);
31
0
    char** res = create_word_array_helper(cptr, 0, tmp, tmplen + 1);
32
0
    free(tmp);
33
0
    return res;
34
0
}
35
36
static void
37
destroy_word_array(char** arr)
38
0
{
39
0
    if (arr) {
40
0
        char** run = arr;
41
0
        while(*run) {
42
0
            free(*run);
43
0
            ++run;
44
0
        }
45
0
        free(arr);
46
0
    }
47
0
}
48
49
struct netsnmp_lookup_domain {
50
    char* application;
51
    char** userDomain;
52
    char** domain;
53
    struct netsnmp_lookup_domain* next;
54
};
55
56
static struct netsnmp_lookup_domain* domains = NULL;
57
58
int
59
netsnmp_register_default_domain(const char* application, const char* domain)
60
0
{
61
0
    struct netsnmp_lookup_domain *run = domains, *prev = NULL;
62
0
    int res = 0;
63
64
0
    while (run != NULL && strcmp(run->application, application) < 0) {
65
0
  prev = run;
66
0
  run = run->next;
67
0
    }
68
0
    if (run && strcmp(run->application, application) == 0) {
69
0
      if (run->domain != NULL) {
70
0
          destroy_word_array(run->domain);
71
0
    run->domain = NULL;
72
0
    res = 1;
73
0
      }
74
0
    } else {
75
0
  run = SNMP_MALLOC_STRUCT(netsnmp_lookup_domain);
76
0
  run->application = strdup(application);
77
0
  run->userDomain = NULL;
78
0
  if (prev) {
79
0
      run->next = prev->next;
80
0
      prev->next = run;
81
0
  } else {
82
0
      run->next = domains;
83
0
      domains = run;
84
0
  }
85
0
    }
86
0
    if (domain) {
87
0
        run->domain = create_word_array(domain);
88
0
    } else if (run->userDomain == NULL) {
89
0
  if (prev)
90
0
      prev->next = run->next;
91
0
  else
92
0
      domains = run->next;
93
0
  free(run->application);
94
0
  free(run);
95
0
    }
96
0
    return res;
97
0
}
98
99
void
100
netsnmp_clear_default_domain(void)
101
0
{
102
0
    while (domains) {
103
0
  struct netsnmp_lookup_domain *tmp = domains;
104
0
  domains = domains->next;
105
0
  free(tmp->application);
106
0
        destroy_word_array(tmp->userDomain);
107
0
        destroy_word_array(tmp->domain);
108
0
  free(tmp);
109
0
    }
110
0
}
111
112
static void
113
netsnmp_register_user_domain(const char* token, char* cptr)
114
0
{
115
0
    struct netsnmp_lookup_domain *run = domains, *prev = NULL;
116
0
    size_t len = strlen(cptr) + 1;
117
0
    char* application = (char*)malloc(len);
118
0
    char** domain;
119
120
0
    {
121
0
        char* cp = copy_nword(cptr, application, len);
122
0
        if (cp == NULL) {
123
0
            netsnmp_config_error("No domain(s) in registration of "
124
0
                                 "defDomain \"%s\"", application);
125
0
            free(application);
126
0
            return;
127
0
        }
128
0
        domain = create_word_array(cp);
129
0
    }
130
131
0
    while (run != NULL && strcmp(run->application, application) < 0) {
132
0
  prev = run;
133
0
  run = run->next;
134
0
    }
135
0
    if (run && strcmp(run->application, application) == 0) {
136
0
  if (run->userDomain != NULL) {
137
0
      config_perror("Default transport already registered for this "
138
0
        "application");
139
0
            destroy_word_array(domain);
140
0
            free(application);
141
0
      return;
142
0
  }
143
0
    } else {
144
0
  run = SNMP_MALLOC_STRUCT(netsnmp_lookup_domain);
145
0
  run->application = strdup(application);
146
0
  run->domain = NULL;
147
0
  if (prev) {
148
0
      run->next = prev->next;
149
0
      prev->next = run;
150
0
  } else {
151
0
      run->next = domains;
152
0
      domains = run;
153
0
  }
154
0
    }
155
0
    run->userDomain = domain;
156
0
    free(application);
157
0
}
158
159
static void
160
netsnmp_clear_user_domain(void)
161
0
{
162
0
    struct netsnmp_lookup_domain *run = domains, *prev = NULL;
163
164
0
    while (run) {
165
0
  if (run->userDomain != NULL) {
166
0
            destroy_word_array(run->userDomain);
167
0
      run->userDomain = NULL;
168
0
  }
169
0
  if (run->domain == NULL) {
170
0
      struct netsnmp_lookup_domain *tmp = run;
171
0
      if (prev)
172
0
    run = prev->next = run->next;
173
0
      else
174
0
    run = domains = run->next;
175
0
      free(tmp->application);
176
0
      free(tmp);
177
0
  } else {
178
0
      prev = run;
179
0
      run = run->next;
180
0
  }
181
0
    }
182
0
}
183
184
const char* const *
185
netsnmp_lookup_default_domains(const char* application)
186
0
{
187
0
    const char * const * res;
188
189
0
    if (application == NULL)
190
0
  res = NULL;
191
0
    else {
192
0
        struct netsnmp_lookup_domain *run = domains;
193
194
0
  while (run && strcmp(run->application, application) < 0)
195
0
      run = run->next;
196
0
  if (run && strcmp(run->application, application) == 0)
197
0
      if (run->userDomain)
198
0
                res = (const char * const *)run->userDomain;
199
0
      else
200
0
                res = (const char * const *)run->domain;
201
0
  else
202
0
      res = NULL;
203
0
    }
204
0
    DEBUGMSGTL(("defaults",
205
0
                "netsnmp_lookup_default_domain(\"%s\") ->",
206
0
                application ? application : "[NIL]"));
207
0
    if (res) {
208
0
        const char * const * r = res;
209
0
        while(*r) {
210
0
            DEBUGMSG(("defaults", " \"%s\"", *r));
211
0
            ++r;
212
0
        }
213
0
        DEBUGMSG(("defaults", "\n"));
214
0
    } else
215
0
        DEBUGMSG(("defaults", " \"[NIL]\"\n"));
216
0
    return res;
217
0
}
218
219
const char*
220
netsnmp_lookup_default_domain(const char* application)
221
0
{
222
0
    const char * const * res = netsnmp_lookup_default_domains(application);
223
0
    return (res ? *res : NULL);
224
0
}
225
226
struct netsnmp_lookup_target {
227
    char* application;
228
    char* domain;
229
    char* userTarget;
230
    char* target;
231
    struct netsnmp_lookup_target* next;
232
};
233
234
static struct netsnmp_lookup_target* targets = NULL;
235
236
/**
237
 * Add an (application, domain, target) triplet to the targets list if target
238
 * != NULL. Remove an entry if target == NULL and the userTarget pointer for
239
 * the entry found is also NULL. Keep at most one target per (application,
240
 * domain) pair.
241
 *
242
 * @return 1 if an entry for (application, domain) was already present in the
243
 *   targets list or 0 if such an entry was not yet present in the targets list.
244
 */
245
int
246
netsnmp_register_default_target(const char* application, const char* domain,
247
        const char* target)
248
0
{
249
0
    struct netsnmp_lookup_target *run = targets, *prev = NULL;
250
0
    int i = 0, res = 0;
251
0
    while (run && ((i = strcmp(run->application, application)) < 0 ||
252
0
       (i == 0 && strcmp(run->domain, domain) < 0))) {
253
0
  prev = run;
254
0
  run = run->next;
255
0
    }
256
0
    if (run && i == 0 && strcmp(run->domain, domain) == 0) {
257
0
      if (run->target != NULL) {
258
0
      free(run->target);
259
0
      run->target = NULL;
260
0
      res = 1;
261
0
      }
262
0
    } else {
263
0
  run = SNMP_MALLOC_STRUCT(netsnmp_lookup_target);
264
0
  run->application = strdup(application);
265
0
  run->domain = strdup(domain);
266
0
  run->userTarget = NULL;
267
0
  if (prev) {
268
0
      run->next = prev->next;
269
0
      prev->next = run;
270
0
  } else {
271
0
      run->next = targets;
272
0
      targets = run;
273
0
  }
274
0
    }
275
0
    if (target) {
276
0
  run->target = strdup(target);
277
0
    } else if (run->userTarget == NULL) {
278
0
  if (prev)
279
0
      prev->next = run->next;
280
0
  else
281
0
      targets = run->next;
282
0
  free(run->domain);
283
0
  free(run->application);
284
0
  free(run);
285
0
    }
286
0
    return res;
287
0
}
288
289
/**
290
 * Clear the targets list.
291
 */
292
void
293
netsnmp_clear_default_target(void)
294
0
{
295
0
    while (targets) {
296
0
  struct netsnmp_lookup_target *tmp = targets;
297
0
  targets = targets->next;
298
0
  free(tmp->application);
299
0
  free(tmp->domain);
300
0
  free(tmp->userTarget);
301
0
  free(tmp->target);
302
0
  free(tmp);
303
0
    }
304
0
}
305
306
static void
307
netsnmp_register_user_target(const char* token, char* cptr)
308
0
{
309
0
    struct netsnmp_lookup_target *run = targets, *prev = NULL;
310
0
    size_t len = strlen(cptr) + 1;
311
0
    char* application = (char*)malloc(len);
312
0
    char* domain = (char*)malloc(len);
313
0
    char* target = (char*)malloc(len);
314
0
    int i = 0;
315
316
0
    if (application == NULL || domain == NULL || target == NULL) {
317
0
        goto done;
318
0
    }
319
0
    {
320
0
  char* cp = copy_nword(cptr, application, len);
321
0
        if (cp == NULL) {
322
0
            netsnmp_config_error("No domain and target in registration of "
323
0
                                 "defTarget \"%s\"", application);
324
0
            goto done;
325
0
        }
326
0
  cp = copy_nword(cp, domain, len);
327
0
        if (cp == NULL) {
328
0
            netsnmp_config_error("No target in registration of "
329
0
                                 "defTarget \"%s\" \"%s\"",
330
0
                                 application, domain);
331
0
            goto done;
332
0
        }
333
0
  cp = copy_nword(cp, target, len);
334
0
  if (cp)
335
0
      config_pwarn("Trailing junk found");
336
0
    }
337
338
0
    while (run && ((i = strcmp(run->application, application)) < 0 ||
339
0
       (i == 0 && strcmp(run->domain, domain) < 0))) {
340
0
  prev = run;
341
0
  run = run->next;
342
0
    }
343
0
    if (run && i == 0 && strcmp(run->domain, domain) == 0) {
344
0
  if (run->userTarget != NULL) {
345
0
      config_perror("Default target already registered for this "
346
0
        "application-domain combination");
347
0
      goto done;
348
0
  }
349
0
    } else {
350
0
  run = SNMP_MALLOC_STRUCT(netsnmp_lookup_target);
351
0
  run->application = strdup(application);
352
0
  run->domain = strdup(domain);
353
0
  run->target = NULL;
354
0
  if (prev) {
355
0
      run->next = prev->next;
356
0
      prev->next = run;
357
0
  } else {
358
0
      run->next = targets;
359
0
      targets = run;
360
0
  }
361
0
    }
362
0
    run->userTarget = strdup(target);
363
0
 done:
364
0
    free(target);
365
0
    free(domain);
366
0
    free(application);
367
0
}
368
369
static void
370
netsnmp_clear_user_target(void)
371
0
{
372
0
    struct netsnmp_lookup_target *run = targets, *prev = NULL;
373
374
0
    while (run) {
375
0
  if (run->userTarget != NULL) {
376
0
      free(run->userTarget);
377
0
      run->userTarget = NULL;
378
0
  }
379
0
  if (run->target == NULL) {
380
0
      struct netsnmp_lookup_target *tmp = run;
381
0
      if (prev)
382
0
    run = prev->next = run->next;
383
0
      else
384
0
    run = targets = run->next;
385
0
      free(tmp->application);
386
0
      free(tmp->domain);
387
0
      free(tmp);
388
0
  } else {
389
0
      prev = run;
390
0
      run = run->next;
391
0
  }
392
0
    }
393
0
}
394
395
const char*
396
netsnmp_lookup_default_target(const char* application, const char* domain)
397
0
{
398
0
    int i = 0;
399
0
    struct netsnmp_lookup_target *run = targets;
400
0
    const char *res;
401
402
0
    if (application == NULL || domain == NULL)
403
0
  res = NULL;
404
0
    else {
405
0
  while (run && ((i = strcmp(run->application, application)) < 0 ||
406
0
           (i == 0 && strcmp(run->domain, domain) < 0)))
407
0
      run = run->next;
408
0
  if (run && i == 0 && strcmp(run->domain, domain) == 0)
409
0
      if (run->userTarget != NULL)
410
0
    res = run->userTarget;
411
0
      else
412
0
    res = run->target;
413
0
  else
414
0
      res = NULL;
415
0
    }
416
0
    DEBUGMSGTL(("defaults",
417
0
    "netsnmp_lookup_default_target(\"%s\", \"%s\") -> \"%s\"\n",
418
0
    application ? application : "[NIL]",
419
0
    domain ? domain : "[NIL]",
420
0
    res ? res : "[NIL]"));
421
0
    return res;
422
0
}
423
424
void
425
netsnmp_register_service_handlers(void)
426
0
{
427
0
    register_config_handler("snmp:", "defDomain",
428
0
          netsnmp_register_user_domain,
429
0
          netsnmp_clear_user_domain,
430
0
          "application domain");
431
0
    register_config_handler("snmp:", "defTarget",
432
0
          netsnmp_register_user_target,
433
0
          netsnmp_clear_user_target,
434
0
          "application domain target");
435
0
}