Beispiel #1
0
int vacm_in_view (struct packet_info *pi,
                  oid *name,
                  int namelen)
{
    struct vacm_securityEntry *sp = securityFirst;
    struct vacm_accessEntry *ap;
    struct vacm_groupEntry *gp;
    struct vacm_viewEntry *vp;
    char *vn;
    char *sn;

    if (pi->sec_model == SNMP_SEC_MODEL_SNMPv1 || pi->sec_model == SNMP_SEC_MODEL_SNMPv2c) {
        DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: ver=%d, source=%.8x, community=%s\n", pi->version, pi->source.sin_addr.s_addr, pi->community));

        /* allow running without snmpd.conf */
        if (sp == NULL) {
            DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: accepted with no com2sec entries\n"));
            switch (pi->pdutype) {
            case SNMP_MSG_GET:
            case SNMP_MSG_GETNEXT:
            case SNMP_MSG_GETBULK:
                return 1;
            default:
                return 0;
            }
        }
        while (sp) {
            if ((pi->source.sin_addr.s_addr & sp->sourceMask.sin_addr.s_addr)
                    == sp->sourceIp.sin_addr.s_addr
                    && strcmp(sp->community, (char *)pi->community) == 0)
                break;
            sp = sp->next;
        }
        if (sp == NULL) return 0;
        sn = sp->securityName;
    }
    else {
        sn = NULL;
    }

    if (sn == NULL) return 0;
    DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: securityName == %s\n", sn));
    gp = vacm_getGroupEntry(pi->sec_model, sn);
    if (gp == NULL) return 0;
    DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: groupName == %s\n", gp->groupName));
    ap = vacm_getAccessEntry(gp->groupName, "", pi->sec_model, pi->sec_level);
    if (ap == NULL) return 0;
    switch (pi->pdutype) {
    case SNMP_MSG_GET:
    case SNMP_MSG_GETNEXT:
    case SNMP_MSG_GETBULK:
        vn = ap->readView;
        break;
    case SNMP_MSG_SET:
        vn = ap->writeView;
        break;
    case SNMP_MSG_TRAP:
    case SNMP_MSG_TRAP2:
    case SNMP_MSG_INFORM:
        vn = ap->notifyView;
        break;
    default:
        fprintf(stderr,"bad msg type in vacm_in_view: %d\n", pi->pdutype);
        vn = ap->readView;
    }
    DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: viewName == %s\n", vn));
    vp = vacm_getViewEntry (vn, name, namelen);
    if (vp == NULL) return 0;
    DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: viewType == %d\n", vp->viewType));
    if (vp->viewType == SNMP_VIEW_EXCLUDED) return 0;
    return 1;
}
Beispiel #2
0
u_char *var_vacm_sec2group(struct variable *vp,
                           oid *name,
                           int *length,
                           int exact,
                           int *var_len,
                           WriteMethod **write_method)
{
    struct vacm_groupEntry *gp;
    oid *groupSubtree;
    int groupSubtreeLen;
    int secmodel;
    char secname[32], *cp;

    write_method = NULL;
    if (memcmp(name, vp->name, sizeof(oid)*vp->namelen) != 0) {
        memcpy(name, vp->name, sizeof(oid)*vp->namelen);
        *length = vp->namelen;
    }
    if (exact) {
        if (*length < 13) return NULL;

        secmodel = name[11];
        groupSubtree = name+13;
        groupSubtreeLen = *length - 13;
        cp = secname;
        while (groupSubtreeLen-- > 0) {
            *cp++ = *groupSubtree++;
        }
        *cp = 0;

        gp = vacm_getGroupEntry(secmodel, secname);
    }
    else {
        secmodel = *length > 11 ? name[11] : 0;
        groupSubtree = name+12;
        groupSubtreeLen = *length - 12;
        cp = secname;
        while (groupSubtreeLen-- > 0) {
            *cp++ = *groupSubtree++;
        }
        *cp = 0;
        vacm_scanGroupInit();
        while ((gp = vacm_scanGroupNext()) != NULL) {
            if (gp->securityModel > secmodel ||
                    (gp->securityModel == secmodel && strcmp(gp->securityName, secname) > 0))
                break;
        }
        if (gp) {
            name[11] = gp->securityModel;
            *length = 12;
            cp = gp->securityName;
            while (*cp) {
                name[(*length)++] = *cp++;
            }
        }
    }

    if (!gp) return NULL;

    *var_len =sizeof(long_return);
    switch (vp->magic) {
    case SECURITYMODEL:
        long_return = gp->securityModel;
        return (u_char *)&long_return;
    case SECURITYNAME:
        *var_len = gp->securityName[0];
        return (u_char *)&gp->securityName[1];
    case SECURITYGROUP:
        *var_len = strlen(gp->groupName);
        return (u_char *)gp->groupName;
    case SECURITYSTORAGE:
        long_return = gp->storageType;
        return (u_char *)&long_return;
    case SECURITYSTATUS:
        long_return = gp->status;
        return (u_char *)&long_return;
    }
    return NULL;
}
Beispiel #3
0
int
vacm_check_view_contents(netsnmp_pdu *pdu, oid * name, size_t namelen,
                         int check_subtree, int viewtype, int flags)
{
    struct vacm_accessEntry *ap;
    struct vacm_groupEntry *gp;
    struct vacm_viewEntry *vp;
    char            vacm_default_context[1] = "";
    const char     *contextName = vacm_default_context;
    const char     *sn = NULL;
    char           *vn;
    const char     *pdu_community;

    /*
     * len defined by the vacmContextName object 
     */
#define CONTEXTNAMEINDEXLEN 32
    char            contextNameIndex[CONTEXTNAMEINDEXLEN + 1];

#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
#if defined(NETSNMP_DISABLE_SNMPV1)
    if (pdu->version == SNMP_VERSION_2c)
#else
#if defined(NETSNMP_DISABLE_SNMPV2C)
    if (pdu->version == SNMP_VERSION_1)
#else
    if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c)
#endif
#endif
    {
        pdu_community = (const char *) pdu->community;
        if (!pdu_community)
            pdu_community = "";
        if (snmp_get_do_debugging()) {
            char           *buf;
            if (pdu->community) {
                buf = (char *) malloc(1 + pdu->community_len);
                memcpy(buf, pdu->community, pdu->community_len);
                buf[pdu->community_len] = '\0';
            } else {
                DEBUGMSGTL(("mibII/vacm_vars", "NULL community"));
                buf = strdup("NULL");
            }

            DEBUGMSGTL(("mibII/vacm_vars",
                        "vacm_in_view: ver=%ld, community=%s\n",
                        pdu->version, buf));
            free(buf);
        }

        /*
         * Okay, if this PDU was received from a UDP or a TCP transport then
         * ask the transport abstraction layer to map its source address and
         * community string to a security name for us.  
         */

        if (0) {
#ifdef NETSNMP_TRANSPORT_UDP_DOMAIN
        } else if (pdu->tDomain == netsnmpUDPDomain
#ifdef NETSNMP_TRANSPORT_TCP_DOMAIN
            || pdu->tDomain == netsnmp_snmpTCPDomain
#endif
            ) {
            if (!netsnmp_udp_getSecName(pdu->transport_data,
                                        pdu->transport_data_length,
                                        pdu_community,
                                        pdu->community_len, &sn,
                                        &contextName)) {
                /*
                 * There are no com2sec entries.  
                 */
                sn = NULL;
            }
            /* force the community -> context name mapping here */
            SNMP_FREE(pdu->contextName);
            pdu->contextName = strdup(contextName);
            pdu->contextNameLen = strlen(contextName);
#endif
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
        } else if (pdu->tDomain == netsnmp_UDPIPv6Domain
#ifdef NETSNMP_TRANSPORT_TCPIPV6_DOMAIN
                   || pdu->tDomain == netsnmp_TCPIPv6Domain
#endif
            ) {
            if (!netsnmp_udp6_getSecName(pdu->transport_data,
                                         pdu->transport_data_length,
                                         pdu_community,
                                         pdu->community_len, &sn,
                                         &contextName)) {
                /*
                 * There are no com2sec entries.  
                 */
                sn = NULL;
            }
            /* force the community -> context name mapping here */
            SNMP_FREE(pdu->contextName);
            pdu->contextName = strdup(contextName);
            pdu->contextNameLen = strlen(contextName);
#endif
#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
        } else if (pdu->tDomain == netsnmp_UnixDomain){
            if (!netsnmp_unix_getSecName(pdu->transport_data,
                                         pdu->transport_data_length,
                                         pdu_community,
                                         pdu->community_len, &sn,
                                         &contextName)) {
					sn = NULL;
            }
            /* force the community -> context name mapping here */
            SNMP_FREE(pdu->contextName);
            pdu->contextName = strdup(contextName);
            pdu->contextNameLen = strlen(contextName);
#endif	
        } else {
            /*
             * Map other <community, transport-address> pairs to security names
             * here.  For now just let non-IPv4 transport always succeed.
             * 
             * WHAAAATTTT.  No, we don't let non-IPv4 transports
             * succeed!  You must fix this to make it usable, sorry.
             * From a security standpoint this is insane. -- Wes
             */
            /** @todo alternate com2sec mappings for non v4 transports.
                Should be implemented via registration */
            sn = NULL;
        }

    } else
#endif /* support for community based SNMP */
      if (find_sec_mod(pdu->securityModel)) {
        /*
         * any legal defined v3 security model 
         */
        DEBUGMSG(("mibII/vacm_vars",
                  "vacm_in_view: ver=%ld, model=%d, secName=%s\n",
                  pdu->version, pdu->securityModel, pdu->securityName));
        sn = pdu->securityName;
        contextName = pdu->contextName;
    } else {
        sn = NULL;
    }

    if (sn == NULL) {
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
        snmp_increment_statistic(STAT_SNMPINBADCOMMUNITYNAMES);
#endif
        DEBUGMSGTL(("mibII/vacm_vars",
                    "vacm_in_view: No security name found\n"));
        return VACM_NOSECNAME;
    }

    if (pdu->contextNameLen > CONTEXTNAMEINDEXLEN) {
        DEBUGMSGTL(("mibII/vacm_vars",
                    "vacm_in_view: bad ctxt length %d\n",
                    (int)pdu->contextNameLen));
        return VACM_NOSUCHCONTEXT;
    }
    /*
     * NULL termination of the pdu field is ugly here.  Do in PDU parsing? 
     */
    if (pdu->contextName)
        memcpy(contextNameIndex, pdu->contextName, pdu->contextNameLen);
    else
        contextNameIndex[0] = '\0';

    contextNameIndex[pdu->contextNameLen] = '\0';
    if (!(flags & VACM_CHECK_VIEW_CONTENTS_DNE_CONTEXT_OK) &&
        !netsnmp_subtree_find_first(contextNameIndex)) {
        /*
         * rfc 3415 section 3.2, step 1
         * no such context here; return no such context error 
         */
        DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: no such ctxt \"%s\"\n",
                    contextNameIndex));
        return VACM_NOSUCHCONTEXT;
    }

    DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: sn=%s", sn));

    gp = vacm_getGroupEntry(pdu->securityModel, sn);
    if (gp == NULL) {
        DEBUGMSG(("mibII/vacm_vars", "\n"));
        return VACM_NOGROUP;
    }
    DEBUGMSG(("mibII/vacm_vars", ", gn=%s", gp->groupName));

    ap = vacm_getAccessEntry(gp->groupName, contextNameIndex,
                             pdu->securityModel, pdu->securityLevel);
    if (ap == NULL) {
        DEBUGMSG(("mibII/vacm_vars", "\n"));
        return VACM_NOACCESS;
    }

    if (name == NULL) { /* only check the setup of the vacm for the request */
        DEBUGMSG(("mibII/vacm_vars", ", Done checking setup\n"));
        return VACM_SUCCESS;
    }

    if (viewtype < 0 || viewtype >= VACM_MAX_VIEWS) {
        DEBUGMSG(("mibII/vacm_vars", " illegal view type\n"));
        return VACM_NOACCESS;
    }
    vn = ap->views[viewtype];
    DEBUGMSG(("mibII/vacm_vars", ", vn=%s", vn));

    if (check_subtree) {
        DEBUGMSG(("mibII/vacm_vars", "\n"));
        return vacm_checkSubtree(vn, name, namelen);
    }

    vp = vacm_getViewEntry(vn, name, namelen, VACM_MODE_FIND);

    if (vp == NULL) {
        DEBUGMSG(("mibII/vacm_vars", "\n"));
        return VACM_NOVIEW;
    }
    DEBUGMSG(("mibII/vacm_vars", ", vt=%d\n", vp->viewType));

    if (vp->viewType == SNMP_VIEW_EXCLUDED) {
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
#if defined(NETSNMP_DISABLE_SNMPV1)
        if (pdu->version == SNMP_VERSION_2c)
#else
#if defined(NETSNMP_DISABLE_SNMPV2C)
        if (pdu->version == SNMP_VERSION_1)
#else
        if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c)
#endif
#endif
        {
            snmp_increment_statistic(STAT_SNMPINBADCOMMUNITYUSES);
        }
#endif
        return VACM_NOTINVIEW;
    }

    return VACM_SUCCESS;

}                               /* end vacm_in_view() */