net-snmp
5.4.1
|
00001 /* 00002 * snmplocalsm.c 00003 * 00004 * This code implements a security model that assumes the local user 00005 * that executed the agent is the user who's attributes called 00006 */ 00007 00008 #include <net-snmp/net-snmp-config.h> 00009 00010 #include <net-snmp/net-snmp-includes.h> 00011 00012 #include <net-snmp/library/snmplocalsm.h> 00013 00014 #include <unistd.h> 00015 00016 static int localsm_session_init(netsnmp_session *); 00017 static void localsm_free_state_ref(void *); 00018 static int localsm_free_pdu(netsnmp_pdu *); 00019 static int localsm_clone_pdu(netsnmp_pdu *, netsnmp_pdu *); 00020 00021 u_int next_sess_id = 1; 00022 00024 void 00025 init_localsm(void) 00026 { 00027 struct snmp_secmod_def *def; 00028 int ret; 00029 00030 def = SNMP_MALLOC_STRUCT(snmp_secmod_def); 00031 00032 if (!def) { 00033 snmp_log(LOG_ERR, 00034 "Unable to malloc snmp_secmod struct, not registering LOCALSM\n"); 00035 return; 00036 } 00037 00038 def->encode_reverse = localsm_rgenerate_out_msg; 00039 def->decode = localsm_process_in_msg; 00040 def->session_open = localsm_session_init; 00041 def->pdu_free_state_ref = localsm_free_state_ref; 00042 def->pdu_free = localsm_free_pdu; 00043 def->pdu_clone = localsm_clone_pdu; 00044 00045 DEBUGMSGTL(("localsm","registering ourselves\n")); 00046 ret = register_sec_mod(NETSNMP_LOCALSM_SECURITY_MODEL, "localsm", def); 00047 DEBUGMSGTL(("localsm"," returned %d\n", ret)); 00048 } 00049 00050 /* 00051 * Initialize specific session information (right now, just set up things to 00052 * not do an engineID probe) 00053 */ 00054 00055 static int 00056 localsm_session_init(netsnmp_session * sess) 00057 { 00058 DEBUGMSGTL(("localsm", 00059 "LOCALSM: Reached our session initialization callback\n")); 00060 00061 sess->flags |= SNMP_FLAGS_DONT_PROBE; 00062 00063 /* XXX: likely needed for something: */ 00064 /* 00065 localsmsession = sess->securityInfo = 00066 if (!localsmsession) 00067 return SNMPERR_GENERR; 00068 */ 00069 00070 return SNMPERR_SUCCESS; 00071 } 00072 00074 static void 00075 localsm_free_state_ref(void *ptr) 00076 { 00077 free(ptr); 00078 } 00079 00081 static int 00082 localsm_free_pdu(netsnmp_pdu *pdu) 00083 { 00084 return SNMPERR_SUCCESS; 00085 } 00086 00088 static int 00089 localsm_clone_pdu(netsnmp_pdu *pdu, netsnmp_pdu *pdu2) 00090 { 00091 return SNMPERR_SUCCESS; 00092 } 00093 00094 /* asn.1 easing definitions */ 00095 #define LOCALSMBUILD_OR_ERR(fun, args, msg, desc) \ 00096 DEBUGDUMPHEADER("send", desc); \ 00097 rc = fun args; \ 00098 DEBUGINDENTLESS(); \ 00099 if (rc == 0) { \ 00100 DEBUGMSGTL(("localsm",msg)); \ 00101 retval = SNMPERR_TOO_LONG; \ 00102 goto outerr; \ 00103 } 00104 00105 #define BUILD_START_SEQ tmpoffset = *offset; 00106 00107 #define BUILD_END_SEQ(x) LOCALSMBUILD_OR_ERR(asn_realloc_rbuild_sequence, \ 00108 (wholeMsg, wholeMsgLen, offset, 1, \ 00109 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), \ 00110 *offset - tmpoffset), \ 00111 x, "sequence"); 00112 00113 /**************************************************************************** 00114 * 00115 * localsm_generate_out_msg 00116 * 00117 * Parameters: 00118 * (See list below...) 00119 * 00120 * Returns: 00121 * SNMPERR_SUCCESS On success. 00122 * ... and others 00123 * 00124 * 00125 * Generate an outgoing message. 00126 * 00127 ****************************************************************************/ 00128 00129 int 00130 localsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms) 00131 { 00132 u_char **wholeMsg = parms->wholeMsg; 00133 size_t *offset = parms->wholeMsgOffset; 00134 int rc; 00135 00136 size_t *wholeMsgLen = parms->wholeMsgLen; 00137 00138 00139 DEBUGMSGTL(("localsm", "Starting LOCALSM processing\n")); 00140 00141 00142 /* 00143 * We define here what the security message section will look like: 00144 * 04 00 -- null string 00145 * XXX: need to actually negotiate a context engine ID? 00146 * XXX: leave room for future expansion just in case? 00147 */ 00148 DEBUGDUMPHEADER("send", "localsm security parameters"); 00149 rc = asn_realloc_rbuild_header(wholeMsg, wholeMsgLen, offset, 1, 00150 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE 00151 | ASN_OCTET_STR), 0); 00152 DEBUGINDENTLESS(); 00153 if (rc == 0) { 00154 DEBUGMSGTL(("localsm", "building msgSecurityParameters failed.\n")); 00155 return SNMPERR_TOO_LONG; 00156 } 00157 00158 /* 00159 * Copy in the msgGlobalData and msgVersion. 00160 */ 00161 while ((*wholeMsgLen - *offset) < parms->globalDataLen) { 00162 if (!asn_realloc(wholeMsg, wholeMsgLen)) { 00163 DEBUGMSGTL(("localsm", "building global data failed.\n")); 00164 return SNMPERR_TOO_LONG; 00165 } 00166 } 00167 00168 *offset += parms->globalDataLen; 00169 memcpy(*wholeMsg + *wholeMsgLen - *offset, 00170 parms->globalData, parms->globalDataLen); 00171 00172 /* 00173 * Total packet sequence. 00174 */ 00175 rc = asn_realloc_rbuild_sequence(wholeMsg, wholeMsgLen, offset, 1, 00176 (u_char) (ASN_SEQUENCE | 00177 ASN_CONSTRUCTOR), *offset); 00178 if (rc == 0) { 00179 DEBUGMSGTL(("localsm", "building master packet sequence failed.\n")); 00180 return SNMPERR_TOO_LONG; 00181 } 00182 00183 DEBUGMSGTL(("localsm", "LOCALSM processing completed.\n")); 00184 return SNMPERR_SUCCESS; 00185 } 00186 00187 /**************************************************************************** 00188 * 00189 * localsm_process_in_msg 00190 * 00191 * Parameters: 00192 * (See list below...) 00193 * 00194 * Returns: 00195 * LOCALSM_ERR_NO_ERROR On success. 00196 * LOCALSM_ERR_GENERIC_ERROR 00197 * LOCALSM_ERR_UNSUPPORTED_SECURITY_LEVEL 00198 * 00199 * 00200 * Processes an incoming message. 00201 * 00202 ****************************************************************************/ 00203 00204 int 00205 localsm_process_in_msg(struct snmp_secmod_incoming_params *parms) 00206 { 00207 u_char type_value; 00208 size_t octet_string_length; 00209 u_char *data_ptr; 00210 00211 /* we don't have one, so set it to 0 */ 00212 parms->secEngineID = strdup(""); 00213 *parms->secEngineIDLen = 0; 00214 00215 /* if this did not come through a tunneled connection, this 00216 security model is in appropriate (and would be a HUGE security 00217 hole to assume otherwise) */ 00218 DEBUGMSGTL(("localsm","checking how we got here\n")); 00219 if (!(parms->pdu->flags & UCD_MSG_FLAG_TUNNELED)) { 00220 DEBUGMSGTL(("localsm"," not tunneled\n")); 00221 return SNMPERR_USM_AUTHENTICATIONFAILURE; 00222 } else { 00223 DEBUGMSGTL(("localsm"," tunneled\n")); 00224 } 00225 00226 00227 /* 00228 * Eat the first octet header. 00229 */ 00230 if ((data_ptr = asn_parse_sequence(parms->secParams, &octet_string_length, 00231 &type_value, 00232 (ASN_UNIVERSAL | ASN_PRIMITIVE | 00233 ASN_OCTET_STR), 00234 "usm first octet")) == NULL) { 00235 /* 00236 * RETURN parse error 00237 */ 00238 return -1; 00239 } 00240 strncpy(parms->secName, strdup(getenv("USER")), *parms->secNameLen); 00241 *parms->secNameLen = strlen(parms->secName); 00242 DEBUGMSGTL(("localsm", "user: %s/%d\n", parms->secName, parms->secNameLen)); 00243 00244 *parms->scopedPdu = data_ptr; 00245 *parms->scopedPduLen = parms->wholeMsgLen - (data_ptr - parms->wholeMsg); 00246 *parms->maxSizeResponse = parms->maxMsgSize; /* XXX */ 00247 parms->secEngineID = strdup(""); 00248 *parms->secEngineIDLen = 0; 00249 parms->secLevel = SNMP_SEC_LEVEL_NOAUTH; 00250 /* 00251 * maybe set this based on the transport in the future: 00252 * 00253 */ 00254 00255 if (octet_string_length != 0) 00256 return -1; 00257 00258 return SNMPERR_SUCCESS; 00259 }