Skip to content

Commit 821979a

Browse files
author
Wes Hardaker
committed
SNMPv3 over TLS support
git-svn-id: file:///home/hardaker/lib/sf-bkups/net-snmp-convert-svnrepo/trunk@19121 06827809-a52a-0410-b366-d66718629ded
1 parent 8e19f8b commit 821979a

File tree

3 files changed

+151
-15
lines changed

3 files changed

+151
-15
lines changed

python/README

+33-14
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ Operational Description:
8989
netsnmp.Session(<tag>=<value>, ... )
9090

9191
DestHost - default 'localhost', hostname or ip addr of SNMP agent
92-
Community - default 'public', SNMP community string (used for both R/W)
9392
Version - default '3', [1, 2 (equiv to 2c), 3]
9493
RemotePort - default '161', allow remote UDP port to be overridden
9594
Timeout - default '500000', micro-seconds before retry
@@ -99,18 +98,6 @@ Operational Description:
9998
undef will be returned for all NOSUCH varbinds, when set
10099
to '0' this feature is disabled and the entire get request
101100
will fail on any NOSUCH error (applies to v1 only)
102-
SecName - default 'initial', security name (v3)
103-
SecLevel - default 'noAuthNoPriv', security level [noAuthNoPriv,
104-
authNoPriv, authPriv] (v3)
105-
SecEngineId - default <none>, security engineID, will be probed if not
106-
supplied (v3)
107-
ContextEngineId - default <SecEngineId>, context engineID, will be
108-
probed if not supplied (v3)
109-
Context - default '', context name (v3)
110-
AuthProto - default 'MD5', authentication protocol [MD5, SHA] (v3)
111-
AuthPass - default <none>, authentication passphrase
112-
PrivProto - default 'DES', privacy protocol [DES] (v3)
113-
PrivPass - default <none>, privacy passphrase (v3)
114101
UseLongNames - set to non-zero to have <tags> for 'getnext' methods
115102
generated preferring longer Mib name convention (e.g.,
116103
system.sysDescr vs just sysDescr)
@@ -136,8 +123,40 @@ Operational Description:
136123
ErrorNum - read-only, holds the snmp_err or status of last request
137124
ErrorInd - read-only, holds the snmp_err_index when appropriate
138125

126+
SNMPv1/SNMPv2c options:
127+
Community - default 'public', SNMP community string (used for both R/W)
128+
129+
SNMPv3 Options:
130+
SecName - default 'initial', security name (v3)
131+
SecLevel - default 'noAuthNoPriv', security level [noAuthNoPriv,
132+
authNoPriv, authPriv] (v3)
133+
ContextEngineId - default <SecEngineId>, context engineID, will be
134+
probed if not supplied (v3)
135+
Context - default '', context name (v3)
136+
137+
SNMPv3 over TLS or DTLS options:
138+
OurIdentity - The fingerprint or file name for the local X.509
139+
certificate to use for our identity. Run
140+
net-snmp-cert to create and manage certificates.
141+
TheirIdentity - The fingerprint or file name for the local X.509
142+
certificate to use for their identity.
143+
TrustCert - A trusted certificate to use for validating
144+
certificates. Typically this would be a CA
145+
certificate.
146+
TheirHostname - Their hostname to expect. Either "TheirIdentity"
147+
or a trusted certificate plus a hostname is needed
148+
to validate the server is the proper server.
149+
150+
SNMPv3 with USM security Options:
151+
SecEngineId - default <none>, security engineID, will be probed if not
152+
supplied (v3)
153+
AuthProto - default 'MD5', authentication protocol [MD5, SHA] (v3)
154+
AuthPass - default <none>, authentication passphrase
155+
PrivProto - default 'DES', privacy protocol [DES] (v3)
156+
PrivPass - default <none>, privacy passphrase (v3)
157+
139158
private:
140-
sess_ptr - internal field used to cache a created session structure
159+
sess_ptr - internal field used to cache a created session structure
141160

142161
methods:
143162

python/netsnmp/client.py

+26-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ def _parse_session_args(kargs):
2929
'Engineboots':0,
3030
'Enginetime':0,
3131
'UseNumeric':0,
32+
'OurIdentity':'',
33+
'TheirIdentity':'',
34+
'TheirHostname':'',
35+
'TrustCert':''
3236
}
3337
keys = kargs.keys()
3438
for key in keys:
@@ -125,7 +129,28 @@ def __init__(self, **args):
125129
for k,v in sess_args.items():
126130
self.__dict__[k] = v
127131

128-
if sess_args['Version'] == 3:
132+
133+
# check for transports that may be tunneled
134+
transportCheck = re.compile('^(tls|dtls|ssh)');
135+
match = transportCheck.match(sess_args['DestHost'])
136+
137+
if match:
138+
self.sess_ptr = client_intf.session_tunneled(
139+
sess_args['Version'],
140+
sess_args['DestHost'],
141+
sess_args['LocalPort'],
142+
sess_args['Retries'],
143+
sess_args['Timeout'],
144+
sess_args['SecName'],
145+
secLevelMap[sess_args['SecLevel']],
146+
sess_args['ContextEngineId'],
147+
sess_args['Context'],
148+
sess_args['OurIdentity'],
149+
sess_args['TheirIdentity'],
150+
sess_args['TheirHostname'],
151+
sess_args['TrustCert'],
152+
);
153+
elif sess_args['Version'] == 3:
129154
self.sess_ptr = client_intf.session_v3(
130155
sess_args['Version'],
131156
sess_args['DestHost'],

python/netsnmp/client_intf.c

+92
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,96 @@ netsnmp_create_session_v3(PyObject *self, PyObject *args)
13541354
return Py_BuildValue("i", (int)ss);
13551355
}
13561356

1357+
static PyObject *
1358+
netsnmp_create_session_tunneled(PyObject *self, PyObject *args)
1359+
{
1360+
int version;
1361+
char *peer;
1362+
int lport;
1363+
int retries;
1364+
int timeout;
1365+
char * sec_name;
1366+
int sec_level;
1367+
char * sec_eng_id;
1368+
char * context_eng_id;
1369+
char * context;
1370+
char * our_identity;
1371+
char * their_identity;
1372+
char * their_hostname;
1373+
char * trust_cert;
1374+
SnmpSession session = {0};
1375+
SnmpSession *ss = NULL;
1376+
int verbose = py_netsnmp_verbose();
1377+
1378+
if (!PyArg_ParseTuple(args, "isiiisissssss", &version,
1379+
&peer, &lport, &retries, &timeout,
1380+
&sec_name, &sec_level,
1381+
&context_eng_id, &context,
1382+
&our_identity, &their_identity,
1383+
&their_hostname, &trust_cert))
1384+
return NULL;
1385+
1386+
__libraries_init("python");
1387+
snmp_sess_init(&session);
1388+
1389+
if (version != 3) {
1390+
session.version = SNMP_VERSION_3;
1391+
if (verbose)
1392+
printf("Using version 3 as it's the only version that supports tunneling\n");
1393+
}
1394+
1395+
session.peername = peer;
1396+
session.retries = retries; /* 5 */
1397+
session.timeout = timeout; /* 1000000L */
1398+
session.contextNameLen = STRLEN(context);
1399+
session.contextName = context;
1400+
session.securityNameLen = STRLEN(sec_name);
1401+
session.securityName = sec_name;
1402+
session.securityLevel = sec_level;
1403+
session.securityModel = NETSNMP_TSM_SECURITY_MODEL;
1404+
1405+
/* create the transport configuration store */
1406+
if (!session.transport_configuration) {
1407+
netsnmp_container_init_list();
1408+
session.transport_configuration =
1409+
netsnmp_container_find("transport_configuration:fifo");
1410+
if (!session.transport_configuration) {
1411+
fprintf(stderr, "failed to initialize the transport configuration container\n");
1412+
return NULL;
1413+
}
1414+
1415+
session.transport_configuration->compare =
1416+
(netsnmp_container_compare*)
1417+
netsnmp_transport_config_compare;
1418+
}
1419+
1420+
if (our_identity && our_identity[0] != '\0')
1421+
CONTAINER_INSERT(session.transport_configuration,
1422+
netsnmp_transport_create_config("our_identity",
1423+
our_identity));
1424+
1425+
if (their_identity && their_identity[0] != '\0')
1426+
CONTAINER_INSERT(session.transport_configuration,
1427+
netsnmp_transport_create_config("their_identity",
1428+
their_identity));
1429+
1430+
if (their_hostname && their_hostname[0] != '\0')
1431+
CONTAINER_INSERT(session.transport_configuration,
1432+
netsnmp_transport_create_config("their_hostname",
1433+
their_hostname));
1434+
1435+
if (trust_cert && trust_cert[0] != '\0')
1436+
CONTAINER_INSERT(session.transport_configuration,
1437+
netsnmp_transport_create_config("trust_cert",
1438+
trust_cert));
1439+
1440+
ss = snmp_sess_open(&session);
1441+
1442+
if (!ss)
1443+
return NULL;
1444+
return Py_BuildValue("i", (int)ss);
1445+
}
1446+
13571447
static PyObject *
13581448
netsnmp_delete_session(PyObject *self, PyObject *args)
13591449
{
@@ -2539,6 +2629,8 @@ static PyMethodDef ClientMethods[] = {
25392629
"create a netsnmp session."},
25402630
{"session_v3", netsnmp_create_session_v3, METH_VARARGS,
25412631
"create a netsnmp session."},
2632+
{"session_tunneled", netsnmp_create_session_tunneled, METH_VARARGS,
2633+
"create a tunneled netsnmp session over tls, dtls or ssh."},
25422634
{"delete_session", netsnmp_delete_session, METH_VARARGS,
25432635
"create a netsnmp session."},
25442636
{"get", netsnmp_get, METH_VARARGS,

0 commit comments

Comments
 (0)