I was thinking about this again (see netsnmp-coders archive, same subject),
and would like to "merge" the com2sec solution with the rfc3584 co-existence
specfication, and at the same time satisfy the concerns MF had with my
previous ideas regarding transport-specific code.

I'd like any feedback on the plan I've outlined below,
so I don't go too far down the wrong track.
Some details I've left out for clarity, and others I've not worked out yet
are indicated.

1) broaden the com2sec directive definition for SOURCE to be one of:

a) "[:][/mask]"
-transport-specifier can be one of the (supported) transport domains
-transport-address would be parsed (along with transport-specifier)
in a similar fashion as the snmpd "LISTENING ADDRESS"
-mask would be a string understood by the specific transport domain
defining a proper subset of it, e.g. an IP subnet mask.

b) hostname
-provided for backwards compatibility, as well as usefulness.
-matches any (supported) transport domain
-hostname resolved to (tdomain-specific format) transport-address

c) "any"
-v1 and v2c community auth method will match for any
address in any supported transport domain

d) "default"
-For backward compatibility, but otherwise equal to "any"

2) com2sec6 and com2secunix would be deprecated.
For some period of time they would be parsed using the same
function as com2sec, with the appropriate tdomain.
Log messages noting their deprecation would be generated.

3) Move the parsing and com2sec data lists "up" from the tdomain-specific
code into snmplib/snmp_transport.c.

Side notes:
I believe Emi Yanagi's patch suffers from having moved the data "up".

I considered snmplib/vacm, but additional interfaces to snmp_transport
would have been needed, i.e. the resulting code ends up having more
to do with snmp_transport than vacm.
The same holds true for creating a new module, which would have
also added build configuration work.

The 3 existing tdomain-specific com2secEntry's would be
replaced by a list of snmpCommunityEntry, which would support
the implementation of SNMP-COMMUNITY-MIB::snmpCommunityTable:

typedef struct _snmpCommunityEntry {

* SNMP-COMMUNITY-MIB type: SnmpAdminString (SIZE(1..32))
* This is an IMPLIED index (ordering not determined by length).
* To be compatible with both SMIv1 and SMIv2, we will implement this
* by always using the same size. 4 seems like plenty. */
char snmpCommunityIndex[4];

char snmpCommunityName[COMMUNITY_MAX_LEN];

/* SNMP-COMMUNITY-MIB type: SnmpAdminString (SIZE(1..32)) */
char snmpCommunitySecurityName[33];

/* SNMP-COMMUNITY-MIB type: SnmpEngineID: SnmpAdminString (SIZE(1..32))
char snmpCommunityContextEngineID[SNMP_MAX_ENG_SIZE+1];

/* SnmpAdminString (SIZE(0..32)) */
char snmpCommunityContextName[33];

* SNMP-COMMUNITY-MIB type: SnmpTagValue: OCTET STRING (SIZE (0..255))
* This is what takes the place of the tdomain-specific
* data that existed before, e.g. for udp: network,mask. */
char snmpCommunityTransportTag[256];

* Can probably remove, but might be useful to save for debugging
char source[SNMP_MAXBUF_SMALL];

int snmpCommunityStorageType;
int snmpCommunityStatus;
struct _snmpCommunityEntry *next;
} snmpCommunityEntry;

4) If the SOURCE of the com2sec directive is "any", e.g.
"com2sec -Cn myContext mySecurityName any myCommunityName",
then the resulting snmpCommunityEntry would be:

snmpCommunityName <== myCommunityName
snmpCommunitySecurityName <== mySecurityName
snmpCommunityTransportTag <== ""
snmpCommunityStorageType <== ST_PERMANENT
snmpCommunityStatus <== RS_ACTIVE
snmpCommunityContextName <== myContext
snmpCommunityContextEngineID <== snmpv3_get_engineID()
// Extend com2sec later to support this?
snmpCommunityIndex <== nextUnique()

5) provide accessor functions for the mib implementation.

6) Support for SOURCE != "any".
Here is where it gets a bit complicated.

a) The tdomain-neutral com2sec config handler will need help from
tdomain-specific functions to error-check and parse the directive.
Code similar to what it is netsnmp_tdomain_transport_full can be
used in part. I'll leave the details out for now, but the parsing
results in these 3 items:
-address (in domain-specific format)
-mask (in domain-specific format)

b) generate a unique snmpCommunityTransportTag to be
used in selecting snmpTargetAddrEntry's.
Using snmpCommunityIndex is convenient.

c) create (unless there are already matchingentries) 2 entries in the
target data list, corrosponding target params data list, and
targetAddrExtEntry data list:
one for SNMPv1 use and one for SNMPv2c use.

I'll use SNMP-TARGET-MIB naming rather than the existing

snmpTargetParamsName <== nextUnique()
// I haven't worked out the details for nextUnique() yet.
// Perhaps it could just be derived from snmpCommunityIndex,
// but I worry about conflicting with other uses of this table,
// (notifications most notably).

snmpTargetParamsMPModel <== SNMP_MP_MODEL_SNMPv1 -or-

snmpTargetParamsSecurityModel <== SNMP_SEC_MODEL_SNMPv1 -or-

snmpTargetParamsSecurityName <== mySecurityName
snmpTargetParamsSecurityLevel <== SNMP_SEC_LEVEL_NOAUTH
snmpTargetParamsStorageType <== PERM
snmpTargetParamsRowStatus <== active

snmpTargetAddrName <== nextUnique()
// Same as snmpTargetParamsName ?

snmpTargetAddrTDomain <== domain from a) above
snmpTargetAddrTAddress <== address from a) above

snmpTargetAddrTimeout <== DEFVAL=1500
// Will be ignored for the purpose of auth
snmpTargetAddrRetryCount <== DEFVAL=3
// Will be ignored for the purpose of auth

snmpTargetAddrTagList <== snmpCommunityTransportTag
// Note: append tag to any existing snmpTargetAddrTagList

snmpTargetAddrParams <== snmpTargetParamsName
snmpTargetAddrStorageType <== ST_PERMANENT
snmpTargetAddrRowStatus <== RS_ACTIVE

//These 2 are in the new, snmpTargetAddrExtEntry:
snmpTargetAddrTMask <== mask from a) above
snmpTargetAddrMMS <== DEFVAL=484
// Will be ignored for the purpose of auth

targetAddrTable_struct also defines a couple of
session-related vars, which we will leave NULL.

7) auth for SNMPv1/v2c
In agent/mibgroup/mibII/vacm_conf.c, we can consolidate calls to
tdomain-specific _getSecName functions into one tdomain-neutral call,
which delegates, where needed, to appropriate tdomain functions,
based on pdu contents. In particular, it would call:

a) netsnmp_transport_check_pdu_transport_data(pdu)
-Called before searching snmpCommunityEntry list.
-Delegates to tdomain-specific calls.

b) netsnmp_transport_match(pdu,snmpCommunityEntry)
-Called inside search loop (in addition to snmpCommunityName matching).
-Delegates to tdomain-specific calls.

The tdomain-specific functions would make use of data stored in the
snmpCommunityEntry, and any snmpTargetAddr{Ext}Entry found containing
snmpCommunityTransportTag in its' snmpTargetAddrTagList.

That's enough to review the general direction of the plan.
In particular, I haven't thought through the functionality of proxy/subagent.

I'd like to provide write support for snmpCommunityTable as well,
which requires the definition of a persistent version of com2sec, pcom2sec.
That paves the way for an app that would do at runtime what com2sec
does at init time, complementing snmpusm.

Support for tdomains that don't have it now would be left for the
experts of each.


This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
Net-snmp-coders mailing list