Coverage Report

Created: 2024-07-27 06:09

/src/net-snmp/snmplib/snmp_secmod.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * security service wrapper to support pluggable security models 
3
 *
4
 * Portions of this file are subject to the following copyright(s).  See
5
 * the Net-SNMP's COPYING file for more details and other copyrights
6
 * that may apply:
7
 *
8
 * Portions of this file are copyrighted by:
9
 * Copyright (c) 2016 VMware, Inc. All rights reserved.
10
 * Use is subject to license terms specified in the COPYING file
11
 * distributed with the Net-SNMP package.
12
 */
13
14
#include <net-snmp/net-snmp-config.h>
15
#include <stdio.h>
16
#include <ctype.h>
17
#ifdef HAVE_STDLIB_H
18
#include <stdlib.h>
19
#endif
20
#ifdef HAVE_STRING_H
21
#include <string.h>
22
#else
23
#include <strings.h>
24
#endif
25
#ifdef HAVE_UNISTD_H
26
#include <unistd.h>
27
#endif
28
29
#include <net-snmp/types.h>
30
#include <net-snmp/output_api.h>
31
#include <net-snmp/config_api.h>
32
#include <net-snmp/utilities.h>
33
34
#include <net-snmp/library/snmp_api.h>
35
#include <net-snmp/library/snmp_enum.h>
36
#include <net-snmp/library/callback.h>
37
#include <net-snmp/library/snmp_secmod.h>
38
#include <net-snmp/library/snmpv3-security-includes.h>
39
40
#include <net-snmp/net-snmp-features.h>
41
42
static struct snmp_secmod_list *registered_services = NULL;
43
44
static SNMPCallback set_default_secmod;
45
46
void
47
init_secmod(void)
48
2.81k
{
49
2.81k
    snmp_register_callback(SNMP_CALLBACK_LIBRARY,
50
2.81k
                           SNMP_CALLBACK_SESSION_INIT, set_default_secmod,
51
2.81k
                           NULL);
52
53
2.81k
    netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defSecurityModel",
54
2.81k
             NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECMODEL);
55
    /*
56
     * this file is generated by configure for all the stuff we're using 
57
     */
58
2.81k
#include "snmpsm_init.h"
59
2.81k
}
60
61
void
62
shutdown_secmod(void)
63
5.62k
{
64
5.62k
    #include "snmpsm_shutdown.h"
65
5.62k
}
66
67
int
68
register_sec_mod(int secmod, const char *modname,
69
                 struct snmp_secmod_def *newdef)
70
8.44k
{
71
8.44k
    int             result = 0;
72
8.44k
    struct snmp_secmod_list *sptr;
73
8.44k
    char           *othername, *modname2 = NULL;
74
75
16.8k
    for (sptr = registered_services; sptr; sptr = sptr->next) {
76
8.43k
        if (sptr->securityModel == secmod) {
77
0
            return SNMPERR_GENERR;
78
0
        }
79
8.43k
    }
80
8.44k
    sptr = SNMP_MALLOC_STRUCT(snmp_secmod_list);
81
8.44k
    if (sptr == NULL)
82
0
        return SNMPERR_MALLOC;
83
8.44k
    sptr->secDef = newdef;
84
8.44k
    sptr->securityModel = secmod;
85
8.44k
    sptr->next = registered_services;
86
8.44k
    registered_services = sptr;
87
8.44k
    modname2 = strdup(modname);
88
8.44k
    if (!modname2)
89
0
        result = SE_NOMEM;
90
8.44k
    else
91
8.44k
        result = se_add_pair_to_slist("snmp_secmods", modname2, secmod);
92
8.44k
    if (result != SE_OK) {
93
0
        switch (result) {
94
0
        case SE_NOMEM:
95
0
            snmp_log(LOG_CRIT, "snmp_secmod: no memory\n");
96
0
            break;
97
98
0
        case SE_ALREADY_THERE:
99
0
            othername = se_find_label_in_slist("snmp_secmods", secmod);
100
0
            if (strcmp(othername, modname) != 0) {
101
0
                snmp_log(LOG_ERR,
102
0
                         "snmp_secmod: two security modules %s and %s registered with the same security number\n",
103
0
                         modname, othername);
104
0
            }
105
0
            break;
106
107
0
        default:
108
0
            snmp_log(LOG_ERR,
109
0
                     "snmp_secmod: unknown error trying to register a new security module\n");
110
0
            break;
111
0
        }
112
0
        return SNMPERR_GENERR;
113
0
    }
114
8.44k
    return SNMPERR_SUCCESS;
115
8.44k
}
116
117
netsnmp_feature_child_of(unregister_sec_mod, netsnmp_unused);
118
#ifndef NETSNMP_FEATURE_REMOVE_UNREGISTER_SEC_MOD
119
int
120
unregister_sec_mod(int secmod)
121
0
{
122
0
    struct snmp_secmod_list *sptr, *lptr;
123
124
0
    for (sptr = registered_services, lptr = NULL; sptr;
125
0
         lptr = sptr, sptr = sptr->next) {
126
0
        if (sptr->securityModel == secmod) {
127
0
            if ( lptr )
128
0
                lptr->next = sptr->next;
129
0
            else
130
0
                registered_services = sptr->next;
131
0
      SNMP_FREE(sptr->secDef);
132
0
            SNMP_FREE(sptr);
133
0
            return SNMPERR_SUCCESS;
134
0
        }
135
0
    }
136
    /*
137
     * not registered 
138
     */
139
0
    return SNMPERR_GENERR;
140
0
}
141
#endif /* NETSNMP_FEATURE_REMOVE_UNREGISTER_SEC_MOD */
142
143
void            
144
clear_sec_mod(void)
145
5.62k
{
146
5.62k
    struct snmp_secmod_list *tmp = registered_services, *next = NULL;
147
148
14.0k
    while (tmp != NULL) {
149
8.43k
  next = tmp->next;
150
8.43k
  SNMP_FREE(tmp->secDef);
151
8.43k
  SNMP_FREE(tmp);
152
8.43k
  tmp = next;
153
8.43k
    }
154
5.62k
    registered_services = NULL;
155
5.62k
}
156
157
158
struct snmp_secmod_def *
159
find_sec_mod(int secmod)
160
88.2k
{
161
88.2k
    struct snmp_secmod_list *sptr;
162
163
295k
    for (sptr = registered_services; sptr; sptr = sptr->next) {
164
214k
        if (sptr->securityModel == secmod) {
165
7.43k
            return sptr->secDef;
166
7.43k
        }
167
214k
    }
168
    /*
169
     * not registered 
170
     */
171
80.8k
    return NULL;
172
88.2k
}
173
174
/* try to pick a reasonable security module default based on what was
175
   compiled into the net-snmp package */
176
#ifdef USM_SEC_MODEL_NUMBER
177
2.81k
#define NETSNMP_SECMOD_DEFAULT_MODEL  USM_SEC_MODEL_NUMBER
178
#elif defined(TSM_SEC_MODEL_NUMBER)
179
#define NETSNMP_SECMOD_DEFAULT_MODEL  TSM_SEC_MODEL_NUMBER
180
#elif defined(KSM_SEC_MODEL_NUMBER)
181
#define NETSNMP_SECMOD_DEFAULT_MODEL  KSM_SEC_MODEL_NUMBER
182
#else
183
/* else we give up and leave it blank */
184
#define NETSNMP_SECMOD_DEFAULT_MODEL  -1
185
#endif
186
187
static int
188
set_default_secmod(int major, int minor, void *serverarg, void *clientarg)
189
4.62k
{
190
4.62k
    netsnmp_session *sess = (netsnmp_session *) serverarg;
191
4.62k
    char           *cptr;
192
4.62k
    int             model;
193
194
4.62k
    if (!sess)
195
0
        return SNMPERR_GENERR;
196
4.62k
    if (sess->securityModel == SNMP_DEFAULT_SECMODEL) {
197
2.81k
        if ((cptr = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
198
2.81k
            NETSNMP_DS_LIB_SECMODEL)) != NULL) {
199
0
            if ((model = se_find_value_in_slist("snmp_secmods", cptr))
200
0
    != SE_DNE) {
201
0
                sess->securityModel = model;
202
0
            } else {
203
0
                snmp_log(LOG_ERR,
204
0
                         "unknown security model name: %s.  Forcing USM instead.\n",
205
0
                         cptr);
206
0
                sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL;
207
0
                return SNMPERR_GENERR;
208
0
            }
209
2.81k
        } else {
210
2.81k
            sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL;
211
2.81k
        }
212
2.81k
    }
213
4.62k
    return SNMPERR_SUCCESS;
214
4.62k
}