Exemple #1
0
void add_responses(struct variable_list *vars, struct oid_value ***next_ov, oid *name, size_t *name_length) {
	int found = 0;
	for (struct variable_list *var = vars; var; var = var->next_variable) {
		if (var->name_length < PRINTER_OID_LEN ||
				0 != netsnmp_oid_equals(PRINTER_OID, PRINTER_OID_LEN, var->name, PRINTER_OID_LEN)) {
			// This OID does not have the printer OID prefix, so we're done.
			*name_length = 0;
			return;
		}

		oid *objid = malloc(var->name_length * sizeof(oid));
		memmove(objid, var->name, var->name_length * sizeof(oid));

		size_t value_length = 1, out_length = 0;;
		char *value = malloc(value_length);
		sprint_realloc_value((unsigned char **)&value, &value_length, &out_length, 1, var->name, var->name_length, var);

		**next_ov = calloc(1, sizeof(struct oid_value));
		(**next_ov)->name = objid;
		(**next_ov)->name_length = var->name_length;
		(**next_ov)->value = value;
		*next_ov = &(**next_ov)->next;

		*name_length = var->name_length;
		memmove(name, var->name, *name_length * sizeof(oid));
	}

	return;
}
Exemple #2
0
void
convert_v2_to_v1(netsnmp_variable_list * vars, netsnmp_pdu *template_pdu)
{
    netsnmp_variable_list *v, *trap_v = NULL, *ent_v = NULL;
    oid             trap_prefix[] = { SNMPV2_TRAPS_PREFIX };
    int             len;

    for (v = vars; v; v = v->next_variable) {
        if (netsnmp_oid_equals(v->name, v->name_length,
                             snmptrap_oid, OID_LENGTH(snmptrap_oid)) == 0)
            trap_v = v;
        if (netsnmp_oid_equals(v->name, v->name_length,
                             snmptrapenterprise_oid,
                             OID_LENGTH(snmptrapenterprise_oid)) == 0)
            ent_v = v;
    }

    if (!trap_v)
        return;                 /* Can't find v2 snmpTrapOID varbind */

    /*
     * Is this a 'standard' trap?
     *  Or at least, does it have the correct prefix?
     */
    if (netsnmp_oid_equals(trap_v->val.objid, OID_LENGTH(trap_prefix),
                         trap_prefix, OID_LENGTH(trap_prefix)) == 0) {
        template_pdu->trap_type =
            trap_v->val.objid[OID_LENGTH(trap_prefix)] - 1;
        template_pdu->specific_type = 0;
    } else {
        len = trap_v->val_len / sizeof(oid);
        template_pdu->trap_type = 6;    /* enterprise specific */
        template_pdu->specific_type = trap_v->val.objid[len - 1];
    }

    /*
     *  TODO:
     *    Extract the appropriate enterprise value from 'ent_v'
     *    Remove uptime/trapOID varbinds from 'vars' list
     */

}
void           *
header_complex_get_from_oid(struct header_complex_index *datalist,
                            oid * searchfor, size_t searchfor_len)
{
    struct header_complex_index *nptr;
    for (nptr = datalist; nptr != NULL; nptr = nptr->next) {
        if (netsnmp_oid_equals(searchfor, searchfor_len,
                             nptr->name, nptr->namelen) == 0)
            return nptr->data;
    }
    return NULL;
}
Exemple #4
0
int
my_test_handler(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{

    oid             myoid1[] = { 1, 2, 3, 4, 5, 6 };
    static u_long   accesses = 0;

    DEBUGMSGTL(("testhandler", "Got request:\n"));
    /*
     * loop through requests 
     */
    while (requests) {
        netsnmp_variable_list *var = requests->requestvb;

        DEBUGMSGTL(("testhandler", "  oid:"));
        DEBUGMSGOID(("testhandler", var->name, var->name_length));
        DEBUGMSG(("testhandler", "\n"));

        switch (reqinfo->mode) {
        case MODE_GET:
            if (netsnmp_oid_equals(var->name, var->name_length, myoid1, 6)
                == 0) {
                snmp_set_var_typed_value(var, ASN_INTEGER,
                                         (u_char *) & accesses,
                                         sizeof(accesses));
                return SNMP_ERR_NOERROR;
            }
            break;

        case MODE_GETNEXT:
            if (snmp_oid_compare(var->name, var->name_length, myoid1, 6)
                < 0) {
                snmp_set_var_objid(var, myoid1, 6);
                snmp_set_var_typed_value(var, ASN_INTEGER,
                                         (u_char *) & accesses,
                                         sizeof(accesses));
                return SNMP_ERR_NOERROR;
            }
            break;

        default:
            netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
            break;
        }

        requests = requests->next;
    }
    return SNMP_ERR_NOERROR;
}
Exemple #5
0
/** find existing cache
 */
netsnmp_cache *
netsnmp_cache_find_by_oid(const oid * rootoid, int rootoid_len)
{
    netsnmp_cache  *cache;

    for (cache = cache_head; cache; cache = cache->next) {
        if (0 == netsnmp_oid_equals(cache->rootoid, cache->rootoid_len,
                                    rootoid, rootoid_len))
            return cache;
    }
    
    return NULL;
}
Exemple #6
0
int
netsnmp_tdomain_support(const oid * in_oid,
                        size_t in_len,
                        const oid ** out_oid, size_t * out_len)
{
    netsnmp_tdomain *d = NULL;

    for (d = domain_list; d != NULL; d = d->next) {
        if (netsnmp_oid_equals(in_oid, in_len, d->name, d->name_length) == 0) {
            if (out_oid != NULL && out_len != NULL) {
                *out_oid = d->name;
                *out_len = d->name_length;
            }
            return 1;
        }
    }
    return 0;
}
Exemple #7
0
unsigned long
count_indexes(oid * name, size_t namelen, int include_unallocated)
{
    struct snmp_index *i = NULL, *j = NULL;
    unsigned long   n = 0;

    for (i = snmp_index_head; i != NULL; i = i->next_oid) {
        if (netsnmp_oid_equals(name, namelen,
                             i->varbind->name,
                             i->varbind->name_length) == 0) {
            for (j = i; j != NULL; j = j->next_idx) {
                if (j->allocated || include_unallocated) {
                    n++;
                }
            }
        }
    }
    return n;
}
Exemple #8
0
int
netsnmp_tdomain_unregister(netsnmp_tdomain *n)
{
    netsnmp_tdomain **prevNext = &domain_list, *d;

    if (n != NULL) {
        for (d = domain_list; d != NULL; d = d->next) {
            if (netsnmp_oid_equals(n->name, n->name_length,
                                d->name, d->name_length) == 0) {
                *prevNext = n->next;
		SNMP_FREE(n->prefix);
                return 1;
            }
            prevNext = &(d->next);
        }
        return 0;
    } else {
        return 0;
    }
}
Exemple #9
0
int
netsnmp_tdomain_register(netsnmp_tdomain *n)
{
    netsnmp_tdomain **prevNext = &domain_list, *d;

    if (n != NULL) {
        for (d = domain_list; d != NULL; d = d->next) {
            if (netsnmp_oid_equals(n->name, n->name_length,
                                d->name, d->name_length) == 0) {
                /*
                 * Already registered.  
                 */
                return 0;
            }
            prevNext = &(d->next);
        }
        n->next = NULL;
        *prevNext = n;
        return 1;
    } else {
        return 0;
    }
}
Exemple #10
0
static int noit_snmp_oid_to_checkid(oid *o, int l, uuid_t checkid, char *out) {
  int i;
  char _uuid_str[UUID_STR_LEN+1], *cp, *uuid_str;

  uuid_str = out ? out : _uuid_str;
  if(l != reconnoiter_check_oid_len) {
    noitL(nlerr, "unsupported (length) trap recieved\n");
    return -1;
  }
  if(netsnmp_oid_equals(o,
                        reconnoiter_check_prefix_oid_len,
                        reconnoiter_check_prefix_oid,
                        reconnoiter_check_prefix_oid_len) != 0) {
    noitL(nlerr, "unsupported (wrong namespace) trap recieved\n");
    return -1;
  }
  /* encode this as a uuid */
  cp = uuid_str;
  for(i=0;
      i < reconnoiter_check_oid_len - reconnoiter_check_prefix_oid_len;
      i++) {
    oid v = o[i + reconnoiter_check_prefix_oid_len];
    if(v > 0xffff) {
      noitL(nlerr, "trap target oid [%ld] out of range\n", (long int)v);
      return -1;
    }
    snprintf(cp, 5, "%04x", (unsigned short)(v & 0xffff));
    cp += 4;
    /* hyphens after index 1,2,3,4 */
    if(i > 0 && i < 5) *cp++ = '-';
  }
  if(uuid_parse(uuid_str, checkid) != 0) {
    noitL(nlerr, "unexpected error decoding trap uuid '%s'\n", uuid_str);
    return -1;
  }
  return 0;
}
Exemple #11
0
netsnmp_transport *
netsnmp_tdomain_transport_oid(const oid * dom,
                              size_t dom_len,
                              const u_char * o, size_t o_len, int local)
{
    netsnmp_tdomain *d;
    int             i;

    DEBUGMSGTL(("tdomain", "domain \""));
    DEBUGMSGOID(("tdomain", dom, dom_len));
    DEBUGMSG(("tdomain", "\"\n"));

    for (d = domain_list; d != NULL; d = d->next) {
        for (i = 0; d->prefix[i] != NULL; i++) {
            if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) ==
                0) {
                return d->f_create_from_ostring(o, o_len, local);
            }
        }
    }

    snmp_log(LOG_ERR, "No support for requested transport domain\n");
    return NULL;
}
Exemple #12
0
static int snmp_get_rssi_cb(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) {
	char value[15] = {0,};
	char *endptr = NULL;
	int value_num = 0;
	struct variable_list *vars = NULL;
	repeater_t *repeater = NULL;
	in_addr_t ipaddr;
	flag_t dodbupdate = 0;

	if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
		if (pdu->errstat == SNMP_ERR_NOERROR) {
			ipaddr = inet_addr(sp->peername);
			repeater = repeaters_findbyip((struct in_addr *)&ipaddr);

			for (vars = pdu->variables; vars; vars = vars->next_variable) {
				if (netsnmp_oid_equals(vars->name, vars->name_length, oid_rssi_ts1, oid_rssi_ts1_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG LOGLEVEL_SNMP "snmp: invalid ts1 rssi value received: %s\n", sp->peername);
					else {
						if (value_num > -200) {
							if (repeater != NULL) {
								repeater->slot[0].rssi = value_num;
								if (repeater->slot[0].avg_rssi == 0)
									repeater->slot[0].avg_rssi = value_num;
								else
									repeater->slot[0].avg_rssi = (repeater->slot[0].avg_rssi+value_num)/2.0;
								dodbupdate = 1;
							}
							console_log(LOGLEVEL_SNMP "snmp [%s]: got ts1 rssi value %d\n", sp->peername, value_num);
						}
					}
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_rssi_ts2, oid_rssi_ts2_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG LOGLEVEL_SNMP "snmp: invalid ts2 rssi value received: %s\n", value);
					else {
						if (value_num > -200) {
							if (repeater != NULL) {
								repeater->slot[1].rssi = value_num;
								if (repeater->slot[1].avg_rssi == 0)
									repeater->slot[1].avg_rssi = value_num;
								else
									repeater->slot[1].avg_rssi = (repeater->slot[1].avg_rssi+value_num)/2.0;
								dodbupdate = 1;
							}
							console_log(LOGLEVEL_SNMP "snmp [%s]: got ts2 rssi value %d\n", sp->peername, value_num);
						}
					}
				}
			}

			if (dodbupdate)
				remotedb_update(repeater);

			snmp_rssi_received = 1;
		} else
			console_log(LOGLEVEL_DEBUG "snmp: rssi read error\n");
    } else
    	console_log(LOGLEVEL_DEBUG "snmp: rssi read timeout\n");

	return 1;
}
Exemple #13
0
void
send_enterprise_trap_vars(int trap,
                          int specific,
                          oid * enterprise, int enterprise_length,
                          netsnmp_variable_list * vars)
{
    netsnmp_variable_list uptime_var, snmptrap_var, enterprise_var;
    netsnmp_variable_list *v2_vars, *last_var = NULL;
    netsnmp_pdu    *template_pdu;
    u_long          uptime;
    in_addr_t      *pdu_in_addr_t;
    struct trap_sink *sink;
#ifdef BRCM_SNMP_MIB_SUPPORT
    oid             temp_oid[MAX_OID_LEN];
#endif
    /*
     * Initialise SNMPv2 required variables
     */
    uptime = netsnmp_get_agent_uptime();
    memset(&uptime_var, 0, sizeof(netsnmp_variable_list));
    snmp_set_var_objid(&uptime_var, sysuptime_oid,
                       OID_LENGTH(sysuptime_oid));
    snmp_set_var_value(&uptime_var, (u_char *) & uptime, sizeof(uptime));
    uptime_var.type = ASN_TIMETICKS;
    uptime_var.next_variable = &snmptrap_var;

    memset(&snmptrap_var, 0, sizeof(netsnmp_variable_list));
    snmp_set_var_objid(&snmptrap_var, snmptrap_oid,
                       OID_LENGTH(snmptrap_oid));
    /*
     * value set later .... 
     */
    snmptrap_var.type = ASN_OBJECT_ID;
    if (vars)
        snmptrap_var.next_variable = vars;
    else
        snmptrap_var.next_variable = &enterprise_var;

    /*
     * find end of provided varbind list,
     * ready to append the enterprise info if necessary 
     */
    last_var = vars;
    while (last_var && last_var->next_variable)
        last_var = last_var->next_variable;

    memset(&enterprise_var, 0, sizeof(netsnmp_variable_list));
    snmp_set_var_objid(&enterprise_var,
                       snmptrapenterprise_oid,
                       OID_LENGTH(snmptrapenterprise_oid));
    snmp_set_var_value(&enterprise_var, (u_char *) enterprise,
                       enterprise_length * sizeof(oid));
    enterprise_var.type = ASN_OBJECT_ID;
    enterprise_var.next_variable = NULL;

    v2_vars = &uptime_var;

    /*
     *  Create a template PDU, ready for sending
     */
    template_pdu = snmp_pdu_create(SNMP_MSG_TRAP);
    if (template_pdu == NULL) {
        /*
         * Free memory if value stored dynamically 
         */
        snmp_set_var_value(&enterprise_var, NULL, 0);
        return;
    }
    template_pdu->trap_type = trap;
    template_pdu->specific_type = specific;
    if (snmp_clone_mem((void **) &template_pdu->enterprise,
                       enterprise, enterprise_length * sizeof(oid))) {
        snmp_free_pdu(template_pdu);
        snmp_set_var_value(&enterprise_var, NULL, 0);
        return;
    }
    template_pdu->enterprise_length = enterprise_length;
    template_pdu->flags |= UCD_MSG_FLAG_FORCE_PDU_COPY;

    pdu_in_addr_t = (in_addr_t *) template_pdu->agent_addr;
    *pdu_in_addr_t = get_myaddr();
    template_pdu->time = uptime;

    /*
     *  Now use the parameters to determine
     *    which v2 variables are needed,
     *    and what values they should take.
     */
    switch (trap) {
    case -1:                   /*
                                 *      SNMPv2 only
                                 *  Check to see whether the variables provided
                                 *    are sufficient for SNMPv2 notifications
                                 */
        if (vars && netsnmp_oid_equals(vars->name, vars->name_length,
                                     sysuptime_oid,
                                     OID_LENGTH(sysuptime_oid)) == 0)
            v2_vars = vars;
        else if (vars && netsnmp_oid_equals(vars->name, vars->name_length,
                                          snmptrap_oid,
                                          OID_LENGTH(snmptrap_oid)) == 0)
            uptime_var.next_variable = vars;
        else {
            /*
             * Hmmm... we don't seem to have a value - oops! 
             */
            snmptrap_var.next_variable = vars;
        }
        last_var = NULL;        /* Don't need enterprise info */
        convert_v2_to_v1(vars, template_pdu);
        break;

        /*
         * "Standard" SNMPv1 traps 
         */

    case SNMP_TRAP_COLDSTART:
        snmp_set_var_value(&snmptrap_var,
                           (u_char *) cold_start_oid,
                           sizeof(cold_start_oid));
        break;
    case SNMP_TRAP_WARMSTART:
        snmp_set_var_value(&snmptrap_var,
                           (u_char *) warm_start_oid,
                           sizeof(warm_start_oid));
        break;
    case SNMP_TRAP_LINKDOWN:
        snmp_set_var_value(&snmptrap_var,
                           (u_char *) link_down_oid,
                           sizeof(link_down_oid));
        break;
    case SNMP_TRAP_LINKUP:
        snmp_set_var_value(&snmptrap_var,
                           (u_char *) link_up_oid, sizeof(link_up_oid));
        break;
    case SNMP_TRAP_AUTHFAIL:
        if (snmp_enableauthentraps == SNMP_AUTHENTICATED_TRAPS_DISABLED) {
            snmp_free_pdu(template_pdu);
            snmp_set_var_value(&enterprise_var, NULL, 0);
            return;
        }
        snmp_set_var_value(&snmptrap_var,
                           (u_char *) auth_fail_oid,
                           sizeof(auth_fail_oid));
        break;
    case SNMP_TRAP_EGPNEIGHBORLOSS:
        snmp_set_var_value(&snmptrap_var,
                           (u_char *) egp_xxx_oid, sizeof(egp_xxx_oid));
        break;

#ifdef BRCM_SNMP_MIB_SUPPORT
    case SNMP_TRAP_ENTERPRISESPECIFIC:
        memcpy(temp_oid,
               (char *) enterprise, (enterprise_length) * sizeof(oid));
        temp_oid[enterprise_length] = 0;
        temp_oid[enterprise_length + 1] = specific;
        snmp_set_var_value(&snmptrap_var,
                           (u_char *) temp_oid,
                           (enterprise_length + 2) * sizeof(oid));
        snmptrap_var.next_variable = vars;
        last_var = NULL;        /* Don't need version info */
        break;
#endif /* BRCM_SNMP_MIB_SUPPORT */
    }


    /*
     *  Now loop through the list of trap sinks,
     *   sending an appropriately formatted PDU to each
     */
    for (sink = sinks; sink; sink = sink->next) {
        if (sink->version == SNMP_VERSION_1 && trap == -1)
            continue;           /* Skip v1 sinks for v2 only traps */
        template_pdu->command = sink->pdutype;

        if (sink->version != SNMP_VERSION_1) {
            template_pdu->variables = v2_vars;
            if (last_var)
                last_var->next_variable = &enterprise_var;
        } else
            template_pdu->variables = vars;

        send_trap_to_sess(sink->sesp, template_pdu);

        if (sink->version != SNMP_VERSION_1 && last_var)
            last_var->next_variable = NULL;
    }

    /*
     * send stuff to registered callbacks 
     */
    /*
     * v2 traps/informs 
     */
    template_pdu->variables = v2_vars;
    if (last_var)
        last_var->next_variable = &enterprise_var;

    snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                        SNMPD_CALLBACK_SEND_TRAP2, template_pdu);

    if (last_var)
        last_var->next_variable = NULL;

    /*
     * v1 traps 
     */
    template_pdu->command = SNMP_MSG_TRAP;
    template_pdu->variables = vars;

    snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
                        SNMPD_CALLBACK_SEND_TRAP1, template_pdu);

    /*
     * Free memory if values stored dynamically 
     */
    snmp_set_var_value(&enterprise_var, NULL, 0);
    snmp_set_var_value(&snmptrap_var, NULL, 0);
    /*
     * Ensure we don't free anything we shouldn't 
     */
    if (last_var)
        last_var->next_variable = NULL;
    template_pdu->variables = NULL;
    snmp_free_pdu(template_pdu);
}
Exemple #14
0
int
tsm_process_in_msg(struct snmp_secmod_incoming_params *parms)
{
    u_char type_value;
    size_t remaining;
    u_char *data_ptr;
    netsnmp_tmStateReference *tmStateRef;
    netsnmp_tsmSecurityReference *tsmSecRef;
    u_char          ourEngineID[SNMP_MAX_ENG_SIZE];
    static size_t   ourEngineID_len = sizeof(ourEngineID);
    
    /* Section 5.2, step 1: Set the securityEngineID to the local
       snmpEngineID. */
    ourEngineID_len =
        snmpv3_get_engineID((u_char*) ourEngineID, ourEngineID_len);
    netsnmp_assert_or_return(ourEngineID_len != 0 &&
                             ourEngineID_len <= *parms->secEngineIDLen,
                             SNMPERR_GENERR);
    memcpy(parms->secEngineID, ourEngineID, *parms->secEngineIDLen);

    /* Section 5.2, step 2: If tmStateReference does not refer to a
       cache containing values for tmTransportDomain,
       tmTransportAddress, tmSecurityName, and
       tmTransportSecurityLevel, then the snmpTsmInvalidCaches counter
       is incremented, an error indication is returned to the calling
       module, and Security Model processing stops for this
       message. */
    if (!parms->pdu->transport_data ||
        sizeof(netsnmp_tmStateReference) !=
        parms->pdu->transport_data_length) {
        /* if we're not coming in over a proper transport; bail! */
        DEBUGMSGTL(("tsm","improper transport data\n"));
        return -1;
    }
    tmStateRef = (netsnmp_tmStateReference *) parms->pdu->transport_data;
    parms->pdu->transport_data = NULL;

    if (tmStateRef == NULL ||
        /* not needed: tmStateRef->transportDomain == NULL || */
        /* not needed: tmStateRef->transportAddress == NULL || */
        tmStateRef->securityName[0] == '\0'
        ) {
        snmp_increment_statistic(STAT_TSM_SNMPTSMINVALIDCACHES);
        return SNMPERR_GENERR;
    }

    /* Section 5.2, step 3: Copy the tmSecurityName to securityName. */
    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                               NETSNMP_DS_LIB_TSM_USE_PREFIX)) {
        /* Section 5.2, step 3:
          If the snmpTsmConfigurationUsePrefix object is set to true, then
          use the tmTransportDomain to look up the corresponding prefix.
        */
        const char *prefix = NULL;
        /*
          possibilities:
           |--------------------+-------|
           | snmpTLSTCPDomain   | tls:  |
           | snmpDTLSUDPDomain  | dtls: |
           | snmpSSHDomain      | ssh:  |
           |--------------------+-------|
        */
        
        if (tmStateRef->transportDomain == NULL) {
            /* XXX: snmpTsmInvalidCaches++ ??? */
            return SNMPERR_GENERR;
        }

        /* XXX: cache in session! */
#ifdef NETSNMP_TRANSPORT_SSH_DOMAIN
        if (netsnmp_oid_equals(netsnmp_snmpSSHDomain,
                               netsnmp_snmpSSHDomain_len,
                               tmStateRef->transportDomain,
                               tmStateRef->transportDomainLen) == 0) {
            prefix = "ssh";
        }
#endif /*  NETSNMP_TRANSPORT_SSH_DOMAIN */

#ifdef NETSNMP_TRANSPORT_DTLSUDP_DOMAIN
        if (netsnmp_oid_equals(netsnmpDTLSUDPDomain,
                               netsnmpDTLSUDPDomain_len,
                               tmStateRef->transportDomain,
                               tmStateRef->transportDomainLen) == 0) {
            
            prefix = "dtls";
        }
#endif /* NETSNMP_TRANSPORT_DTLSUDP_DOMAIN */

#ifdef NETSNMP_TRANSPORT_TLSTCP_DOMAIN
        if (netsnmp_oid_equals(netsnmpTLSTCPDomain,
                               netsnmpTLSTCPDomain_len,
                               tmStateRef->transportDomain,
                               tmStateRef->transportDomainLen) == 0) {
            
            prefix = "tls";
        }
#endif /* NETSNMP_TRANSPORT_TLSTCP_DOMAIN */

        /* Section 5.2, step 3:
          If the prefix lookup fails for any reason, then the
          snmpTsmUnknownPrefixes counter is incremented, an error
          indication is returned to the calling module, and message
          processing stops.
        */
        if (prefix == NULL) {
            snmp_increment_statistic(STAT_TSM_SNMPTSMUNKNOWNPREFIXES);
            return SNMPERR_GENERR;
        }

        /* Section 5.2, step 3:
          If the lookup succeeds but the prefix length is less than 1 or
          greater than 4 octets, then the snmpTsmInvalidPrefixes counter
          is incremented, an error indication is returned to the calling
          module, and message processing stops.
        */
#ifdef NOT_USING_HARDCODED_PREFIXES
        /* the above code actually ensures this will never happen as
           we don't support a dynamic prefix database where this might
           happen. */
        if (strlen(prefix) < 1 || strlen(prefix) > 4) {
            /* XXX: snmpTsmInvalidPrefixes++ */
            return SNMPERR_GENERR;
        }
#endif
        
        /* Section 5.2, step 3:
          Set the securityName to be the concatenation of the prefix, a
          ':' character (US-ASCII 0x3a), and the tmSecurityName.
        */
        snprintf(parms->secName, *parms->secNameLen,
                 "%s:%s", prefix, tmStateRef->securityName);
    } else {
        /* if the use prefix flag wasn't set, do a straight copy */
        strncpy(parms->secName, tmStateRef->securityName, *parms->secNameLen);
    }

    /* set the length of the security name */
    *parms->secNameLen = strlen(parms->secName);
    DEBUGMSGTL(("tsm", "user: %s/%d\n", parms->secName, (int)*parms->secNameLen));

    /* Section 5.2 Step 4:
       Compare the value of tmTransportSecurityLevel in the
       tmStateReference cache to the value of the securityLevel
       parameter passed in the processIncomingMsg ASI.  If securityLevel
       specifies privacy (Priv) and tmTransportSecurityLevel specifies
       no privacy (noPriv), or if securityLevel specifies authentication
       (auth) and tmTransportSecurityLevel specifies no authentication
       (noAuth) was provided by the Transport Model, then the
       snmpTsmInadequateSecurityLevels counter is incremented, an error
       indication (unsupportedSecurityLevel) together with the OID and
       value of the incremented counter is returned to the calling
       module, and Transport Security Model processing stops for this
       message.*/
    if (parms->secLevel > tmStateRef->transportSecurityLevel) {
        snmp_increment_statistic(STAT_TSM_SNMPTSMINADEQUATESECURITYLEVELS);
        DEBUGMSGTL(("tsm", "inadequate security level: %d\n", parms->secLevel));
        /* net-snmp returns error codes not OIDs, which are dealt with later */
        return SNMPERR_UNSUPPORTED_SEC_LEVEL;
    }

    /* Section 5.2 Step 5
       The tmStateReference is cached as cachedSecurityData so that a
       possible response to this message will use the same security
       parameters.  Then securityStateReference is set for subsequent
       references to this cached data.
    */
    if (NULL == *parms->secStateRef) {
        tsmSecRef = SNMP_MALLOC_TYPEDEF(netsnmp_tsmSecurityReference);
    } else {
        tsmSecRef = *parms->secStateRef;
    }

    netsnmp_assert_or_return(NULL != tsmSecRef, SNMPERR_GENERR);

    *parms->secStateRef = tsmSecRef;
    tsmSecRef->tmStateRef = tmStateRef;

    /* If this did not come through a tunneled connection, this
       security model is inappropriate (and would be a HUGE security
       hole to assume otherwise).  This is functionally a double check
       since the pdu wouldn't have transport data otherwise.  But this
       is safer though is functionally an extra step beyond the TSM
       RFC. */
    DEBUGMSGTL(("tsm","checking how we got here\n"));
    if (!(parms->pdu->flags & UCD_MSG_FLAG_TUNNELED)) {
        DEBUGMSGTL(("tsm","  pdu not tunneled\n"));
        if (!(parms->sess->flags & NETSNMP_TRANSPORT_FLAG_TUNNELED)) {
            DEBUGMSGTL(("tsm","  session not tunneled\n"));
            return SNMPERR_USM_AUTHENTICATIONFAILURE;
        }
        DEBUGMSGTL(("tsm","  but session is tunneled\n"));
    } else {
        DEBUGMSGTL(("tsm","  tunneled\n"));
    }

    /* Section 5.2, Step 6:
       The scopedPDU component is extracted from the wholeMsg. */
    /*
     * Eat the first octet header.
     */
    remaining = parms->wholeMsgLen - (parms->secParams - parms->wholeMsg);
    if ((data_ptr = asn_parse_sequence(parms->secParams, &remaining,
                                        &type_value,
                                        (ASN_UNIVERSAL | ASN_PRIMITIVE |
                                         ASN_OCTET_STR),
                                        "tsm first octet")) == NULL) {
        /*
         * RETURN parse error 
         */
        return SNMPERR_ASN_PARSE_ERR;
    }
    
    *parms->scopedPdu = data_ptr;
    *parms->scopedPduLen = parms->wholeMsgLen - (data_ptr - parms->wholeMsg);

    /* Section 5.2, Step 7:
       The maxSizeResponseScopedPDU is calculated.  This is the maximum
       size allowed for a scopedPDU for a possible Response message.
     */
    *parms->maxSizeResponse = parms->maxMsgSize; /* XXX */

    /* Section 5.2, Step 8:
       The statusInformation is set to success and a return is made to
       the calling module passing back the OUT parameters as specified
       in the processIncomingMsg ASI.
    */
    return SNMPERR_SUCCESS;
}
Exemple #15
0
/** implements the old_api handler */
int
netsnmp_old_api_helper(netsnmp_mib_handler *handler,
                       netsnmp_handler_registration *reginfo,
                       netsnmp_agent_request_info *reqinfo,
                       netsnmp_request_info *requests)
{

#if MIB_CLIENTS_ARE_EVIL
    oid             save[MAX_OID_LEN];
    size_t          savelen = 0;
#endif
    struct variable compat_var, *cvp = &compat_var;
    int             exact = 1;
    int             status;

    struct variable *vp;
    netsnmp_old_api_cache *cacheptr;
    netsnmp_agent_session *oldasp = NULL;
    u_char         *access = NULL;
    WriteMethod    *write_method = NULL;
    size_t          len;
    size_t          tmp_len;
    oid             tmp_name[MAX_OID_LEN];

    vp = (struct variable *) handler->myvoid;

    /*
     * create old variable structure with right information 
     */
    memcpy(cvp->name, reginfo->rootoid,
           reginfo->rootoid_len * sizeof(oid));
    cvp->namelen = reginfo->rootoid_len;
    cvp->type = vp->type;
    cvp->magic = vp->magic;
    cvp->acl = vp->acl;
    cvp->findVar = vp->findVar;

    switch (reqinfo->mode) {
    case MODE_GETNEXT:
    case MODE_GETBULK:
        exact = 0;
    }

    for (; requests; requests = requests->next) {

#if MIB_CLIENTS_ARE_EVIL
        savelen = requests->requestvb->name_length;
        memcpy(save, requests->requestvb->name, savelen * sizeof(oid));
#endif

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
#ifndef NETSNMP_NO_WRITE_SUPPORT
        case MODE_SET_RESERVE1:
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
            /*
             * Actually call the old mib-module function 
             */
            if (vp && vp->findVar) {
                memcpy(tmp_name, requests->requestvb->name,
                                 requests->requestvb->name_length*sizeof(oid));
                tmp_len = requests->requestvb->name_length;
                access = (*(vp->findVar)) (cvp, tmp_name, &tmp_len,
                                           exact, &len, &write_method);
                snmp_set_var_objid( requests->requestvb, tmp_name, tmp_len );
            }
            else
                access = NULL;

#ifdef WWW_FIX
            if (IS_DELEGATED(cvp->type)) {
                add_method = (AddVarMethod *) statP;
                requests->delayed = 1;
                have_delegated = 1;
                continue;       /* WWW: This may not get to the right place */
            }
#endif

            /*
             * WWW: end range checking 
             */
            if (access) {
                /*
                 * result returned 
                 */
#ifndef NETSNMP_NO_WRITE_SUPPORT
                if (reqinfo->mode != MODE_SET_RESERVE1)
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
                    snmp_set_var_typed_value(requests->requestvb,
                                             cvp->type, access, len);
            } else {
                /*
                 * no result returned 
                 */
#if MIB_CLIENTS_ARE_EVIL
                if (access == NULL) {
                    if (netsnmp_oid_equals(requests->requestvb->name,
                                         requests->requestvb->name_length,
                                         save, savelen) != 0) {
                        DEBUGMSGTL(("old_api", "evil_client: %s\n",
                                    reginfo->handlerName));
                        memcpy(requests->requestvb->name, save,
                               savelen * sizeof(oid));
                        requests->requestvb->name_length = savelen;
                    }
                }
#endif
            }

            /*
             * AAA: fall through for everything that is a set (see BBB) 
             */
#ifndef NETSNMP_NO_WRITE_SUPPORT
            if (reqinfo->mode != MODE_SET_RESERVE1)
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
                break;

            cacheptr = SNMP_MALLOC_TYPEDEF(netsnmp_old_api_cache);
            if (!cacheptr)
                return netsnmp_set_request_error(reqinfo, requests,
                                                 SNMP_ERR_RESOURCEUNAVAILABLE);
            cacheptr->data = access;
            cacheptr->write_method = write_method;
            write_method = NULL;
            netsnmp_request_add_list_data(requests,
                                          netsnmp_create_data_list
                                          (OLD_API_NAME, cacheptr,
                                           &free_wrapper));
            /*
             * BBB: fall through for everything that is a set (see AAA) 
             */

        default:
            /*
             * WWW: explicitly list the SET conditions 
             */
            /*
             * (the rest of the) SET contions 
             */
            cacheptr =
                (netsnmp_old_api_cache *)
                netsnmp_request_get_list_data(requests, OLD_API_NAME);

            if (cacheptr == NULL || cacheptr->write_method == NULL) {
                /*
                 * WWW: try to set ourselves if possible? 
                 */
                return netsnmp_set_request_error(reqinfo, requests,
                                                 SNMP_ERR_NOTWRITABLE);
            }

            oldasp = netsnmp_get_current_agent_session();
            set_current_agent_session(reqinfo->asp);
            status =
                (*(cacheptr->write_method)) (reqinfo->mode,
                                             requests->requestvb->val.
                                             string,
                                             requests->requestvb->type,
                                             requests->requestvb->val_len,
                                             cacheptr->data,
                                             requests->requestvb->name,
                                             requests->requestvb->
                                             name_length);
            set_current_agent_session(oldasp);

            if (status != SNMP_ERR_NOERROR) {
                netsnmp_set_request_error(reqinfo, requests, status);
            }

            /*
             * clean up is done by the automatic freeing of the
             * cache stored in the request. 
             */

            break;
        }
    }
    return SNMP_ERR_NOERROR;
}
Exemple #16
0
static int snmp_get_repeaterinfo_cb(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) {
	char value[200] = {0,};
	char *endptr = NULL;
	int value_num = 0;
	struct variable_list *vars = NULL;
	repeater_t *repeater = NULL;
	in_addr_t ipaddr;
	char value_utf16[sizeof(value)/2] = {0,};
	char value_utf8[sizeof(value_utf16)/2] = {0,};
	int length = 0;
	flag_t dodbupdate = 0;

	if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
		if (pdu->errstat == SNMP_ERR_NOERROR) {
			ipaddr = inet_addr(sp->peername);
			repeater = repeaters_findbyip((struct in_addr *)&ipaddr);

			for (vars = pdu->variables; vars; vars = vars->next_variable) {
				if (netsnmp_oid_equals(vars->name, vars->name_length, oid_id, oid_id_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG "snmp [%s]: invalid id value received: %s\n", sp->peername, value);
					else {
						if (repeater != NULL) {
							repeater->id = value_num;
							dodbupdate = 1;
						}
						console_log("snmp [%s]: got id value %d\n", sp->peername, value_num);
					}
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_repeatertype, oid_repeatertype_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					length = snmp_hexstring_to_bytearray(value+12, value_utf16, sizeof(value_utf16)); // +12: cutting "Hex-STRING: " text returned by snprint_value().
					snmp_utf16_to_utf8(value_utf16, length, value_utf8, sizeof(value_utf8));
					if (repeater != NULL) {
						strncpy(repeater->type, value_utf8, sizeof(repeater->type));
						dodbupdate = 1;
					}
					console_log("snmp [%s]: got repeater type value %s\n", sp->peername, value_utf8);
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_fwversion, oid_fwversion_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					length = snmp_hexstring_to_bytearray(value+12, value_utf16, sizeof(value_utf16)); // +12: cutting "Hex-STRING: " text returned by snprint_value().
					snmp_utf16_to_utf8(value_utf16, length, value_utf8, sizeof(value_utf8));
					if (repeater != NULL) {
						strncpy(repeater->fwversion, value_utf8, sizeof(repeater->fwversion));
						dodbupdate = 1;
					}
					console_log("snmp [%s]: got repeater fw version value %s\n", sp->peername, value_utf8);
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_callsign, oid_callsign_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					length = snmp_hexstring_to_bytearray(value+12, value_utf16, sizeof(value_utf16)); // +12: cutting "Hex-STRING: " text returned by snprint_value().
					snmp_utf16_to_utf8(value_utf16, length, value_utf8, sizeof(value_utf8));
					if (repeater != NULL) {
						strncpy(repeater->callsign, value_utf8, sizeof(repeater->callsign));
						dodbupdate = 1;
					}
					console_log("snmp [%s]: got repeater callsign value %s\n", sp->peername, value_utf8);
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_dlfreq, oid_dlfreq_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG "snmp [%s]: invalid dl freq value received: %s\n", sp->peername, value);
					else {
						if (repeater != NULL) {
							repeater->dlfreq = value_num;
							dodbupdate = 1;
						}
						console_log("snmp [%s]: got dl freq value %d\n", sp->peername, value_num);
					}
				} else if (netsnmp_oid_equals(vars->name, vars->name_length, oid_ulfreq, oid_ulfreq_length) == 0) {
					snprint_value(value, sizeof(value), vars->name, vars->name_length, vars);
					errno = 0;
					value_num = strtol(value+9, &endptr, 10); // +9: cutting "INTEGER: " text returned by snprint_value().
					if (*endptr != 0 || errno != 0)
						console_log(LOGLEVEL_DEBUG "snmp [%s]: invalid dl freq value received: %s\n", sp->peername, value);
					else {
						if (repeater != NULL) {
							repeater->ulfreq = value_num;
							dodbupdate = 1;
						}
						console_log("snmp [%s]: got ul freq value %d\n", sp->peername, value_num);
					}
				}
			}

			if (dodbupdate)
				remotedb_update_repeater(repeater);

			snmp_repeaterinfo_received = 1;
		} else
			console_log(LOGLEVEL_DEBUG "snmp [%s]: repeater info read error\n", sp->peername);
    } else
    	console_log(LOGLEVEL_DEBUG "snmp [%s]: repeater info read timeout\n", sp->peername);

	return 1;
}
/**
 * Authorizes incoming notifications for further processing
 */
int
netsnmp_trapd_auth(netsnmp_pdu           *pdu,
                   netsnmp_transport     *transport,
                   netsnmp_trapd_handler *handler)
{
    int ret = 0;
    oid snmptrapoid[] = { 1,3,6,1,6,3,1,1,4,1,0 };
    size_t snmptrapoid_len = OID_LENGTH(snmptrapoid);
    int i;
    netsnmp_pdu *newpdu = pdu;
    netsnmp_variable_list *var;

    /* check to see if authorization was not disabled */
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_APP_NO_AUTHORIZATION)) {
        DEBUGMSGTL(("snmptrapd:auth",
                    "authorization turned off: not checking\n"));
        return NETSNMPTRAPD_HANDLER_OK;
    }

    /* bail early if called illegally */
    if (!pdu || !transport || !handler)
        return NETSNMPTRAPD_HANDLER_FINISH;
    
    /* convert to v2 so we can check it in a consistent manner */
#ifndef NETSNMP_DISABLE_SNMPV1
    if (pdu->version == SNMP_VERSION_1) {
        newpdu = convert_v1pdu_to_v2(pdu);
        if (!newpdu) {
            snmp_log(LOG_ERR, "Failed to duplicate incoming PDU.  Refusing to authorize.\n");
            return NETSNMPTRAPD_HANDLER_FINISH;
        }
    }
#endif

    if (!vacm_is_configured()) {
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        snmp_log(LOG_WARNING, "No access configuration - dropping trap.\n");
        return NETSNMPTRAPD_HANDLER_FINISH;
    }

    /* loop through each variable and find the snmpTrapOID.0 var
       indicating what the trap is we're staring at. */
    for (var = newpdu->variables; var != NULL; var = var->next_variable) {
        if (netsnmp_oid_equals(var->name, var->name_length,
                               snmptrapoid, snmptrapoid_len) == 0)
            break;
    }

    /* make sure we can continue: we found the snmpTrapOID.0 and its an oid */
    if (!var || var->type != ASN_OBJECT_ID) {
        snmp_log(LOG_ERR, "Can't determine trap identifier; refusing to authorize it\n");
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        return NETSNMPTRAPD_HANDLER_FINISH;
    }

#ifdef USING_MIBII_VACM_CONF_MODULE
    /* check the pdu against each typo of VACM access we may want to
       check up on later.  We cache the results for future lookup on
       each call to netsnmp_trapd_check_auth */
    for(i = 0; i < VACM_MAX_VIEWS; i++) {
        /* pass the PDU to the VACM routine for handling authorization */
        DEBUGMSGTL(("snmptrapd:auth", "Calling VACM for checking phase %d:%s\n",
                    i, se_find_label_in_slist(VACM_VIEW_ENUM_NAME, i)));
        if (vacm_check_view_contents(newpdu, var->val.objid,
                                     var->val_len/sizeof(oid), 0, i,
                                     VACM_CHECK_VIEW_CONTENTS_DNE_CONTEXT_OK)
            == VACM_SUCCESS) {
            DEBUGMSGTL(("snmptrapd:auth", "  result: authorized\n"));
            ret |= 1 << i;
        } else {
            DEBUGMSGTL(("snmptrapd:auth", "  result: not authorized\n"));
        }
    }
    DEBUGMSGTL(("snmptrapd:auth", "Final bitmask auth: %x\n", ret));
#endif

    if (ret) {
        /* we have policy to at least do "something".  Remember and continue. */
        lastlookup = ret;
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        return NETSNMPTRAPD_HANDLER_OK;
    }

    /* No policy was met, so we drop the PDU from further processing */
    DEBUGMSGTL(("snmptrapd:auth", "Dropping unauthorized message\n"));
#ifndef NETSNMP_DISABLE_SNMPV1
    if (newpdu != pdu)
        snmp_free_pdu(newpdu);
#endif
    return NETSNMPTRAPD_HANDLER_FINISH;
}