net-snmp
5.4.1
|
00001 /* 00002 * security service wrapper to support pluggable security models 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 * this file is generated by configure for all the stuff we're using 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 * not registered 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 * not registered 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 }