示例#1
0
/* this is called after the connection on the server side by us to
   check other aspects about the connection and obtain the
   securityName from the remote certificate. */
int netsnmp_tlsbase_extract_security_name (SSL * ssl, _netsnmpTLSBaseData * tlsdata)
{
    netsnmp_container *chain_maps;

    netsnmp_cert_map *cert_map, *peer_cert;

    netsnmp_iterator *itr;

    int rc;

    netsnmp_assert_or_return (ssl != NULL, SNMPERR_GENERR);
    netsnmp_assert_or_return (tlsdata != NULL, SNMPERR_GENERR);

    if (NULL == (chain_maps = netsnmp_openssl_get_cert_chain (ssl)))
        return SNMPERR_GENERR;
    /*
     * map fingerprints to mapping entries
     */
    rc = netsnmp_cert_get_secname_maps (chain_maps);
    if ((-1 == rc) || (CONTAINER_SIZE (chain_maps) == 0))
    {
        netsnmp_cert_map_container_free (chain_maps);
        return SNMPERR_GENERR;
    }

    /*
     * change container to sorted (by clearing unsorted option), then
     * iterate over it until we find a map that returns a secname.
     */
    CONTAINER_SET_OPTIONS (chain_maps, 0, rc);
    itr = CONTAINER_ITERATOR (chain_maps);
    if (NULL == itr)
    {
        snmp_log (LOG_ERR, "could not get iterator for secname fingerprints\n");
        netsnmp_cert_map_container_free (chain_maps);
        return SNMPERR_GENERR;
    }
    peer_cert = cert_map = ITERATOR_FIRST (itr);
    for (; !tlsdata->securityName && cert_map; cert_map = ITERATOR_NEXT (itr))
        tlsdata->securityName = netsnmp_openssl_extract_secname (cert_map, peer_cert);
    ITERATOR_RELEASE (itr);

    netsnmp_cert_map_container_free (chain_maps);

    return (tlsdata->securityName ? SNMPERR_SUCCESS : SNMPERR_GENERR);
}
示例#2
0
/*
 * read file names in a directory, with an optional filter
 */
netsnmp_container *
netsnmp_directory_container_read_some(netsnmp_container *user_container,
                                      const char *dirname,
                                      netsnmp_directory_filter *filter,
                                      void *filter_ctx, u_int flags)
{
    DIR               *dir;
    netsnmp_container *container = user_container;
    struct dirent     *file;
    char               path[SNMP_MAXPATH];
    size_t             dirname_len;
    int                rc;
    struct stat        statbuf;
    netsnmp_file       ns_file_tmp;

    if ((flags & NETSNMP_DIR_RELATIVE_PATH) && (flags & NETSNMP_DIR_RECURSE)) {
        DEBUGMSGTL(("directory:container",
                    "no support for relative path with recursion\n"));
        return NULL;
    }

    DEBUGMSGTL(("directory:container", "reading %s\n", dirname));

    /*
     * create the container, if needed
     */
    if (NULL == container) {
        if (flags & NETSNMP_DIR_NSFILE) {
            container = netsnmp_container_find("nsfile_directory_container:"
                                               "binary_array");
            if (container) {
                container->compare = (netsnmp_container_compare*)
                    netsnmp_file_compare_name;
                container->free_item = (netsnmp_container_obj_func *)
                    netsnmp_file_container_free;
            }
        }
        else
            container = netsnmp_container_find("directory_container:cstring");
        if (NULL == container)
            return NULL;
        container->container_name = strdup(dirname);
        /** default to unsorted */
        if (! (flags & NETSNMP_DIR_SORTED))
            CONTAINER_SET_OPTIONS(container, CONTAINER_KEY_UNSORTED, rc);
    }

    dir = opendir(dirname);
    if (NULL == dir) {
        DEBUGMSGTL(("directory:container", "  not a dir\n"));
        if (container != user_container)
            netsnmp_directory_container_free(container);
        return NULL;
    }

    /** copy dirname into path */
    if (flags & NETSNMP_DIR_RELATIVE_PATH)
        dirname_len = 0;
    else {
        dirname_len = strlen(dirname);
        strncpy(path, dirname, sizeof(path));
        if ((dirname_len + 2) > sizeof(path)) {
            /** not enough room for files */
            closedir(dir);
            if (container != user_container)
                netsnmp_directory_container_free(container);
            return NULL;
        }
        path[dirname_len] = '/';
        path[++dirname_len] = 0;
    }

    /** iterate over dir */
    while ((file = readdir(dir))) {

        if ((file->d_name == NULL) || (file->d_name[0] == 0))
            continue;

        /** skip '.' and '..' */
        if ((file->d_name[0] == '.') &&
            ((file->d_name[1] == 0) ||
             ((file->d_name[1] == '.') && ((file->d_name[2] == 0)))))
            continue;

        strncpy(&path[dirname_len], file->d_name, sizeof(path) - dirname_len);
        if (NULL != filter) {
            if (flags & NETSNMP_DIR_NSFILE_STATS) {
                /** use local vars for now */
                if (stat(path, &statbuf) != 0) {
                    snmp_log(LOG_ERR, "could not stat %s\n", file->d_name);
                    break;
                }
                ns_file_tmp.stats = &statbuf;
                ns_file_tmp.name = path;
                rc = (*filter)(&ns_file_tmp, filter_ctx);
            }
            else
                rc = (*filter)(path, filter_ctx);
            if (0 == rc) {
                DEBUGMSGTL(("directory:container:filtered", "%s\n",
                            file->d_name));
                continue;
            }
        }

        DEBUGMSGTL(("directory:container:found", "%s\n", path));
        if ((flags & NETSNMP_DIR_RECURSE) 
#if defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DT_DIR)
            && (file->d_type == DT_DIR)
#elif defined(S_ISDIR)
            && (stat(file->d_name, &statbuf) != 0) && (S_ISDIR(statbuf.st_mode))
#endif
            ) {
            /** xxx add the dir as well? not for now.. maybe another flag? */
            netsnmp_directory_container_read(container, path, flags);
        }
        else if (flags & NETSNMP_DIR_NSFILE) {
            if (_insert_nsfile( container, file->d_name,
                                filter ? &statbuf : NULL, flags ) < 0)
                break;
        }
        else {
            char *dup = strdup(path);
            if (NULL == dup) {
                snmp_log(LOG_ERR,
                         "strdup failed while building directory container\n");
                break;
            }
            rc = CONTAINER_INSERT(container, dup);
            if (-1 == rc ) {
                DEBUGMSGTL(("directory:container", "  err adding %s\n", path));
                free(dup);
            }
        }
    } /* while */

    closedir(dir);

    rc = CONTAINER_SIZE(container);
    DEBUGMSGTL(("directory:container", "  container now has %d items\n", rc));
    if ((0 == rc) && !(flags & NETSNMP_DIR_EMPTY_OK)) {
        netsnmp_directory_container_free(container);
        return NULL;
    }
    
    return container;
}