net-snmp 5.7
|
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/snmpv3-security-includes.h> 00034 00035 #include <net-snmp/net-snmp-features.h> 00036 00037 static struct snmp_secmod_list *registered_services = NULL; 00038 00039 static SNMPCallback set_default_secmod; 00040 00041 void 00042 init_secmod(void) 00043 { 00044 snmp_register_callback(SNMP_CALLBACK_LIBRARY, 00045 SNMP_CALLBACK_SESSION_INIT, set_default_secmod, 00046 NULL); 00047 00048 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defSecurityModel", 00049 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECMODEL); 00050 /* 00051 * this file is generated by configure for all the stuff we're using 00052 */ 00053 #include "snmpsm_init.h" 00054 } 00055 00056 void 00057 shutdown_secmod(void) 00058 { 00059 #include "snmpsm_shutdown.h" 00060 } 00061 00062 int 00063 register_sec_mod(int secmod, const char *modname, 00064 struct snmp_secmod_def *newdef) 00065 { 00066 int result; 00067 struct snmp_secmod_list *sptr; 00068 char *othername; 00069 00070 for (sptr = registered_services; sptr; sptr = sptr->next) { 00071 if (sptr->securityModel == secmod) { 00072 return SNMPERR_GENERR; 00073 } 00074 } 00075 sptr = SNMP_MALLOC_STRUCT(snmp_secmod_list); 00076 if (sptr == NULL) 00077 return SNMPERR_MALLOC; 00078 sptr->secDef = newdef; 00079 sptr->securityModel = secmod; 00080 sptr->next = registered_services; 00081 registered_services = sptr; 00082 if ((result = 00083 se_add_pair_to_slist("snmp_secmods", strdup(modname), secmod)) 00084 != SE_OK) { 00085 switch (result) { 00086 case SE_NOMEM: 00087 snmp_log(LOG_CRIT, "snmp_secmod: no memory\n"); 00088 break; 00089 00090 case SE_ALREADY_THERE: 00091 othername = se_find_label_in_slist("snmp_secmods", secmod); 00092 if (strcmp(othername, modname) != 0) { 00093 snmp_log(LOG_ERR, 00094 "snmp_secmod: two security modules %s and %s registered with the same security number\n", 00095 modname, othername); 00096 } 00097 break; 00098 00099 default: 00100 snmp_log(LOG_ERR, 00101 "snmp_secmod: unknown error trying to register a new security module\n"); 00102 break; 00103 } 00104 return SNMPERR_GENERR; 00105 } 00106 return SNMPERR_SUCCESS; 00107 } 00108 00109 netsnmp_feature_child_of(unregister_sec_mod, netsnmp_unused) 00110 #ifndef NETSNMP_FEATURE_REMOVE_UNREGISTER_SEC_MOD 00111 int 00112 unregister_sec_mod(int secmod) 00113 { 00114 struct snmp_secmod_list *sptr, *lptr; 00115 00116 for (sptr = registered_services, lptr = NULL; sptr; 00117 lptr = sptr, sptr = sptr->next) { 00118 if (sptr->securityModel == secmod) { 00119 if ( lptr ) 00120 lptr->next = sptr->next; 00121 else 00122 registered_services = sptr->next; 00123 SNMP_FREE(sptr->secDef); 00124 SNMP_FREE(sptr); 00125 return SNMPERR_SUCCESS; 00126 } 00127 } 00128 /* 00129 * not registered 00130 */ 00131 return SNMPERR_GENERR; 00132 } 00133 #endif /* NETSNMP_FEATURE_REMOVE_UNREGISTER_SEC_MOD */ 00134 00135 void 00136 clear_sec_mod(void) 00137 { 00138 struct snmp_secmod_list *tmp = registered_services, *next = NULL; 00139 00140 while (tmp != NULL) { 00141 next = tmp->next; 00142 SNMP_FREE(tmp->secDef); 00143 SNMP_FREE(tmp); 00144 tmp = next; 00145 } 00146 registered_services = NULL; 00147 } 00148 00149 00150 struct snmp_secmod_def * 00151 find_sec_mod(int secmod) 00152 { 00153 struct snmp_secmod_list *sptr; 00154 00155 for (sptr = registered_services; sptr; sptr = sptr->next) { 00156 if (sptr->securityModel == secmod) { 00157 return sptr->secDef; 00158 } 00159 } 00160 /* 00161 * not registered 00162 */ 00163 return NULL; 00164 } 00165 00166 /* try to pick a reasonable security module default based on what was 00167 compiled into the net-snmp package */ 00168 #ifdef USM_SEC_MODEL_NUMBER 00169 #define NETSNMP_SECMOD_DEFAULT_MODEL USM_SEC_MODEL_NUMBER 00170 #elif defined(TSM_SEC_MODEL_NUMBER) 00171 #define NETSNMP_SECMOD_DEFAULT_MODEL TSM_SEC_MODEL_NUMBER 00172 #elif defined(KSM_SEC_MODEL_NUMBER) 00173 #define NETSNMP_SECMOD_DEFAULT_MODEL KSM_SEC_MODEL_NUMBER 00174 #else 00175 /* else we give up and leave it blank */ 00176 #define NETSNMP_SECMOD_DEFAULT_MODEL -1 00177 #endif 00178 00179 static int 00180 set_default_secmod(int major, int minor, void *serverarg, void *clientarg) 00181 { 00182 netsnmp_session *sess = (netsnmp_session *) serverarg; 00183 char *cptr; 00184 int model; 00185 00186 if (!sess) 00187 return SNMPERR_GENERR; 00188 if (sess->securityModel == SNMP_DEFAULT_SECMODEL) { 00189 if ((cptr = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 00190 NETSNMP_DS_LIB_SECMODEL)) != NULL) { 00191 if ((model = se_find_value_in_slist("snmp_secmods", cptr)) 00192 != SE_DNE) { 00193 sess->securityModel = model; 00194 } else { 00195 snmp_log(LOG_ERR, 00196 "unknown security model name: %s. Forcing USM instead.\n", 00197 cptr); 00198 sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL; 00199 return SNMPERR_GENERR; 00200 } 00201 } else { 00202 sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL; 00203 } 00204 } 00205 return SNMPERR_SUCCESS; 00206 }