int
agentx_register(netsnmp_session * ss, oid start[], size_t startlen,
                int priority, int range_subid, oid range_ubound,
                int timeout, u_char flags, const char *contextName)
{
    netsnmp_pdu    *pdu, *response;

    DEBUGMSGTL(("agentx/subagent", "registering: "));
    DEBUGMSGOIDRANGE(("agentx/subagent", start, startlen, range_subid,
                      range_ubound));
    DEBUGMSG(("agentx/subagent", "\n"));

    if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
        return 0;
    }

    pdu = snmp_pdu_create(AGENTX_MSG_REGISTER);
    if (pdu == NULL) {
        return 0;
    }
    pdu->time = timeout;
    pdu->priority = priority;
    pdu->sessid = ss->sessid;
    pdu->range_subid = range_subid;
    if (contextName) {
        pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT;
        pdu->community = strdup(contextName);
        pdu->community_len = strlen(contextName);
    }

    if (flags & FULLY_QUALIFIED_INSTANCE) {
        pdu->flags |= AGENTX_MSG_FLAG_INSTANCE_REGISTER;
    }

    if (range_subid) {
        snmp_pdu_add_variable(pdu, start, startlen, ASN_OBJECT_ID,
                              (u_char *) start, startlen * sizeof(oid));
        pdu->variables->val.objid[range_subid - 1] = range_ubound;
    } else {
        snmp_add_null_var(pdu, start, startlen);
    }

    if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS) {
        DEBUGMSGTL(("agentx/subagent", "registering failed!\n"));
        return 0;
    }

    if (response->errstat != SNMP_ERR_NOERROR) {
        snmp_log(LOG_ERR,"registering pdu failed: %d!\n", response->errstat);
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    DEBUGMSGTL(("agentx/subagent", "registered\n"));
    return 1;
}
Пример #2
0
/** Write on/off status
*/
double  setMainSwitch(HSNMP m_sessp,float value) {
  struct snmp_pdu* pdu = snmp_pdu_create(SNMP_MSG_SET);    // prepare set-request pdu
  pdu->community = (u_char*)strdup(writeCommunity);
  pdu->community_len = strlen(writeCommunity);

  // for(each SET request to one crate) {
  int v = (int) value;
  snmp_pdu_add_variable(pdu,oidSysMainSwitch,lengthSysMainSwitch,ASN_INTEGER,(u_char*)&v,sizeof(v));
  // } // endfor

  struct snmp_pdu* response;
	int status = snmp_sess_synch_response(m_sessp,pdu,&response);

  /*
  * Process the response.
  */

  if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
    /*
    * SUCCESS: Print the result variables
    */
    struct variable_list *vars;
    
    // debug print
    //for(vars = response->variables; vars; vars = vars->next_variable)
    //  print_variable(vars->name, vars->name_length, vars);

    /* manipuate the information ourselves */
    for(vars = response->variables; vars; vars = vars->next_variable) {
			if (vars->type == ASN_OPAQUE_FLOAT) {				    // 0x78
        value = *vars->val.floatVal;
      }
			else if (vars->type == ASN_OPAQUE_DOUBLE) {			// 0x79
        value = *vars->val.doubleVal;
      }
			else if(vars->type == ASN_INTEGER) {				      // 0x02
				value = (double)*vars->val.integer;
      }
    }
  } else {
    /*
    * FAILURE: print what went wrong!
    */

    if (status == STAT_SUCCESS)
      fprintf(stderr, "Error in packet\nReason: %s\n",
      snmp_errstring(response->errstat));
    else
      snmp_sess_perror("snmpget",snmp_sess_session(m_sessp));
    return 0;
  }
  snmp_free_pdu(response);


  return value;
}
Пример #3
0
static inline void add_field (
	netsnmp_pdu *trap_pdu,
	u_char asn_type,
	const char *prefix,
	void *value,
	size_t value_size)
{
	oid _oid[MAX_OID_LEN];
	size_t _oid_len = MAX_OID_LEN;
	if (snmp_parse_oid(prefix, _oid, &_oid_len)) {
		snmp_pdu_add_variable (trap_pdu, _oid, _oid_len, asn_type, (u_char *) value, value_size);
	}
}
Пример #4
0
static void
OpeningEntry(UNUSED tState self)
{
    netsnmp_pdu* act =
        pdu_create_opt_context(AGENTX_MSG_OPEN, context, contextLen);
    if(act) {
        act->sessid = 0;
        act->transid = 0;
        act->reqid = ++packetid;
        act->time = 0;
        snmp_pdu_add_variable(act, NULL, 0, ASN_OCTET_STR, NULL, 0);
        if(snmp_sess_send(sessp, act) == 0)
            snmp_free_pdu(act);
    }
}
Пример #5
0
int
agentx_register( struct snmp_session *ss, oid start[], size_t startlen,
                 int priority, int range_subid, oid range_ubound)
{
    struct snmp_pdu *pdu, *response;

    DEBUGMSGTL(("agentx/subagent","registering: "));
    DEBUGMSGOID(("agentx/subagent", start, startlen));
    DEBUGMSG(("agentx/subagent","\n"));
    if (! IS_AGENTX_VERSION( ss->version ))
        return 0;

    pdu = snmp_pdu_create(AGENTX_MSG_REGISTER);
    if ( pdu == NULL )
        return 0;
    pdu->time = 0;
    pdu->priority = priority;
    pdu->sessid = ss->sessid;
    pdu->range_subid = range_subid;
    if ( range_subid ) {
        snmp_pdu_add_variable( pdu, start, startlen,
                               ASN_OBJECT_ID, (u_char *)start, startlen);
        pdu->variables->val.objid[ range_subid-1 ] = range_ubound;
    }
    else
        snmp_add_null_var( pdu, start, startlen);

    if ( agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS ) {
        DEBUGMSGTL(("agentx/subagent","registering failed!\n"));
        return 0;
    }

    if ( response->errstat != SNMP_ERR_NOERROR ) {
        DEBUGMSGTL(("agentx/subagent","registering pdu failed: %d!\n",
                    response->errstat));
        snmp_free_pdu(response);
        return 0;
    }

    snmp_free_pdu(response);
    DEBUGMSGTL(("agentx/subagent","registered\n"));
    return 1;
}
Пример #6
0
/*
 *
 * AgentX State diagram.  [mode] = internal mode it's mapped from:
 *
 * TESTSET -success-> COMMIT -success-> CLEANUP
 * [RESERVE1]         [ACTION]          [COMMIT]
 *    |                 |
 *    |                 \--failure-> UNDO
 *    |                              [UNDO]
 *    |
 *     --failure-> CLEANUP
 *                 [FREE]
 */
int
agentx_master_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{
    netsnmp_session *ax_session = (netsnmp_session *) handler->myvoid;
    netsnmp_request_info *request = requests;
    netsnmp_pdu    *pdu;
    void           *cb_data;
    int             result;

    DEBUGMSGTL(("agentx/master",
                "agentx master handler starting, mode = 0x%02x\n",
                reqinfo->mode));

    if (!ax_session) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }        

    /*
     * build a new pdu based on the pdu type coming in 
     */
    switch (reqinfo->mode) {
    case MODE_GET:
        pdu = snmp_pdu_create(AGENTX_MSG_GET);
        break;

    case MODE_GETNEXT:
        pdu = snmp_pdu_create(AGENTX_MSG_GETNEXT);
        break;

    case MODE_GETBULK:         /* WWWXXX */
        pdu = snmp_pdu_create(AGENTX_MSG_GETNEXT);
        break;

    case MODE_SET_RESERVE1:
        pdu = snmp_pdu_create(AGENTX_MSG_TESTSET);
        break;

    case MODE_SET_RESERVE2:
        /*
         * don't do anything here for AgentX.  Assume all is fine
         * and go on since AgentX only has one test phase. 
         */
        return SNMP_ERR_NOERROR;

    case MODE_SET_ACTION:
        pdu = snmp_pdu_create(AGENTX_MSG_COMMITSET);
        break;

    case MODE_SET_UNDO:
        pdu = snmp_pdu_create(AGENTX_MSG_UNDOSET);
        break;

    case MODE_SET_COMMIT:
    case MODE_SET_FREE:
        pdu = snmp_pdu_create(AGENTX_MSG_CLEANUPSET);
        break;

    default:
        snmp_log(LOG_WARNING,
                 "unsupported mode for agentx/master called\n");
        return SNMP_ERR_NOERROR;
    }

    if (!pdu) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }

    pdu->version = AGENTX_VERSION_1;
    pdu->reqid = snmp_get_next_transid();
    pdu->transid = reqinfo->asp->pdu->transid;
    pdu->sessid = ax_session->subsession->sessid;
    if (reginfo->contextName) {
        pdu->community = (u_char *) strdup(reginfo->contextName);
        pdu->community_len = strlen(reginfo->contextName);
        pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT;
    }
    if (ax_session->subsession->flags & AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER)
        pdu->flags |= AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER;

    while (request) {

        size_t nlen = request->requestvb->name_length;
        oid   *nptr = request->requestvb->name;
        
        DEBUGMSGTL(("agentx/master","request for variable ("));
        DEBUGMSGOID(("agentx/master", nptr, nlen));
        DEBUGMSG(("agentx/master", ")\n"));
        
        /*
         * loop through all the requests and create agentx ones out of them 
         */

        if (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK) {

            if (snmp_oid_compare(nptr, nlen, request->subtree->start_a,
                                 request->subtree->start_len) < 0) {
                DEBUGMSGTL(("agentx/master","inexact request preceeding region ("));
                DEBUGMSGOID(("agentx/master", request->subtree->start_a,
                             request->subtree->start_len));
                DEBUGMSG(("agentx/master", ")\n"));
                nptr = request->subtree->start_a;
                nlen = request->subtree->start_len;
                request->inclusive = 1;
            }

            if (request->inclusive) {
                DEBUGMSGTL(("agentx/master", "INCLUSIVE varbind "));
                DEBUGMSGOID(("agentx/master", nptr, nlen));
                DEBUGMSG(("agentx/master", " scoped to "));
                DEBUGMSGOID(("agentx/master", request->range_end,
                             request->range_end_len));
                DEBUGMSG(("agentx/master", "\n"));
                snmp_pdu_add_variable(pdu, nptr, nlen, ASN_PRIV_INCL_RANGE,
                                      (u_char *) request->range_end,
                                      request->range_end_len *
                                      sizeof(oid));
                request->inclusive = 0;
            } else {
                DEBUGMSGTL(("agentx/master", "EXCLUSIVE varbind "));
                DEBUGMSGOID(("agentx/master", nptr, nlen));
                DEBUGMSG(("agentx/master", " scoped to "));
                DEBUGMSGOID(("agentx/master", request->range_end,
                             request->range_end_len));
                DEBUGMSG(("agentx/master", "\n"));
                snmp_pdu_add_variable(pdu, nptr, nlen, ASN_PRIV_EXCL_RANGE,
                                      (u_char *) request->range_end,
                                      request->range_end_len *
                                      sizeof(oid));
            }
        } else {
            snmp_pdu_add_variable(pdu, request->requestvb->name,
                                  request->requestvb->name_length,
                                  request->requestvb->type,
                                  request->requestvb->val.string,
                                  request->requestvb->val_len);
        }

        /*
         * mark the request as delayed 
         */
        if (pdu->command != AGENTX_MSG_CLEANUPSET)
            request->delegated = REQUEST_IS_DELEGATED;
        else
            request->delegated = REQUEST_IS_NOT_DELEGATED;

        /*
         * next... 
         */
        request = request->next;
    }

    /*
     * When the master sends a CleanupSet PDU, it will never get a response
     * back from the subagent. So we shouldn't allocate the
     * netsnmp_delegated_cache structure in this case.
     */
    if (pdu->command != AGENTX_MSG_CLEANUPSET)
        cb_data = netsnmp_create_delegated_cache(handler, reginfo,
                                                 reqinfo, requests,
                                                 (void *) ax_session);
    else
        cb_data = NULL;

    /*
     * send the requests out.
     */
    DEBUGMSGTL(("agentx", "sending pdu (req=0x%x,trans=0x%x,sess=0x%x)\n",
                (unsigned)pdu->reqid, (unsigned)pdu->transid, (unsigned)pdu->sessid));
    result = snmp_async_send(ax_session, pdu, agentx_got_response, cb_data);
    if (result == 0) {
        snmp_free_pdu(pdu);
    }

    return SNMP_ERR_NOERROR;
}
Пример #7
0
/*
 * Configure special parameters on the session.
 * Currently takes the parameter configured and changes it if something 
 * was configured.  It becomes "-c" if the community string from the pdu
 * is placed on the session.
 */
int
proxy_fill_in_session(netsnmp_mib_handler *handler,
                      netsnmp_agent_request_info *reqinfo,
                      void **configured)
{
    netsnmp_session *session;
    struct simple_proxy *sp;

    sp = (struct simple_proxy *) handler->myvoid;
    if (!sp) {
        return 0;
    }
    session = sp->sess;
    if (!session) {
        return 0;
    }

#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
#if defined(DISABLE_SNMPV1)
    if (session->version == SNMP_VERSION_2c) {
#else
#if defined(DISABLE_SNMPV2C)
    if (session->version == SNMP_VERSION_1) {
#else
    if (session->version == SNMP_VERSION_1 ||
        session->version == SNMP_VERSION_2c) {
#endif
#endif

        /*
         * Check if session has community string defined for it.
         * If not, need to extract community string from the pdu.
         * Copy to session and set 'configured' to indicate this.
         */
        if (session->community_len == 0) {
            DEBUGMSGTL(("proxy", "session has no community string\n"));
            if (reqinfo->asp == NULL || reqinfo->asp->pdu == NULL ||
                reqinfo->asp->pdu->community_len == 0) {
                return 0;
            }

            *configured = malloc(strlen("-c") + 1);
            strcpy(*configured, "-c");
            DEBUGMSGTL(("proxy", "pdu has community string\n"));
            session->community_len = reqinfo->asp->pdu->community_len;
            session->community = malloc(session->community_len + 1);
            strncpy((char *)session->community,
                    (const char *)reqinfo->asp->pdu->community,
                    session->community_len);
        }
    }
#endif

    return 1;
}

/*
 * Free any specially configured parameters used on the session.
 */
void
proxy_free_filled_in_session_args(netsnmp_session *session, void **configured)
{

    /* Only do comparisions, etc., if something was configured */
    if (*configured == NULL) {
        return;
    }

    /* If used community string from pdu, release it from session now */
    if (strcmp((const char *)(*configured), "-c") == 0) {
        free(session->community);
        session->community = NULL;
        session->community_len = 0;
    }

    free((u_char *)(*configured));
    *configured = NULL;
}

void
init_proxy(void)
{
    snmpd_register_config_handler("proxy", proxy_parse_config,
                                  proxy_free_config,
                                  "[snmpcmd args] host oid [remoteoid]");
}

void
shutdown_proxy(void)
{
    proxy_free_config();
}

int
proxy_handler(netsnmp_mib_handler *handler,
              netsnmp_handler_registration *reginfo,
              netsnmp_agent_request_info *reqinfo,
              netsnmp_request_info *requests)
{

    netsnmp_pdu    *pdu;
    struct simple_proxy *sp;
    oid            *ourname;
    size_t          ourlength;
    netsnmp_request_info *request = requests;
    u_char         *configured = NULL;

    DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n",
                reqinfo->mode));

    switch (reqinfo->mode) {
    case MODE_GET:
    case MODE_GETNEXT:
    case MODE_GETBULK:         /* WWWXXX */
        pdu = snmp_pdu_create(reqinfo->mode);
        break;

    case MODE_SET_ACTION:
        pdu = snmp_pdu_create(SNMP_MSG_SET);
        break;

    case MODE_SET_UNDO:
        /*
         *  If we set successfully (status == NOERROR),
         *     we can't back out again, so need to report the fact.
         *  If we failed to set successfully, then we're fine.
         */
        for (request = requests; request; request=request->next) {
            if (request->status == SNMP_ERR_NOERROR) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_UNDOFAILED);
                return SNMP_ERR_UNDOFAILED;
	    }
	}
        return SNMP_ERR_NOERROR;

    case MODE_SET_RESERVE1:
    case MODE_SET_RESERVE2:
    case MODE_SET_FREE:
    case MODE_SET_COMMIT:
        /*
         *  Nothing to do in this pass
         */
        return SNMP_ERR_NOERROR;

    default:
        snmp_log(LOG_WARNING, "unsupported mode for proxy called (%d)\n",
                               reqinfo->mode);
        return SNMP_ERR_NOERROR;
    }

    sp = (struct simple_proxy *) handler->myvoid;

    if (!pdu || !sp) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }

    while (request) {
        ourname = request->requestvb->name;
        ourlength = request->requestvb->name_length;

        if (sp->base_len > 0) {
            if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) {
                /*
                 * too large 
                 */
                snmp_log(LOG_ERR,
                         "proxy oid request length is too long\n");
                return SNMP_ERR_NOERROR;
            }
            /*
             * suffix appended? 
             */
            DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n",
                        ourlength, sp->base_len, sp->name_len));
            if (ourlength > (int) sp->name_len)
                memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]),
                       sizeof(oid) * (ourlength - sp->name_len));
            ourlength = ourlength - sp->name_len + sp->base_len;
            ourname = sp->base;
        }

        snmp_pdu_add_variable(pdu, ourname, ourlength,
                              request->requestvb->type,
                              request->requestvb->val.string,
                              request->requestvb->val_len);
        request->delegated = 1;
        request = request->next;
    }

    /*
     * Customize session parameters based on request information
     */
    if (!proxy_fill_in_session(handler, reqinfo, (void **)&configured)) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }

    /*
     * send the request out 
     */
    DEBUGMSGTL(("proxy", "sending pdu\n"));
    snmp_async_send(sp->sess, pdu, proxy_got_response,
                    netsnmp_create_delegated_cache(handler, reginfo,
                                                   reqinfo, requests,
                                                   (void *) sp));

    /* Free any special parameters generated on the session */
    proxy_free_filled_in_session_args(sp->sess, (void **)&configured);

    return SNMP_ERR_NOERROR;
}
Пример #8
0
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu = NULL, *response = NULL;

    int             arg;
    size_t          name_length = USM_OID_LEN;
    size_t          name_length2 = USM_OID_LEN;
    int             status;
    int             exitval = 1;
    int             rval;
    int             command = 0;
    long            longvar;

    size_t          oldKu_len = SNMP_MAXBUF_SMALL,
        newKu_len = SNMP_MAXBUF_SMALL,
        oldkul_len = SNMP_MAXBUF_SMALL,
        oldkulpriv_len = SNMP_MAXBUF_SMALL,
        newkulpriv_len = SNMP_MAXBUF_SMALL,
        newkul_len = SNMP_MAXBUF_SMALL,
        keychange_len = SNMP_MAXBUF_SMALL,
        keychangepriv_len = SNMP_MAXBUF_SMALL;

    char           *newpass = NULL, *oldpass = NULL;
    u_char          oldKu[SNMP_MAXBUF_SMALL],
        newKu[SNMP_MAXBUF_SMALL],
        oldkul[SNMP_MAXBUF_SMALL],
        oldkulpriv[SNMP_MAXBUF_SMALL],
        newkulpriv[SNMP_MAXBUF_SMALL],
        newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL],
        keychangepriv[SNMP_MAXBUF_SMALL];

    SOCK_STARTUP;

    authKeyChange = authKeyOid;
    privKeyChange = privKeyOid;

    /*
     * get the common command line arguments 
     */
    switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
    case NETSNMP_PARSE_ARGS_ERROR:
        goto out;
    case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
        exitval = 0;
        goto out;
    case NETSNMP_PARSE_ARGS_ERROR_USAGE:
        usage();
        goto out;
    default:
        break;
    }

    if (arg >= argc) {
        fprintf(stderr, "Please specify an operation to perform.\n");
        usage();
        goto out;
    }

    /*
     * open an SNMP session 
     */
    /*
     * Note:  this needs to obtain the engineID used below 
     */
    session.flags &= ~SNMP_FLAGS_DONT_PROBE;
    ss = snmp_open(&session);
    if (ss == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpusm", &session);
        goto out;
    }

    /*
     * set usmUserEngineID from ss->contextEngineID
     *   if not already set (via -CE)
     */
    if (usmUserEngineID == NULL) {
      usmUserEngineID    = ss->contextEngineID;
      usmUserEngineIDLen = ss->contextEngineIDLen;
    }

    /*
     * create PDU for SET request and add object names and values to request 
     */
    pdu = snmp_pdu_create(SNMP_MSG_SET);
    if (!pdu) {
        fprintf(stderr, "Failed to create request\n");
        goto close_session;
    }


    if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) {

        /*
         * passwd: change a users password.
         *
         * XXX:  Uses the auth type of the calling user, a MD5 user can't
         *       change a SHA user's key.
         */
        char *passwd_user;

        command = CMD_PASSWD;
        oldpass = argv[++arg];
        newpass = argv[++arg];
        passwd_user = argv[++arg];

        if (doprivkey == 0 && doauthkey == 0)
            doprivkey = doauthkey = 1;

        if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "New passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            goto close_session;
        }

        if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "Old passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            goto close_session;
        }

        DEBUGMSGTL(("9:usm:passwd", "oldpass len %" NETSNMP_PRIz "d, newpass len %" NETSNMP_PRIz "d\n",
                    strlen(oldpass), strlen(newpass)));

        /* 
         * Change the user supplied on command line.
         */
        if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) {
            session.securityName = passwd_user;
        } else {
            /*
             * Use own key object if no user was supplied.
             */
            authKeyChange = ownAuthKeyOid;
            privKeyChange = ownPrivKeyOid;
        }

        /*
         * do we have a securityName?  If not, copy the default 
         */
        if (session.securityName == NULL) {
            session.securityName = 
	      strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					   NETSNMP_DS_LIB_SECNAME));
        }

        /*
         * the old Ku is in the session, but we need the new one 
         */
        if (session.securityAuthProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_authtype(&session.securityAuthProtoLen);
            session.securityAuthProto =
                snmp_duplicate_objid(def, session.securityAuthProtoLen);
        }
        if (session.securityAuthProto == NULL) {
            /*
             * assume MD5 
             */
#ifndef NETSNMP_DISABLE_MD5
            session.securityAuthProtoLen =
                sizeof(usmHMACMD5AuthProtocol) / sizeof(oid);
            session.securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     session.securityAuthProtoLen);
#else
            session.securityAuthProtoLen =
                sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid);
            session.securityAuthProto =
                snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
                                     session.securityAuthProtoLen);
#endif

        }

	if (uselocalizedkey && (strncmp(oldpass, "0x", 2) == 0)) {
	    /*
	     * use the localized key from the command line
	     */
	    u_char *buf;
	    size_t buf_len = SNMP_MAXBUF_SMALL;
	    buf = (u_char *) malloc (buf_len * sizeof(u_char));

	    oldkul_len = 0; /* initialize the offset */
	    if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &oldkul_len, 0, oldpass)) {
	      snmp_perror(argv[0]);
	      fprintf(stderr, "generating the old Kul from localized key failed\n");
	      goto close_session;
	    }
	    
	    memcpy(oldkul, buf, oldkul_len);
	    SNMP_FREE(buf);
	}
	else {
	    /*
	     * the old Ku is in the session, but we need the new one 
	     */
	    rval = generate_Ku(session.securityAuthProto,
			       session.securityAuthProtoLen,
			       (u_char *) oldpass, strlen(oldpass),
			       oldKu, &oldKu_len);
	    
	    if (rval != SNMPERR_SUCCESS) {
	        snmp_perror(argv[0]);
	        fprintf(stderr, "generating the old Ku failed\n");
	        goto close_session;
	    }

	    /*
	     * generate the two Kul's 
	     */
	    rval = generate_kul(session.securityAuthProto,
				session.securityAuthProtoLen,
				usmUserEngineID, usmUserEngineIDLen,
				oldKu, oldKu_len, oldkul, &oldkul_len);
	    
	    if (rval != SNMPERR_SUCCESS) {
	        snmp_perror(argv[0]);
		fprintf(stderr, "generating the old Kul failed\n");
		goto close_session;
	    }
            DEBUGMSGTL(("9:usm:passwd", "oldkul len %" NETSNMP_PRIz "d\n", oldkul_len));
	}
	if (uselocalizedkey && (strncmp(newpass, "0x", 2) == 0)) {
	    /*
	     * use the localized key from the command line
	     */
	    u_char *buf;
	    size_t buf_len = SNMP_MAXBUF_SMALL;
	    buf = (u_char *) malloc (buf_len * sizeof(u_char));

	    newkul_len = 0; /* initialize the offset */
	    if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &newkul_len, 0, newpass)) {
	      snmp_perror(argv[0]);
	      fprintf(stderr, "generating the new Kul from localized key failed\n");
	      goto close_session;
	    }
	    
	    memcpy(newkul, buf, newkul_len);
	    SNMP_FREE(buf);
	} else {
            rval = generate_Ku(session.securityAuthProto,
                               session.securityAuthProtoLen,
                               (u_char *) newpass, strlen(newpass),
                               newKu, &newKu_len);

            if (rval != SNMPERR_SUCCESS) {
                snmp_perror(argv[0]);
                fprintf(stderr, "generating the new Ku failed\n");
                goto close_session;
            }

	    rval = generate_kul(session.securityAuthProto,
				session.securityAuthProtoLen,
				usmUserEngineID, usmUserEngineIDLen,
				newKu, newKu_len, newkul, &newkul_len);

	    if (rval != SNMPERR_SUCCESS) {
	        snmp_perror(argv[0]);
		fprintf(stderr, "generating the new Kul failed\n");
		goto close_session;
	    }
            DEBUGMSGTL(("9:usm:passwd", "newkul len %" NETSNMP_PRIz "d\n", newkul_len));
	}

        /*
         * for encryption, we may need to truncate the key to the proper length
         * so we need two copies.  For simplicity, we always just copy even if
         * they're the same lengths.
         */
        if (doprivkey) {
            int privtype, properlength;
            u_char *okp = oldkulpriv, *nkp = newkulpriv;
            if (!session.securityPrivProto) {
                snmp_log(LOG_ERR, "no encryption type specified, which I need in order to know to change the key\n");
                goto close_session;
            }

            privtype = sc_get_privtype(session.securityPrivProto,
                                       session.securityPrivProtoLen);
            properlength = sc_get_proper_priv_length_bytype(privtype);
            if (USM_CREATE_USER_PRIV_DES == privtype)
                properlength *= 2; /* ?? we store salt with key */
            DEBUGMSGTL(("9:usm:passwd", "proper len %d\n", properlength));
            oldkulpriv_len = oldkul_len;
            newkulpriv_len = newkul_len;
            memcpy(oldkulpriv, oldkul, oldkulpriv_len);
            memcpy(newkulpriv, newkul, newkulpriv_len);

            if (oldkulpriv_len > properlength) {
                oldkulpriv_len = newkulpriv_len = properlength;
            }
            else if (oldkulpriv_len < properlength) {
                rval = netsnmp_extend_kul(properlength,
                                          session.securityAuthProto,
                                          session.securityAuthProtoLen,
                                          privtype,
                                          usmUserEngineID, usmUserEngineIDLen,
                                          &okp, &oldkulpriv_len,
                                          sizeof(oldkulpriv));
                rval = netsnmp_extend_kul(properlength,
                                          session.securityAuthProto,
                                          session.securityAuthProtoLen,
                                          privtype,
                                          usmUserEngineID, usmUserEngineIDLen,
                                          &nkp, &newkulpriv_len,
                                          sizeof(newkulpriv));
            }
        }

        /*
         * create the keychange string 
         */
	if (doauthkey) {
	  rval = encode_keychange(session.securityAuthProto,
				  session.securityAuthProtoLen,
				  oldkul, oldkul_len,
				  newkul, newkul_len,
				  keychange, &keychange_len);

	  if (rval != SNMPERR_SUCCESS) {
	    snmp_perror(argv[0]);
            fprintf(stderr, "encoding the keychange failed\n");
            usage();
            goto close_session;
	  }
	}

        /* which is slightly different for encryption if lengths are
           different */
	if (doprivkey) {
            DEBUGMSGTL(("9:usm:passwd:encode", "proper len %" NETSNMP_PRIz "d, old_len %" NETSNMP_PRIz "d, new_len %" NETSNMP_PRIz "d\n",
                        oldkulpriv_len, oldkulpriv_len, newkulpriv_len));
	  rval = encode_keychange(session.securityAuthProto,
                                session.securityAuthProtoLen,
                                oldkulpriv, oldkulpriv_len,
                                newkulpriv, newkulpriv_len,
                                keychangepriv, &keychangepriv_len);

          DEBUGMSGTL(("9:usm:passwd:encode", "keychange len %" NETSNMP_PRIz "d\n",
                      keychangepriv_len));
	  if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "encoding the keychange failed\n");
            usage();
            goto close_session;
	  }
	}

        /*
         * add the keychange string to the outgoing packet 
         */
        if (doauthkey) {
            setup_oid(authKeyChange, &name_length,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, authKeyChange, name_length,
                                  ASN_OCTET_STR, keychange, keychange_len);
        }
        if (doprivkey) {
            setup_oid(privKeyChange, &name_length2,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, privKeyChange, name_length2,
                                  ASN_OCTET_STR,
                                  keychangepriv, keychangepriv_len);
        }

    } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) {
        /*
         * create:  create a user
         *
         * create USER [CLONEFROM]
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to create\n");
            usage();
            goto close_session;
        }

        command = CMD_CREATE;

        if (++arg < argc) {
            /*
             * clone the new user from an existing user
             *   (and make them active immediately)
             */
            setup_oid(usmUserStatus, &name_length,
                      usmUserEngineID, usmUserEngineIDLen, argv[arg-1]);
            if (docreateandwait) {
                longvar = RS_CREATEANDWAIT;
            } else {
                longvar = RS_CREATEANDGO;
            }
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));

            name_length = USM_OID_LEN;
            setup_oid(usmUserCloneFrom, &name_length,
                      usmUserEngineID, usmUserEngineIDLen,
                      argv[arg - 1]);
            setup_oid(usmUserSecurityName, &name_length2,
                      usmUserEngineID, usmUserEngineIDLen,
                      argv[arg]);
            snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                                  ASN_OBJECT_ID,
                                  (u_char *) usmUserSecurityName,
                                  sizeof(oid) * name_length2);
        } else {
            /*
             * create a new (unauthenticated) user from scratch
             * The Net-SNMP agent won't allow such a user to be made active.
             */
            setup_oid(usmUserStatus, &name_length,
                      usmUserEngineID, usmUserEngineIDLen, argv[arg-1]);
            longvar = RS_CREATEANDWAIT;
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));
        }

    } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) {
        /*
         * create:  clone a user from another
         *
         * cloneFrom USER FROM
         */
        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to operate on\n");
            usage();
            goto close_session;
        }

        command = CMD_CLONEFROM;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_ACTIVE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
        name_length = USM_OID_LEN;
        setup_oid(usmUserCloneFrom, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);

        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to clone from\n");
            usage();
            goto close_session;
        }

        setup_oid(usmUserSecurityName, &name_length2,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                              ASN_OBJECT_ID,
                              (u_char *) usmUserSecurityName,
                              sizeof(oid) * name_length2);

    } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) {
        /*
         * delete:  delete a user
         *
         * delete USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to delete\n");
            goto close_session;
        }

        command = CMD_DELETE;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
    } else if (strcmp(argv[arg], CMD_ACTIVATE_NAME) == 0) {
        /*
         * activate:  activate a user
         *
         * activate USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to activate\n");
            goto close_session;
        }

        command = CMD_ACTIVATE;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_ACTIVE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
    } else if (strcmp(argv[arg], CMD_DEACTIVATE_NAME) == 0) {
        /*
         * deactivate:  deactivate a user
         *
         * deactivate USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to deactivate\n");
            goto close_session;
        }

        command = CMD_DEACTIVATE;
        setup_oid(usmUserStatus, &name_length,
                  usmUserEngineID, usmUserEngineIDLen, argv[arg]);
        longvar = RS_NOTINSERVICE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
    } else if (strcmp(argv[arg], CMD_CHANGEKEY_NAME) == 0) {
        /*
         * change the key of a user if DH is available
         */

        char *passwd_user;
        netsnmp_pdu *dhpdu, *dhresponse = NULL;
        netsnmp_variable_list *vars, *dhvar;
        
        command = CMD_CHANGEKEY;
        name_length = DH_USM_OID_LEN;
        name_length2 = DH_USM_OID_LEN;

        passwd_user = argv[++arg];

        if (doprivkey == 0 && doauthkey == 0)
            doprivkey = doauthkey = 1;

        /* 
         * Change the user supplied on command line.
         */
        if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) {
            session.securityName = passwd_user;
        } else {
            /*
             * Use own key object if no user was supplied.
             */
            dhauthKeyChange = usmDHUserOwnAuthKeyChange;
            dhprivKeyChange = usmDHUserOwnPrivKeyChange;
        }

        /*
         * do we have a securityName?  If not, copy the default 
         */
        if (session.securityName == NULL) {
            session.securityName = 
	      strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					   NETSNMP_DS_LIB_SECNAME));
        }

        /* fetch the needed diffie helman parameters */
        dhpdu = snmp_pdu_create(SNMP_MSG_GET);
        if (!dhpdu) {
            fprintf(stderr, "Failed to create DH request\n");
            goto close_session;
        }

        /* get the current DH parameters */
        snmp_add_null_var(dhpdu, usmDHParameters, usmDHParameters_len);
        
        /* maybe the auth key public value */
        if (doauthkey) {
            setup_oid(dhauthKeyChange, &name_length,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_add_null_var(dhpdu, dhauthKeyChange, name_length);
        }
            
        /* maybe the priv key public value */
        if (doprivkey) {
            setup_oid(dhprivKeyChange, &name_length2,
                      usmUserEngineID, usmUserEngineIDLen,
                      session.securityName);
            snmp_add_null_var(dhpdu, dhprivKeyChange, name_length2);
        }

        /* fetch the values */
        status = snmp_synch_response(ss, dhpdu, &dhresponse);

        if (status != SNMPERR_SUCCESS || dhresponse == NULL ||
            dhresponse->errstat != SNMP_ERR_NOERROR ||
            dhresponse->variables->type != ASN_OCTET_STR) {
            snmp_sess_perror("snmpusm", ss);
            if (dhresponse && dhresponse->variables &&
                dhresponse->variables->type != ASN_OCTET_STR) {
                fprintf(stderr,
                        "Can't get diffie-helman exchange from the agent\n");
                fprintf(stderr,
                        "  (maybe it doesn't support the SNMP-USM-DH-OBJECTS-MIB MIB)\n");
            }
            exitval = 1;
            goto begone;
        }
        
        dhvar = dhresponse->variables;
        vars = dhvar->next_variable;
        /* complete the DH equation & print resulting keys */
        if (doauthkey) {
            if (get_USM_DH_key(vars, dhvar,
                               sc_get_properlength(ss->securityAuthProto,
                                                   ss->securityAuthProtoLen),
                               pdu, "auth",
                               dhauthKeyChange, name_length) != SNMPERR_SUCCESS)
                goto begone;
            vars = vars->next_variable;
        }
        if (doprivkey) {
            size_t dhprivKeyLen = 0;
            int privtype = sc_get_privtype(ss->securityPrivProto,
                                           ss->securityPrivProtoLen);
            dhprivKeyLen = sc_get_proper_priv_length_bytype(privtype);
            if (USM_CREATE_USER_PRIV_DES == privtype)
                dhprivKeyLen *= 2; /* ?? we store salt with key */
            if (get_USM_DH_key(vars, dhvar,
                               dhprivKeyLen,
                               pdu, "priv",
                               dhprivKeyChange, name_length2)
                != SNMPERR_SUCCESS)
                goto begone;
            vars = vars->next_variable;
        }
        /* snmp_free_pdu(dhresponse); */ /* parts still in use somewhere */
#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
    } else {
        fprintf(stderr, "Unknown command\n");
        usage();
        goto close_session;
    }

    /*
     * add usmUserPublic if specified (via -Cp)
     */
    if (usmUserPublic_val) {
        name_length = USM_OID_LEN;
	setup_oid(usmUserPublic, &name_length,
		  usmUserEngineID, usmUserEngineIDLen,
		  session.securityName);
	snmp_pdu_add_variable(pdu, usmUserPublic, name_length,
			      ASN_OCTET_STR, usmUserPublic_val, 
			      strlen(usmUserPublic_val));	  
    }

    /*
     * do the request 
     */
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS) {
        if (response) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                fprintf(stdout, "%s\n", successNotes[command - 1]);
            } else {
                fprintf(stderr, "Error in packet.\nReason: %s\n",
                        snmp_errstring(response->errstat));
                if (response->errindex != 0) {
                    int             count;
                    netsnmp_variable_list *vars;
                    fprintf(stderr, "Failed object: ");
                    for (count = 1, vars = response->variables;
                         vars && count != response->errindex;
                         vars = vars->next_variable, count++)
                        /*EMPTY*/;
                    if (vars)
                        fprint_objid(stderr, vars->name,
                                     vars->name_length);
                    fprintf(stderr, "\n");
                }
                exitval = 2;
            }
        }
    } else if (status == STAT_TIMEOUT) {
        fprintf(stderr, "Timeout: No Response from %s\n",
                session.peername);
        exitval = 1;
    } else {                    /* status == STAT_ERROR */
        snmp_sess_perror("snmpset", ss);
        exitval = 1;
    }

    exitval = 0;
#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
  begone:
#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
    if (response)
        snmp_free_pdu(response);

close_session:
    snmp_close(ss);

out:
    SOCK_CLEANUP;
    return exitval;
}
Пример #9
0
int
get_USM_DH_key(netsnmp_variable_list *vars, netsnmp_variable_list *dhvar,
               size_t outkey_len,
               netsnmp_pdu *pdu, const char *keyname,
               oid *keyoid, size_t keyoid_len) {
    u_char *dhkeychange;
    DH *dh;
    const BIGNUM *p, *g, *pub_key;
    BIGNUM *other_pub;
    u_char *key;
    size_t key_len;
            
    dhkeychange = (u_char *) malloc(2 * vars->val_len * sizeof(char));
    if (!dhkeychange)
        return SNMPERR_GENERR;
    
    memcpy(dhkeychange, vars->val.string, vars->val_len);

    {
        const unsigned char *cp = dhvar->val.string;
        dh = d2i_DHparams(NULL, &cp, dhvar->val_len);
    }

    if (dh)
        DH_get0_pqg(dh, &p, NULL, &g);

    if (!dh || !g || !p) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }

    if (!DH_generate_key(dh)) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }

    DH_get0_key(dh, &pub_key, NULL);
    if (vars->val_len != (unsigned int)BN_num_bytes(pub_key)) {
        SNMP_FREE(dhkeychange);
        fprintf(stderr,"incorrect diffie-helman lengths (%lu != %d)\n",
                (unsigned long)vars->val_len, BN_num_bytes(pub_key));
        return SNMPERR_GENERR;
    }

    BN_bn2bin(pub_key, dhkeychange + vars->val_len);

    key_len = DH_size(dh);
    if (!key_len) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }
    key = (u_char *) malloc(key_len * sizeof(u_char));

    if (!key) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }

    other_pub = BN_bin2bn(vars->val.string, vars->val_len, NULL);
    if (!other_pub) {
        SNMP_FREE(dhkeychange);
        SNMP_FREE(key);
        return SNMPERR_GENERR;
    }

    if (DH_compute_key(key, other_pub, dh)) {
        u_char *kp;

        printf("new %s key: 0x", keyname);
        for(kp = key + key_len - outkey_len;
            kp - key < (int)key_len;  kp++) {
            printf("%02x", (unsigned char) *kp);
        }
        printf("\n");
    }

    snmp_pdu_add_variable(pdu, keyoid, keyoid_len,
                          ASN_OCTET_STR, dhkeychange,
                          2 * vars->val_len);

    SNMP_FREE(dhkeychange);
    SNMP_FREE(other_pub);
    SNMP_FREE(key);

    return SNMPERR_SUCCESS;
}
Пример #10
0
int
proxy_handler(netsnmp_mib_handler *handler,
              netsnmp_handler_registration *reginfo,
              netsnmp_agent_request_info *reqinfo,
              netsnmp_request_info *requests)
{

    netsnmp_pdu    *pdu;
    struct simple_proxy *sp;
    oid            *ourname;
    size_t          ourlength;
    netsnmp_request_info *request = requests;

    DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n",
                reqinfo->mode));

    switch (reqinfo->mode) {
    case MODE_GET:
    case MODE_GETNEXT:
    case MODE_GETBULK:         /* WWWXXX */
        pdu = snmp_pdu_create(reqinfo->mode);
        break;

    case MODE_SET_COMMIT:
        pdu = snmp_pdu_create(SNMP_MSG_SET);
        break;

    default:
        snmp_log(LOG_WARNING, "unsupported mode for proxy called\n");
        return SNMP_ERR_NOERROR;
    }

    sp = (struct simple_proxy *) handler->myvoid;

    if (!pdu || !sp) {
        netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
        return SNMP_ERR_NOERROR;
    }

    while (request) {
        ourname = request->requestvb->name;
        ourlength = request->requestvb->name_length;

        if (sp->base_len > 0) {
            if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) {
                /*
                 * too large 
                 */
                snmp_log(LOG_ERR,
                         "proxy oid request length is too long\n");
                return SNMP_ERR_NOERROR;
            }
            /*
             * suffix appended? 
             */
            DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n",
                        ourlength, sp->base_len, sp->name_len));
            if (ourlength > (int) sp->name_len)
                memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]),
                       sizeof(oid) * (ourlength - sp->name_len));
            ourlength = ourlength - sp->name_len + sp->base_len;
            ourname = sp->base;
        }

        snmp_pdu_add_variable(pdu, ourname, ourlength,
                              request->requestvb->type,
                              request->requestvb->val.string,
                              request->requestvb->val_len);
        request->delegated = 1;
        request = request->next;
    }

    /*
     * send the request out 
     */
    DEBUGMSGTL(("proxy", "sending pdu\n"));
    snmp_async_send(sp->sess, pdu, proxy_got_response,
                    netsnmp_create_delegated_cache(handler, reginfo,
                                                   reqinfo, requests,
                                                   (void *) sp));
    return SNMP_ERR_NOERROR;
}
Пример #11
0
/**
 * snmp_set
 * @ss: a handle to the snmp session needed to make an snmp transaction.
 * @objid: string containing the OID to set.
 * @value: the value to set the oid with.
 *
 * Sets a value where indicated by the objectid
 * using snmp.
 *
 * Returns: 0 if Success, less than 0 if Failure.
 **/
SaErrorT snmp_set(
        struct snmp_session *ss,
        char *objid,
        struct snmp_value value) 
{
        struct snmp_pdu *pdu;
        struct snmp_pdu *response;

        oid anOID[MAX_OID_LEN];
        size_t anOID_len = MAX_OID_LEN;
        void *dataptr = NULL;
        int status = 0;
	SaErrorT rtncode = 0;

        /*
         * Create the PDU for the data for our request.
         */
        pdu = snmp_pdu_create(SNMP_MSG_SET);
        read_objid(objid, anOID, &anOID_len);

        rtncode = 0; /* Default - All is OK */

        switch (value.type)
        {
                case ASN_INTEGER:
		case ASN_UNSIGNED:
                case ASN_COUNTER:
			dataptr = &value.integer;
                        break;
                case ASN_OCTET_STR:
			dataptr = value.string;
                        break;
                default:
                        rtncode = SA_ERR_HPI_INVALID_PARAMS;
                        dbg("datatype %c not yet supported by snmp_set()\n", value.type);
                        break;
        }

        if (rtncode == 0) {

		/*
		 * Set the data to send out
		 */
                /* Old code - int rc = snmp_add_var(pdu, objid, objid_len, datatype, dataptr)      */
		/*            was missing checking for rc, so there was no OID and no data was     */
		/*            included in the package.                                             */
		/*            Since snmp_add_var() converts input data to string then call         */
		/*            snmp_pdu_add_variable(), we stick with add_variable() for efficiency */
		snmp_pdu_add_variable(pdu, anOID, anOID_len, value.type, dataptr, value.str_len);

        	/*
         	* Send the Request out.
         	*/
        	status = snmp_synch_response(ss, pdu, &response);

        	/*
         	* Process the response.
         	*/
                if (status == STAT_SUCCESS) 
                                rtncode = errstat2hpi(response->errstat);
                else {
			snmp_sess_perror("snmpset", ss);
			rtncode = snmpstat2hpi(status);;
		}
		
        	/* Clean up: free the response */
        	if (response) snmp_free_pdu(response);
	}

        return rtncode;
}
Пример #12
0
/*
 * Add a null variable with the requested name to the end of the list of
 * variables for this pdu.
 */
netsnmp_variable_list *
snmp_add_null_var(netsnmp_pdu *pdu, const oid * name, size_t name_length)
{
    return snmp_pdu_add_variable(pdu, name, name_length, ASN_NULL, NULL, 0);
}
Пример #13
0
static int
_hook_parse(netsnmp_session * sp, netsnmp_pdu * pdu,
            u_char * pkt, size_t len)
{
    int      i;
    int      rc;
    u_char  *p;
    oid      val;
    int      payload_len;
    netsnmp_transport *transport;
    struct asmp_connection *asmp;

    transport = snmp_sess_transport(snmp_sess_pointer(sp));
    if (transport == NULL || transport->data == NULL)
        return -1;

    asmp = transport->data;

    pdu->msgid   = pdu->reqid = (pkt[5] << 8) | pkt[6];
    pdu->command = pkt[7];

    if (pdu->command == 0x90 || pdu->command == 0x91)
        rc = 1;
    else
        rc = SNMP_ERR_NOERROR;

    p = pkt+12;
    payload_len = ntohl(*((uint32_t *)(pkt+8)));
    while (payload_len > 1) {
        uint16_t vlen;

        if (*p == ASMP_FIELD_TERM)
            break;

        val  = *p;
        vlen = ntohs(*((uint16_t *)(p+1)));

        if (asmp->proto != ASMP_PROTO_AIDP) {
            switch (val) {
            case 1:
                if (pdu->command >= 0x90 && pdu->command <= 0x92)
                    pdu->errstat = ntohs(*((uint16_t *)(p+3)));
                break;

            case 2:
                if (pdu->command >= 0x90 && pdu->command <= 0x92)
                    pdu->errindex = ntohs(*((uint16_t *)(p+3)));
                break;

            case 3:
                if (pdu->command >= 0x90 && pdu->command <= 0x92) {
                    int     nlen;
                    oid    *name = NULL;
                    netsnmp_variable_list *var = NULL;

                    p += 3;
                    if (*p != ASN_OBJECT_ID) {
                        fprintf(stderr, "Wrong VarBind data\n");
                        return rc;
                    }
                    while (vlen > 0) {
                        nlen = (*(p+1) << 8 | *(p+2));

                        switch (*p) {
                        case ASN_OBJECT_ID:
                            name = calloc(1, nlen);
                            //fprintf(stderr, "OID: ");
                            for (p += 3, i=0; i<nlen/sizeof(oid); i++, p += 4) {
                                name[i] = *p     << 24 |
                                          *(p+1) << 16 |
                                          *(p+2) << 8  |
                                          *(p+3);
                                //fprintf(stderr, ".%d", name[i]);
                            }
                            //fprintf(stderr, "\n");
                            /* move pointer back */
                            p -= nlen+3;
#if 0
                            if (pkt[16] == 6 && pkt[21] == 1)
                                 snmp_pdu_add_variable(pdu, name, nlen,
                                                       SNMP_ENDOFMIBVIEW,
                                                       NULL, 0);
#endif
                            if (var == NULL) {
                                /* First OID is name OID */
                                var = snmp_add_null_var(pdu, name, nlen/sizeof(oid));
                            } else {
                                /* Second OID is value OID */
                                var->type = *p;
                                snmp_set_var_value(var, (u_char *)name, nlen);
                            }
                            free(name);
                            break;

                        case ASN_COUNTER:
                        case ASN_TIMETICKS:
                        case ASN_GAUGE:
                        case ASN_INTEGER: {
                                int32_t v;
                                v = ntohl(*((int32_t *)(p+3)));
                                var->type = *p;
                                snmp_set_var_value(var, (u_char *)&v, nlen);
                            }
                            break;

                        case ASN_OCTET_STR:
                            var->type = *p;
                            snmp_set_var_value(var, p+3, nlen);
                            break;

                        case ASN_IPADDRESS:
                            var->type = *p;
                            snmp_set_var_value(var, p+3, nlen);
                            break;

                        case ASN_NULL:
                            var->type = *p;
                            snmp_set_var_value(var, NULL, 0);
                            break;

                        default:
                            fprintf(stderr, "AAA: %d\n", *p);
                            break;
                        }
                        p += nlen+3;
                        vlen -= nlen+3;
                        payload_len -= nlen+3;
                    }
                    pdu->command = SNMP_MSG_RESPONSE;
                    rc = SNMP_ERR_NOERROR;
                }
                break;

            default:
                break;
            }
        } else {
            fprintf(stderr, "Flen: %04x\n", vlen);
            snmp_pdu_add_variable(pdu, &val, 1,
                                  ASN_OCTET_STR,
                                  p+3, vlen);
        }

        p += vlen+3;
        payload_len -= vlen+3;
    }

    return rc;
}
Пример #14
0
int main (int argc, char *argv[])
{
    netsnmp_session session, *ss;

    netsnmp_pdu *pdu = NULL, *response = NULL;

#ifdef notused
    netsnmp_variable_list *vars;
#endif

    int arg;

#ifdef notused
    int count;

    int current_name = 0;

    int current_type = 0;

    int current_value = 0;

    char *names[128];

    char types[128];

    char *values[128];

    oid name[MAX_OID_LEN];
#endif
    size_t name_length;

    int status;

    int exitval = 0;

    int command = 0;

    long longvar;

    int secModel, secLevel, contextMatch;

    unsigned int val, i = 0;

    char *mask, *groupName, *prefix, *authtype;

    u_char viewMask[VACMSTRINGLEN];

    char *st;


    /*
     * get the common command line arguments 
     */
    switch (arg = snmp_parse_args (argc, argv, &session, "C:", optProc))
    {
        case NETSNMP_PARSE_ARGS_ERROR:
            exit (1);
        case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
            exit (0);
        case NETSNMP_PARSE_ARGS_ERROR_USAGE:
            usage ();
            exit (1);
        default:
            break;
    }


    SOCK_STARTUP;

    /*
     * open an SNMP session 
     */
    /*
     * Note:  this wil obtain the engineID needed below 
     */
    ss = snmp_open (&session);
    if (ss == NULL)
    {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror ("snmpvacm", &session);
        exit (1);
    }

    /*
     * create PDU for SET request and add object names and values to request 
     */
    pdu = snmp_pdu_create (SNMP_MSG_SET);

    if (arg >= argc)
    {
        fprintf (stderr, "Please specify a operation to perform.\n");
        usage ();
        exit (1);
    }

    if (strcmp (argv[arg], CMD_DELETEVIEW_NAME) == 0)
        /*
         * deleteView: delete a view
         *
         * deleteView NAME SUBTREE
         *
         */
    {
        if (++arg + 2 != argc)
        {
            fprintf (stderr, "You must specify the view to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETEVIEW;
        name_length = VIEW_OID_LEN;
        view_oid (vacmViewTreeFamilyStatus, &name_length, argv[arg], argv[arg + 1]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATEVIEW_NAME) == 0)
        /*
         * createView: create a view
         *
         * createView NAME SUBTREE MASK
         *
         */
    {
        if (++arg + 2 > argc)
        {
            fprintf (stderr, "You must specify name, subtree and mask\n");
            usage ();
            exit (1);
        }
        command = CMD_CREATEVIEW;
        name_length = VIEW_OID_LEN;
        view_oid (vacmViewTreeFamilyStatus, &name_length, argv[arg], argv[arg + 1]);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
        /*
         * Mask
         */
        if (arg + 3 == argc)
        {
            mask = argv[arg + 2];
            for (mask = strtok_r (mask, ".:", &st); mask; mask = strtok_r (NULL, ".:", &st))
            {
                if (i >= sizeof (viewMask))
                {
                    printf ("MASK too long\n");
                    exit (1);
                }
                if (sscanf (mask, "%x", &val) == 0)
                {
                    printf ("invalid MASK\n");
                    exit (1);
                }
                viewMask[i] = val;
                i++;
            }
        }
        else
        {
            for (i = 0; i < (name_length + 7) / 8; i++)
                viewMask[i] = (u_char) 0xff;
        }
        view_oid (vacmViewTreeFamilyMask, &name_length, argv[arg], argv[arg + 1]);
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyMask, name_length, ASN_OCTET_STR, viewMask, i);

        view_oid (vacmViewTreeFamilyType, &name_length, argv[arg], argv[arg + 1]);
        snmp_pdu_add_variable (pdu, vacmViewTreeFamilyType, name_length,
                               ASN_INTEGER, (u_char *) & viewTreeFamilyType, sizeof (viewTreeFamilyType));

    }
    else if (strcmp (argv[arg], CMD_DELETESEC2GROUP_NAME) == 0)
        /*
         * deleteSec2Group: delete security2group
         *
         * deleteSec2Group  MODEL SECURITYNAME
         *
         */
    {
        if (++arg + 2 != argc)
        {
            fprintf (stderr, "You must specify the sec2group to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETESEC2GROUP;
        name_length = SEC2GROUP_OID_LEN;
        if (sscanf (argv[arg], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        sec2group_oid (vacmSec2GroupStatus, &name_length, secModel, argv[arg + 1]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, vacmSec2GroupStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATESEC2GROUP_NAME) == 0)
        /*
         * createSec2Group: create a security2group
         *
         * createSec2Group  MODEL SECURITYNAME GROUPNAME
         *
         */
    {
        if (++arg + 3 != argc)
        {
            fprintf (stderr, "You must specify model, security name and group name\n");
            usage ();
            exit (1);
        }

        command = CMD_CREATESEC2GROUP;
        name_length = SEC2GROUP_OID_LEN;
        if (sscanf (argv[arg], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        sec2group_oid (vacmSec2GroupStatus, &name_length, secModel, argv[arg + 1]);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, vacmSec2GroupStatus, name_length,
                               ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
        sec2group_oid (vacmGroupName, &name_length, secModel, argv[arg + 1]);
        snmp_pdu_add_variable (pdu, vacmGroupName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 2], strlen (argv[arg + 2]));
    }
    else if (strcmp (argv[arg], CMD_DELETEACCESS_NAME) == 0)
        /*
         * deleteAccess: delete access entry
         *
         * deleteAccess  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL
         *
         */
    {
        if (++arg + 3 > argc)
        {
            fprintf (stderr, "You must specify the access entry to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETEACCESS;
        name_length = ACCESS_OID_LEN;
        groupName = argv[arg];
        if (arg + 4 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        access_oid (vacmAccessStatus, &name_length, groupName, prefix, secModel, secLevel);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, vacmAccessStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATEACCESS_NAME) == 0)
        /*
         * createAccess: create access entry
         *
         * createAccess  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL CONTEXTMATCH READVIEWNAME WRITEVIEWNAME NOTIFYVIEWNAME
         *
         */
    {
        if (++arg + 7 > argc)
        {
            fprintf (stderr, "You must specify the access entry to create\n");
            usage ();
            exit (1);
        }

        command = CMD_CREATEACCESS;
        name_length = ACCESS_OID_LEN;
        groupName = argv[arg];
        if (arg + 8 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        access_oid (vacmAccessStatus, &name_length, groupName, prefix, secModel, secLevel);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, vacmAccessStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));

        access_oid (vacmAccessContextMatch, &name_length, groupName, prefix, secModel, secLevel);
        if (sscanf (argv[arg + 3], "%d", &contextMatch) == 0)
        {
            printf ("invalid contextMatch\n");
            usage ();
            exit (1);
        }
        snmp_pdu_add_variable (pdu, vacmAccessContextMatch, name_length,
                               ASN_INTEGER, (u_char *) & contextMatch, sizeof (contextMatch));

        access_oid (vacmAccessReadViewName, &name_length, groupName, prefix, secModel, secLevel);
        snmp_pdu_add_variable (pdu, vacmAccessReadViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 4], strlen (argv[arg + 4]));

        access_oid (vacmAccessWriteViewName, &name_length, groupName, prefix, secModel, secLevel);
        snmp_pdu_add_variable (pdu, vacmAccessWriteViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 5], strlen (argv[arg + 5]));

        access_oid (vacmAccessNotifyViewName, &name_length, groupName, prefix, secModel, secLevel);
        snmp_pdu_add_variable (pdu, vacmAccessNotifyViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 6], strlen (argv[arg + 6]));
    }
    else if (strcmp (argv[arg], CMD_DELETEAUTH_NAME) == 0)
        /*
         * deleteAuth: delete authAccess entry
         *
         * deleteAuth  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE
         *
         */
    {
        if (++arg + 4 > argc)
        {
            fprintf (stderr, "You must specify the authAccess entry to delete\n");
            usage ();
            exit (1);
        }

        command = CMD_DELETEAUTH;
        name_length = AUTH_OID_LEN;
        groupName = argv[arg];
        if (arg + 5 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        authtype = argv[arg + 3];
        auth_oid (nsVacmRowStatus, &name_length, groupName, prefix, secModel, secLevel, authtype);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable (pdu, nsVacmRowStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));
    }
    else if (strcmp (argv[arg], CMD_CREATEAUTH_NAME) == 0)
        /*
         * createAuth: create authAccess entry
         *
         * createAuth  GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE CONTEXTMATCH VIEWNAME
         *
         */
    {
        if (++arg + 6 > argc)
        {
            fprintf (stderr, "You must specify the authAccess entry to create\n");
            usage ();
            exit (1);
        }

        command = CMD_CREATEAUTH;
        name_length = AUTH_OID_LEN;
        groupName = argv[arg];
        if (arg + 7 == argc)
            prefix = argv[++arg];
        else
            prefix = NULL;

        if (sscanf (argv[arg + 1], "%d", &secModel) == 0)
        {
            printf ("invalid security model\n");
            usage ();
            exit (1);
        }
        if (sscanf (argv[arg + 2], "%d", &secLevel) == 0)
        {
            printf ("invalid security level\n");
            usage ();
            exit (1);
        }
        authtype = argv[arg + 3];
        auth_oid (nsVacmRowStatus, &name_length, groupName, prefix, secModel, secLevel, authtype);
        longvar = RS_CREATEANDGO;
        snmp_pdu_add_variable (pdu, nsVacmRowStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof (longvar));

        auth_oid (nsVacmContextPfx, &name_length, groupName, prefix, secModel, secLevel, authtype);
        if (sscanf (argv[arg + 4], "%d", &contextMatch) == 0)
        {
            printf ("invalid contextMatch\n");
            usage ();
            exit (1);
        }
        snmp_pdu_add_variable (pdu, nsVacmContextPfx, name_length,
                               ASN_INTEGER, (u_char *) & contextMatch, sizeof (contextMatch));

        auth_oid (nsVacmViewName, &name_length, groupName, prefix, secModel, secLevel, authtype);
        snmp_pdu_add_variable (pdu, nsVacmViewName, name_length,
                               ASN_OCTET_STR, (u_char *) argv[arg + 5], strlen (argv[arg + 5]));
    }
    else
    {
        printf ("Unknown command\n");
        usage ();
        exit (1);
    }

    /*
     * do the request 
     */
    status = snmp_synch_response (ss, pdu, &response);
    if (status == STAT_SUCCESS)
    {
        if (response)
        {
            if (response->errstat == SNMP_ERR_NOERROR)
            {
                fprintf (stderr, "%s\n", successNotes[command - 1]);
            }
            else
            {
                fprintf (stderr, "Error in packet.\nReason: %s\n", snmp_errstring (response->errstat));
                if (response->errindex != 0)
                {
                    int count;

                    struct variable_list *vars = response->variables;

                    fprintf (stderr, "Failed object: ");
                    for (count = 1; vars && (count != response->errindex); vars = vars->next_variable, count++)
                        ;
                    if (vars)
                        fprint_objid (stderr, vars->name, vars->name_length);
                    fprintf (stderr, "\n");
                }
                exitval = 2;
            }
        }
    }
    else if (status == STAT_TIMEOUT)
    {
        fprintf (stderr, "Timeout: No Response from %s\n", session.peername);
        exitval = 1;
    }
    else
    {
        snmp_sess_perror ("snmpset", ss);
        exitval = 1;
    }

    if (response)
        snmp_free_pdu (response);

    snmp_close (ss);
    SOCK_CLEANUP;
    return exitval;
}
Пример #15
0
int
main(int argc, char *argv[])
{
    netsnmp_session session, *ss;
    netsnmp_pdu    *pdu = NULL, *response = NULL;
#ifdef notused
    netsnmp_variable_list *vars;
#endif

    int             arg;
#ifdef notused
    int             count;
    int             current_name = 0;
    int             current_type = 0;
    int             current_value = 0;
    char           *names[128];
    char            types[128];
    char           *values[128];
    oid             name[MAX_OID_LEN];
#endif
    size_t          name_length = USM_OID_LEN;
    size_t          name_length2 = USM_OID_LEN;
    int             status;
    int             exitval = 0;
    int             rval;
    int             command = 0;
    long            longvar;

    size_t          oldKu_len = SNMP_MAXBUF_SMALL,
        newKu_len = SNMP_MAXBUF_SMALL,
        oldkul_len = SNMP_MAXBUF_SMALL,
        newkul_len = SNMP_MAXBUF_SMALL, keychange_len = SNMP_MAXBUF_SMALL;

    char           *newpass = NULL, *oldpass = NULL;
    u_char          oldKu[SNMP_MAXBUF_SMALL],
        newKu[SNMP_MAXBUF_SMALL],
        oldkul[SNMP_MAXBUF_SMALL],
        newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL];

    authKeyChange = authKeyOid;
    privKeyChange = privKeyOid;

    /*
     * get the common command line arguments 
     */
    switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
    case -2:
        exit(0);
    case -1:
        usage();
        exit(1);
    default:
        break;
    }

    SOCK_STARTUP;

    /*
     * open an SNMP session 
     */
    /*
     * Note:  this wil obtain the engineID needed below 
     */
    ss = snmp_open(&session);
    if (ss == NULL) {
        /*
         * diagnose snmp_open errors with the input netsnmp_session pointer 
         */
        snmp_sess_perror("snmpusm", &session);
        exit(1);
    }

    /*
     * create PDU for SET request and add object names and values to request 
     */
    pdu = snmp_pdu_create(SNMP_MSG_SET);

    if (arg >= argc) {
        fprintf(stderr, "Please specify a operation to perform.\n");
        usage();
        exit(1);
    }

    if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) {

        /*
         * passwd: change a users password.
         *
         * XXX:  Uses the auth type of the calling user, a MD5 user can't
         *       change a SHA user's key.
         */
        command = CMD_PASSWD;
        oldpass = argv[++arg];
        newpass = argv[++arg];

        if (doprivkey == 0 && doauthkey == 0)
            doprivkey = doauthkey = 1;

        if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "New passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            exit(1);
        }

        if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) {
            fprintf(stderr,
                    "Old passphrase must be greater than %d characters in length.\n",
                    USM_LENGTH_P_MIN);
            exit(1);
        }

        /*
         * do we have a securityName?  If not, copy the default 
         */
        if (session.securityName == NULL) {
            session.securityName = 
	      strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					   NETSNMP_DS_LIB_SECNAME));
        }

        /*
         * the old Ku is in the session, but we need the new one 
         */
        if (session.securityAuthProto == NULL) {
            /*
             * get .conf set default 
             */
            const oid      *def =
                get_default_authtype(&session.securityAuthProtoLen);
            session.securityAuthProto =
                snmp_duplicate_objid(def, session.securityAuthProtoLen);
        }
        if (session.securityAuthProto == NULL) {
            /*
             * assume MD5 
             */
            session.securityAuthProtoLen =
                sizeof(usmHMACMD5AuthProtocol) / sizeof(oid);
            session.securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     session.securityAuthProtoLen);
        }
        rval = generate_Ku(session.securityAuthProto,
                           session.securityAuthProtoLen,
                           (u_char *) newpass, strlen(newpass),
                           newKu, &newKu_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the old Ku failed\n");
            exit(1);
        }

        /*
         * the old Ku is in the session, but we need the new one 
         */
        rval = generate_Ku(session.securityAuthProto,
                           session.securityAuthProtoLen,
                           (u_char *) oldpass, strlen(oldpass),
                           oldKu, &oldKu_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the new Ku failed\n");
            exit(1);
        }

        /*
         * generate the two Kul's 
         */
        rval = generate_kul(session.securityAuthProto,
                            session.securityAuthProtoLen,
                            ss->contextEngineID, ss->contextEngineIDLen,
                            oldKu, oldKu_len, oldkul, &oldkul_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the old Kul failed\n");
            exit(1);
        }

        rval = generate_kul(session.securityAuthProto,
                            session.securityAuthProtoLen,
                            ss->contextEngineID, ss->contextEngineIDLen,
                            newKu, newKu_len, newkul, &newkul_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "generating the new Kul failed\n");
            exit(1);
        }

        /*
         * create the keychange string 
         */
        rval = encode_keychange(session.securityAuthProto,
                                session.securityAuthProtoLen,
                                oldkul, oldkul_len,
                                newkul, newkul_len,
                                keychange, &keychange_len);

        if (rval != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr, "encoding the keychange failed\n");
            usage();
            exit(1);
        }

        /*
         * add the keychange string to the outgoing packet 
         */
        if (doauthkey) {
            setup_oid(authKeyChange, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, authKeyChange, name_length,
                                  ASN_OCTET_STR, keychange, keychange_len);
        }
        if (doprivkey) {
            setup_oid(privKeyChange, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      session.securityName);
            snmp_pdu_add_variable(pdu, privKeyChange, name_length,
                                  ASN_OCTET_STR, keychange, keychange_len);
        }

    } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) {
        /*
         * create:  create a user
         *
         * create USER [CLONEFROM]
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to create\n");
            usage();
            exit(1);
        }

        command = CMD_CREATE;

        if (++arg < argc) {
            /*
             * clone the new user from an existing user
             *   (and make them active immediately)
             */
            setup_oid(usmUserStatus, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen, argv[arg-1]);
            longvar = RS_CREATEANDGO;
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));

            setup_oid(usmUserCloneFrom, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      argv[arg - 1]);
            setup_oid(usmUserSecurityName, &name_length2,
                      ss->contextEngineID, ss->contextEngineIDLen,
                      argv[arg]);
            snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                                  ASN_OBJECT_ID,
                                  (u_char *) usmUserSecurityName,
                                  sizeof(oid) * name_length2);
        } else {
            /*
             * create a new (unauthenticated) user from scratch
             * The Net-SNMP agent won't allow such a user to be made active.
             */
            setup_oid(usmUserStatus, &name_length,
                      ss->contextEngineID, ss->contextEngineIDLen, argv[arg-1]);
            longvar = RS_CREATEANDWAIT;
            snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                                  ASN_INTEGER, (u_char *) & longvar,
                                  sizeof(longvar));
        }

    } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) {
        /*
         * create:  clone a user from another
         *
         * cloneFrom USER FROM
         */
        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to operate on\n");
            usage();
            exit(1);
        }

        command = CMD_CLONEFROM;
        setup_oid(usmUserStatus, &name_length,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);
        longvar = RS_ACTIVE;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
        setup_oid(usmUserCloneFrom, &name_length,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);

        if (++arg >= argc) {
            fprintf(stderr,
                    "You must specify the user name to clone from\n");
            usage();
            exit(1);
        }

        setup_oid(usmUserSecurityName, &name_length2,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);
        snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
                              ASN_OBJECT_ID,
                              (u_char *) usmUserSecurityName,
                              sizeof(oid) * name_length2);

    } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) {
        /*
         * delete:  delete a user
         *
         * delete USER
         */
        if (++arg >= argc) {
            fprintf(stderr, "You must specify the user name to delete\n");
            exit(1);
        }

        command = CMD_DELETE;
        setup_oid(usmUserStatus, &name_length,
                  ss->contextEngineID, ss->contextEngineIDLen, argv[arg]);
        longvar = RS_DESTROY;
        snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
                              ASN_INTEGER, (u_char *) & longvar,
                              sizeof(longvar));
    } else {
        fprintf(stderr, "Unknown command\n");
        usage();
        exit(1);
    }


    /*
     * do the request 
     */
    status = snmp_synch_response(ss, pdu, &response);
    if (status == STAT_SUCCESS) {
        if (response) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                fprintf(stderr, "%s\n", successNotes[command - 1]);
            } else {
                fprintf(stderr, "Error in packet.\nReason: %s\n",
                        snmp_errstring(response->errstat));
                if (response->errindex != 0) {
                    int             count;
                    netsnmp_variable_list *vars;
                    fprintf(stderr, "Failed object: ");
                    for (count = 1, vars = response->variables;
                         vars && count != response->errindex;
                         vars = vars->next_variable, count++)
                        /*EMPTY*/;
                    if (vars)
                        fprint_objid(stderr, vars->name,
                                     vars->name_length);
                    fprintf(stderr, "\n");
                }
                exitval = 2;
            }
        }
    } else if (status == STAT_TIMEOUT) {
        fprintf(stderr, "Timeout: No Response from %s\n",
                session.peername);
        exitval = 1;
    } else {                    /* status == STAT_ERROR */
        snmp_sess_perror("snmpset", ss);
        exitval = 1;
    }

    if (response)
        snmp_free_pdu(response);
    snmp_close(ss);
    SOCK_CLEANUP;
    return exitval;
}
Пример #16
0
/**
 * snmp_set2: Gets a single value indicated by the objectid
 * using snmp.
 * @handle: a handle to the snmp session needed to make an
 * snmp transaction.
 * @objid: string containing the OID entry.
 * @value: the value received from snmp will be put in this union.
 *
 * In the case of multiple values being returned, the type in 'value' will be
 * ASN_NULL (0x05). Nothing else in 'value' will be filled in.
 * Use snmp_get_all for doing gets that return multiple values.
 *
 * Return value: Returns 0 if successful, -1 if there was an error.
 **/
SaErrorT snmp_set2(struct snmp_session *ss, 
	           oid *objid,
	           size_t objid_len,
                   struct snmp_value *value) 
{
	struct snmp_pdu *pdu;
	struct snmp_pdu *response;
        struct variable_list *vars;

        void *dataptr = NULL;
        int status = 0;
	SaErrorT rtncode = SA_OK; /* Default - All is OK */

        /*
         * Create the PDU for the data for our request.
         */
        pdu = snmp_pdu_create(SNMP_MSG_SET);

        switch (value->type)
        {
                case ASN_INTEGER:
		case ASN_UNSIGNED:
                case ASN_COUNTER:
			dataptr = &value->integer;
                        break;
                case ASN_OCTET_STR:
			dataptr = value->string;
                        break;
                default:
                        rtncode = SA_ERR_HPI_INVALID_PARAMS;
                        dbg("datatype %c not yet supported by snmp_set2()", 
				value->type);
                        break;
        }

        if (rtncode == SA_OK) {

		/*
		 * Set the data to send out
		 */
                /* Old code - snmp_add_var(pdu, objid, objid_len, datatype, dataptr); */
                //int retcode = snmp_add_var(pdu, objid, objid_len, datatype, dataptr);
		snmp_pdu_add_variable(pdu, objid, objid_len, value->type, dataptr, value->str_len);

        	/*
         	* Send the Request out.
         	*/
        	status = snmp_synch_response(ss, pdu, &response);
        	/*
         	* Process the response.
         	*/
		if (status == STAT_SUCCESS) {
               	 	vars = response->variables;
			if (response->errstat == SNMP_ERR_NOERROR) {
				/* display data */
#ifdef DEBUG
				fprintf(stderr, "*** snmp_set2 ******************************************\n");
					if (CHECK_END(response->variables->type)) {
						fprint_variable(stderr, 
								response->variables->name,
								response->variables->name_length,
								response->variables);  
					}  else 
						fprintf(stderr, "snmp_set2(): No idea.\n");
				fprintf(stderr, "********************************************************\n");
#endif
				if (!(CHECK_END(response->variables->type)) ) {
                                	/* This is one of the exception condition */
				        rtncode = SA_ERR_HPI_NOT_PRESENT;
                                	dbg("snmp exception %d \n",vars->type);
				}
			} else {
                        	dbg("snmp_set2: Error in packet, Reason: %s",
						snmp_errstring(response->errstat));
                                rtncode = errstat2hpi(response->errstat);

			}                
        	} else {
                       	snmp_sess_perror("snmpset", ss);
                       	rtncode = snmpstat2hpi(status);

        	}

        	/* Clean up: free the response */
        	if (response) snmp_free_pdu(response);
	
	}

        return rtncode;

}
Пример #17
0
static int SetSnmp(const char *ip, int port, const char *szoid, int type, void *buffer, unsigned int size, int *pml_result, int *result)
{
   struct snmp_session session, *ss=NULL;
   struct snmp_pdu *pdu=NULL;
   struct snmp_pdu *response=NULL;
   oid anOID[MAX_OID_LEN];
   size_t anOID_len = MAX_OID_LEN;
   unsigned int i, len=0;
   uint32_t val;

   *result = HPMUD_R_IO_ERROR;
   *pml_result = PML_EV_ERROR_UNKNOWN_REQUEST;

   init_snmp("snmpapp");

   snmp_sess_init(&session );                   /* set up defaults */
   session.peername = (char *)ip;
   session.version = SNMP_VERSION_1;
   session.community = (unsigned char *)SnmpPort[port];
   session.community_len = strlen((const char *)session.community);
   ss = snmp_open(&session);                     /* establish the session */
   if (ss == NULL)
      goto bugout;

   pdu = snmp_pdu_create(SNMP_MSG_SET);
   read_objid(szoid, anOID, &anOID_len);

   switch (type)
   {
      case PML_DT_ENUMERATION:
      case PML_DT_SIGNED_INTEGER:
         /* Convert PML big-endian to SNMP little-endian byte stream. */
         for(i=0, val=0; i<size && i<sizeof(val); i++)    
            val = ((val << 8) | ((unsigned char *)buffer)[i]);
         snmp_pdu_add_variable(pdu, anOID, anOID_len, ASN_INTEGER, (unsigned char *)&val, sizeof(val));
         break;
      case PML_DT_REAL:
      case PML_DT_STRING:
      case PML_DT_BINARY:
      case PML_DT_NULL_VALUE:
      case PML_DT_COLLECTION:
      default:
         snmp_pdu_add_variable(pdu, anOID, anOID_len, ASN_OCTET_STR, buffer, size);
         break;
   }

  
   /* Send the request and get response. */
   if (snmp_synch_response(ss, pdu, &response) != STAT_SUCCESS)
      goto bugout;

   if (response->errstat == SNMP_ERR_NOERROR) 
   {
      len = size;
   }

   *pml_result = SnmpErrorToPml(response->errstat);
   *result = HPMUD_R_OK;

bugout:
   if (response != NULL)
      snmp_free_pdu(response);
   if (ss != NULL)
      snmp_close(ss);
   return len;
}