Coverage Report

Created: 2023-06-07 06:42

/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
0
{
49
0
    snmp_register_callback(SNMP_CALLBACK_LIBRARY,
50
0
                           SNMP_CALLBACK_SESSION_INIT, set_default_secmod,
51
0
                           NULL);
52
53
0
    netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defSecurityModel",
54
0
             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
0
#include "snmpsm_init.h"
59
0
}
60
61
void
62
shutdown_secmod(void)
63
0
{
64
0
    #include "snmpsm_shutdown.h"
65
0
}
66
67
int
68
register_sec_mod(int secmod, const char *modname,
69
                 struct snmp_secmod_def *newdef)
70
2
{
71
2
    int             result = 0;
72
2
    struct snmp_secmod_list *sptr;
73
2
    char           *othername, *modname2 = NULL;
74
75
2
    for (sptr = registered_services; sptr; sptr = sptr->next) {
76
0
        if (sptr->securityModel == secmod) {
77
0
            return SNMPERR_GENERR;
78
0
        }
79
0
    }
80
2
    sptr = SNMP_MALLOC_STRUCT(snmp_secmod_list);
81
2
    if (sptr == NULL)
82
0
        return SNMPERR_MALLOC;
83
2
    sptr->secDef = newdef;
84
2
    sptr->securityModel = secmod;
85
2
    sptr->next = registered_services;
86
2
    registered_services = sptr;
87
2
    modname2 = strdup(modname);
88
2
    if (!modname2)
89
0
        result = SE_NOMEM;
90
2
    else
91
2
        result = se_add_pair_to_slist("snmp_secmods", modname2, secmod);
92
2
    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
2
    return SNMPERR_SUCCESS;
115
2
}
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
0
{
146
0
    struct snmp_secmod_list *tmp = registered_services, *next = NULL;
147
148
0
    while (tmp != NULL) {
149
0
  next = tmp->next;
150
0
  SNMP_FREE(tmp->secDef);
151
0
  SNMP_FREE(tmp);
152
0
  tmp = next;
153
0
    }
154
0
    registered_services = NULL;
155
0
}
156
157
158
struct snmp_secmod_def *
159
find_sec_mod(int secmod)
160
5.52k
{
161
5.52k
    struct snmp_secmod_list *sptr;
162
163
11.0k
    for (sptr = registered_services; sptr; sptr = sptr->next) {
164
5.52k
        if (sptr->securityModel == secmod) {
165
0
            return sptr->secDef;
166
0
        }
167
5.52k
    }
168
    /*
169
     * not registered 
170
     */
171
5.52k
    return NULL;
172
5.52k
}
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
0
#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
0
{
190
0
    netsnmp_session *sess = (netsnmp_session *) serverarg;
191
0
    char           *cptr;
192
0
    int             model;
193
194
0
    if (!sess)
195
0
        return SNMPERR_GENERR;
196
0
    if (sess->securityModel == SNMP_DEFAULT_SECMODEL) {
197
0
        if ((cptr = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
198
0
            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
0
        } else {
210
0
            sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL;
211
0
        }
212
0
    }
213
0
    return SNMPERR_SUCCESS;
214
0
}