00001
00002
00003
00004
00005 #include <net-snmp/net-snmp-config.h>
00006 #include <stdio.h>
00007 #include <ctype.h>
00008 #if HAVE_STDLIB_H
00009 #include <stdlib.h>
00010 #endif
00011 #if HAVE_STRING_H
00012 #include <string.h>
00013 #else
00014 #include <strings.h>
00015 #endif
00016 #if HAVE_UNISTD_H
00017 #include <unistd.h>
00018 #endif
00019
00020 #if HAVE_DMALLOC_H
00021 #include <dmalloc.h>
00022 #endif
00023
00024 #include <net-snmp/types.h>
00025 #include <net-snmp/output_api.h>
00026 #include <net-snmp/config_api.h>
00027 #include <net-snmp/utilities.h>
00028
00029 #include <net-snmp/library/snmp_api.h>
00030 #include <net-snmp/library/snmp_enum.h>
00031 #include <net-snmp/library/callback.h>
00032 #include <net-snmp/library/snmp_secmod.h>
00033 #include <net-snmp/library/snmpusm.h>
00034
00035 static struct snmp_secmod_list *registered_services = NULL;
00036
00037 static SNMPCallback set_default_secmod;
00038
00039 void
00040 init_secmod(void)
00041 {
00042 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
00043 SNMP_CALLBACK_SESSION_INIT, set_default_secmod,
00044 NULL);
00045
00046 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defSecurityModel",
00047 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECMODEL);
00048
00049
00050
00051 #include "snmpsm_init.h"
00052 }
00053
00054
00055 int
00056 register_sec_mod(int secmod, const char *modname,
00057 struct snmp_secmod_def *newdef)
00058 {
00059 int result;
00060 struct snmp_secmod_list *sptr;
00061 char *othername;
00062
00063 for (sptr = registered_services; sptr; sptr = sptr->next) {
00064 if (sptr->securityModel == secmod) {
00065 return SNMPERR_GENERR;
00066 }
00067 }
00068 sptr = SNMP_MALLOC_STRUCT(snmp_secmod_list);
00069 if (sptr == NULL)
00070 return SNMPERR_MALLOC;
00071 sptr->secDef = newdef;
00072 sptr->securityModel = secmod;
00073 sptr->next = registered_services;
00074 registered_services = sptr;
00075 if ((result =
00076 se_add_pair_to_slist("snmp_secmods", strdup(modname), secmod))
00077 != SE_OK) {
00078 switch (result) {
00079 case SE_NOMEM:
00080 snmp_log(LOG_CRIT, "snmp_secmod: no memory\n");
00081 break;
00082
00083 case SE_ALREADY_THERE:
00084 othername = se_find_label_in_slist("snmp_secmods", secmod);
00085 if (strcmp(othername, modname) != 0) {
00086 snmp_log(LOG_ERR,
00087 "snmp_secmod: two security modules %s and %s registered with the same security number\n",
00088 modname, othername);
00089 }
00090 break;
00091
00092 default:
00093 snmp_log(LOG_ERR,
00094 "snmp_secmod: unknown error trying to register a new security module\n");
00095 break;
00096 }
00097 return SNMPERR_GENERR;
00098 }
00099 return SNMPERR_SUCCESS;
00100 }
00101
00102 int
00103 unregister_sec_mod(int secmod)
00104 {
00105 struct snmp_secmod_list *sptr, *lptr;
00106
00107 for (sptr = registered_services, lptr = NULL; sptr;
00108 lptr = sptr, sptr = sptr->next) {
00109 if (sptr->securityModel == secmod) {
00110 if ( lptr )
00111 lptr->next = sptr->next;
00112 else
00113 registered_services = sptr->next;
00114 SNMP_FREE(sptr->secDef);
00115 SNMP_FREE(sptr);
00116 return SNMPERR_SUCCESS;
00117 }
00118 }
00119
00120
00121
00122 return SNMPERR_GENERR;
00123 }
00124
00125 void
00126 clear_sec_mod(void)
00127 {
00128 struct snmp_secmod_list *tmp = registered_services, *next = NULL;
00129
00130 while (tmp != NULL) {
00131 next = tmp->next;
00132 SNMP_FREE(tmp->secDef);
00133 SNMP_FREE(tmp);
00134 tmp = next;
00135 }
00136 registered_services = NULL;
00137 }
00138
00139
00140 struct snmp_secmod_def *
00141 find_sec_mod(int secmod)
00142 {
00143 struct snmp_secmod_list *sptr;
00144
00145 for (sptr = registered_services; sptr; sptr = sptr->next) {
00146 if (sptr->securityModel == secmod) {
00147 return sptr->secDef;
00148 }
00149 }
00150
00151
00152
00153 return NULL;
00154 }
00155
00156 static int
00157 set_default_secmod(int major, int minor, void *serverarg, void *clientarg)
00158 {
00159 netsnmp_session *sess = (netsnmp_session *) serverarg;
00160 char *cptr;
00161 int model;
00162
00163 if (!sess)
00164 return SNMPERR_GENERR;
00165 if (sess->securityModel == SNMP_DEFAULT_SECMODEL) {
00166 if ((cptr = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
00167 NETSNMP_DS_LIB_SECMODEL)) != NULL) {
00168 if ((model = se_find_value_in_slist("snmp_secmods", cptr))
00169 != SE_DNE) {
00170 sess->securityModel = model;
00171 } else {
00172 snmp_log(LOG_ERR,
00173 "unknown security model name: %s. Forcing USM instead.\n",
00174 cptr);
00175 sess->securityModel = USM_SEC_MODEL_NUMBER;
00176 return SNMPERR_GENERR;
00177 }
00178 } else {
00179 sess->securityModel = USM_SEC_MODEL_NUMBER;
00180 }
00181 }
00182 return SNMPERR_SUCCESS;
00183 }