Coverage Report

Created: 2024-09-11 06:05

/src/net-snmp/agent/mibgroup/utilities/iquery.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Portions of this file are copyrighted by:
3
 * Copyright (c) 2016 VMware, Inc. All rights reserved.
4
 * Use is subject to license terms specified in the COPYING file
5
 * distributed with the Net-SNMP package.
6
 */
7
#include <net-snmp/net-snmp-config.h>
8
#include <net-snmp/net-snmp-features.h>
9
#include <net-snmp/net-snmp-includes.h>
10
#include <net-snmp/agent/net-snmp-agent-includes.h>
11
12
#include "agent_global_vars.h"
13
#include "agentx/subagent.h"
14
#include "utilities/iquery.h"
15
16
netsnmp_feature_child_of(iquery_all, libnetsnmpmibs);
17
netsnmp_feature_child_of(iquery, iquery_all);
18
netsnmp_feature_child_of(iquery_community_session, iquery_all);
19
netsnmp_feature_child_of(iquery_pdu_session, iquery_all);
20
21
netsnmp_feature_require(query_set_default_session);
22
23
#ifndef NETSNMP_FEATURE_REMOVE_IQUERY
24
25
void
26
netsnmp_parse_iquerySecLevel(const char *token, char *line)
27
0
{
28
0
    int secLevel;
29
30
0
#ifndef NETSNMP_FEATURE_REMOVE_RUNTIME_DISABLE_VERSION
31
0
    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
32
0
                               NETSNMP_DS_LIB_DISABLE_V3)) {
33
0
        netsnmp_config_error("SNMPv3 disabled");
34
0
    } else
35
0
#endif
36
0
    if ((secLevel = parse_secLevel_conf( token, line )) >= 0 ) {
37
0
        netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
38
0
                           NETSNMP_DS_AGENT_INTERNAL_SECLEVEL, secLevel);
39
0
    } else {
40
0
  netsnmp_config_error("Unknown security level: %s", line);
41
0
    }
42
0
}
43
44
void
45
netsnmp_parse_iqueryVersion(const char *token, char *line)
46
0
{
47
0
#ifndef NETSNMP_DISABLE_SNMPV1
48
0
    if (!strcmp( line, "1" )
49
0
#ifndef NETSNMP_FEATURE_REMOVE_RUNTIME_DISABLE_VERSION
50
0
        && !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
51
0
                                NETSNMP_DS_LIB_DISABLE_V1)
52
0
#endif
53
0
        )
54
0
        netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
55
0
                           NETSNMP_DS_AGENT_INTERNAL_VERSION, SNMP_VERSION_1);
56
0
    else 
57
0
#endif
58
0
#ifndef NETSNMP_DISABLE_SNMPV2C
59
0
        if ((!strcmp( line, "2"  ) || !strcasecmp( line, "2c" ))
60
0
#ifndef NETSNMP_FEATURE_REMOVE_RUNTIME_DISABLE_VERSION
61
0
            && !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
62
0
                                       NETSNMP_DS_LIB_DISABLE_V2c)
63
0
#endif
64
0
            )
65
0
        netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
66
0
                           NETSNMP_DS_AGENT_INTERNAL_VERSION, SNMP_VERSION_2c);
67
0
    else 
68
0
#endif
69
0
         if (!strcmp( line, "3" )
70
0
#ifndef NETSNMP_FEATURE_REMOVE_RUNTIME_DISABLE_VERSION
71
0
             && !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
72
0
                                        NETSNMP_DS_LIB_DISABLE_V3)
73
0
#endif
74
0
             )
75
0
        netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
76
0
                           NETSNMP_DS_AGENT_INTERNAL_VERSION, SNMP_VERSION_3);
77
0
    else {
78
0
  netsnmp_config_error("Unknown/disabled version: %s", line);
79
0
    }
80
0
}
81
82
  /*
83
   * Set up a default session for running internal queries.
84
   * This needs to be done before the config files are read,
85
   *  so that it is available for "monitor" directives...
86
   */
87
int
88
_init_default_iquery_session( int majorID, int minorID,
89
                              void *serverargs, void *clientarg)
90
2.62k
{
91
2.62k
    char *secName = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
92
2.62k
                                          NETSNMP_DS_AGENT_INTERNAL_SECNAME);
93
2.62k
    if (secName)
94
0
        netsnmp_query_set_default_session(
95
0
             netsnmp_iquery_user_session(secName));
96
2.62k
    return SNMPERR_SUCCESS;
97
2.62k
}
98
99
  /*
100
   * ... Unfortunately, the internal engine ID is not set up
101
   * until later, so this default session is incomplete.
102
   * The resulting engineID probe runs into problems,
103
   * causing the very first internal query to time out.
104
   *   Updating the default session with the internal engineID
105
   * once it has been set, fixes this problem.
106
   */
107
int
108
_tweak_default_iquery_session( int majorID, int minorID,
109
                              void *serverargs, void *clientarg)
110
2.62k
{
111
2.62k
    u_char eID[SNMP_MAXBUF_SMALL];
112
2.62k
    size_t elen;
113
2.62k
    netsnmp_session *s = netsnmp_query_get_default_session_unchecked();
114
115
2.62k
    if ( s && s->securityEngineIDLen == 0 ) {
116
0
        elen = snmpv3_get_engineID(eID, sizeof(eID));
117
0
        s->securityEngineID = netsnmp_memdup(eID, elen);
118
0
        s->securityEngineIDLen = elen;
119
0
    }
120
2.62k
    return SNMPERR_SUCCESS;
121
2.62k
}
122
123
2.62k
void init_iquery(void){
124
2.62k
    char *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
125
2.62k
                                       NETSNMP_DS_LIB_APPTYPE);
126
2.62k
    netsnmp_ds_register_premib(ASN_OCTET_STR, type, "agentSecName",
127
2.62k
                               NETSNMP_DS_APPLICATION_ID,
128
2.62k
                               NETSNMP_DS_AGENT_INTERNAL_SECNAME);
129
2.62k
    netsnmp_ds_register_premib(ASN_OCTET_STR, type, "iquerySecName",
130
2.62k
                               NETSNMP_DS_APPLICATION_ID,
131
2.62k
                               NETSNMP_DS_AGENT_INTERNAL_SECNAME);
132
133
2.62k
    snmpd_register_config_handler("iqueryVersion",
134
2.62k
                                   netsnmp_parse_iqueryVersion, NULL,
135
2.62k
                                   "1 | 2c | 3");
136
2.62k
    snmpd_register_config_handler("iquerySecLevel",
137
2.62k
                                   netsnmp_parse_iquerySecLevel, NULL,
138
2.62k
                                   "noAuthNoPriv | authNoPriv | authPriv");
139
140
    /*
141
     * Set defaults
142
     */
143
2.62k
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
144
2.62k
                       NETSNMP_DS_AGENT_INTERNAL_VERSION, SNMP_VERSION_3);
145
2.62k
    netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
146
2.62k
                       NETSNMP_DS_AGENT_INTERNAL_SECLEVEL, SNMP_SEC_LEVEL_AUTHNOPRIV);
147
148
2.62k
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, 
149
2.62k
                           SNMP_CALLBACK_POST_PREMIB_READ_CONFIG,
150
2.62k
                           _init_default_iquery_session, NULL);
151
2.62k
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, 
152
2.62k
                           SNMP_CALLBACK_POST_READ_CONFIG,
153
2.62k
                           _tweak_default_iquery_session, NULL);
154
2.62k
}
155
156
    /**************************
157
     *
158
     *  APIs to construct an "internal query" session
159
     *
160
     **************************/
161
162
#ifndef NETSNMP_FEATURE_REMOVE_IQUERY_PDU_SESSION
163
0
netsnmp_session *netsnmp_iquery_pdu_session(netsnmp_pdu* pdu) {
164
0
    if (!pdu || NETSNMP_RUNTIME_PROTOCOL_SKIP(pdu->version))
165
0
       return NULL;
166
0
    if (pdu->version == SNMP_VERSION_3)
167
0
        return netsnmp_iquery_session( pdu->securityName, 
168
0
                           pdu->version,
169
0
                           pdu->securityModel,
170
0
                           pdu->securityLevel,
171
0
                           pdu->securityEngineID,
172
0
                           pdu->securityEngineIDLen);
173
0
    else
174
0
        return netsnmp_iquery_session((char *) pdu->community, 
175
176
0
                           pdu->version,
177
0
                           pdu->version+1,
178
0
                           SNMP_SEC_LEVEL_NOAUTH,
179
0
                           pdu->securityEngineID,
180
0
                           pdu->securityEngineIDLen);
181
0
}
182
#endif /* NETSNMP_FEATURE_REMOVE_IQUERY_PDU_SESSION */
183
184
0
netsnmp_session *netsnmp_iquery_user_session(char* secName){
185
0
    u_char eID[SNMP_MAXBUF_SMALL];
186
0
    size_t elen = snmpv3_get_engineID(eID, sizeof(eID));
187
188
0
    return netsnmp_iquery_session( secName, 
189
0
                           SNMP_VERSION_3,
190
0
                           SNMP_SEC_MODEL_USM,
191
0
                           SNMP_SEC_LEVEL_AUTHNOPRIV, eID, elen);
192
0
}
193
194
#ifndef NETSNMP_FEATURE_REMOVE_IQUERY_COMMUNITY_SESSION
195
0
netsnmp_session *netsnmp_iquery_community_session( char* community, int version ) { 
196
0
    u_char eID[SNMP_MAXBUF_SMALL];
197
0
    size_t elen = snmpv3_get_engineID(eID, sizeof(eID));
198
199
0
    return netsnmp_iquery_session( community, version, version+1,
200
0
                           SNMP_SEC_LEVEL_NOAUTH, eID, elen);
201
0
}
202
#endif /* NETSNMP_FEATURE_REMOVE_IQUERY_COMMUNITY_SESSION */
203
204
netsnmp_session *netsnmp_iquery_session(char* secName,   int   version,
205
                                        int   secModel,  int   secLevel,
206
0
                                       u_char* engineID, size_t engIDLen) {
207
208
    /*
209
     * This routine creates a completely new session every time.
210
     * It might be worth keeping track of which 'secNames' already
211
     * have iquery sessions created, and re-using the appropriate one.  
212
     */
213
0
    netsnmp_session *ss = NULL;
214
215
0
    NETSNMP_RUNTIME_PROTOCOL_CHECK(version, unsupported_version);
216
217
0
#ifdef NETSNMP_TRANSPORT_CALLBACK_DOMAIN
218
0
    ss = netsnmp_callback_open( callback_master_num, NULL, NULL, NULL);
219
0
    if (ss) {
220
0
        ss->version       = version;
221
0
        ss->securityModel = secModel;
222
0
        ss->securityLevel = secLevel;
223
0
        ss->securityEngineID = netsnmp_memdup(engineID, engIDLen);
224
0
        ss->securityEngineIDLen = engIDLen;
225
0
        if ( version == SNMP_VERSION_3 ) {
226
0
            ss->securityNameLen = strlen(secName);
227
0
            ss->securityName = netsnmp_memdup(secName, ss->securityNameLen + 1);
228
0
        } else {
229
0
            ss->community = netsnmp_memdup(secName, strlen(secName));
230
0
            ss->community_len = strlen(secName);
231
0
        }
232
0
        ss->myvoid = (void *)netsnmp_check_outstanding_agent_requests;
233
0
        ss->flags |= SNMP_FLAGS_RESP_CALLBACK | SNMP_FLAGS_DONT_PROBE;
234
0
    }
235
0
#endif
236
237
0
  unsupported_version:
238
0
    return ss;
239
0
}
240
241
#else /* NETSNMP_FEATURE_REMOVE_IQUERY */
242
netsnmp_feature_unused(iquery);
243
#endif /* NETSNMP_FEATURE_REMOVE_IQUERY */
244