00001
00002
00003
00004
00005
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
00052
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
00064
00065
00066
00067
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
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
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
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
00144
00145
00146
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
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
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
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
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
00212 parms->secEngineID = strdup("");
00213 *parms->secEngineIDLen = 0;
00214
00215
00216
00217
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
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
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;
00247 parms->secEngineID = strdup("");
00248 *parms->secEngineIDLen = 0;
00249 parms->secLevel = SNMP_SEC_LEVEL_NOAUTH;
00250
00251
00252
00253
00254
00255 if (octet_string_length != 0)
00256 return -1;
00257
00258 return SNMPERR_SUCCESS;
00259 }