/* 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); }
/* * 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; }