snmplocalsm.c

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 }

net-snmpに対してSat Sep 5 13:14:26 2009に生成されました。  doxygen 1.4.7