static int file_close(OSSL_STORE_LOADER_CTX *ctx) { if (ctx->type == is_dir) { OPENSSL_DIR_end(&ctx->_.dir.ctx); } else { BIO_free_all(ctx->_.file.file); } OSSL_STORE_LOADER_CTX_free(ctx); return 1; }
/* * Get next file from the directory path. * Returns BIO of the next file to read and updates dirctx. */ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) { const char *filename; while ((filename = OPENSSL_DIR_read(dirctx, path)) != NULL) { size_t namelen; namelen = strlen(filename); if ((namelen > 5 && strcasecmp(filename + namelen - 5, ".conf") == 0) || (namelen > 4 && strcasecmp(filename + namelen - 4, ".cnf") == 0)) { size_t newlen; char *newpath; BIO *bio; newlen = strlen(path) + namelen + 2; newpath = OPENSSL_zalloc(newlen); if (newpath == NULL) { CONFerr(CONF_F_GET_NEXT_FILE, ERR_R_MALLOC_FAILURE); break; } #ifdef OPENSSL_SYS_VMS /* * If the given path isn't clear VMS syntax, * we treat it as on Unix. */ { size_t pathlen = strlen(path); if (path[pathlen - 1] == ']' || path[pathlen - 1] == '>' || path[pathlen - 1] == ':') { /* Clear VMS directory syntax, just copy as is */ OPENSSL_strlcpy(newpath, path, newlen); } } #endif if (newpath[0] == '\0') { OPENSSL_strlcpy(newpath, path, newlen); OPENSSL_strlcat(newpath, "/", newlen); } OPENSSL_strlcat(newpath, filename, newlen); bio = BIO_new_file(newpath, "r"); OPENSSL_free(newpath); /* Errors when opening files are non-fatal. */ if (bio != NULL) return bio; } } OPENSSL_DIR_end(dirctx); *dirctx = NULL; return NULL; }
int main() { OPENSSL_DIR_CTX *ctx = NULL; const char *result; while ((result = OPENSSL_DIR_read(&ctx, CURRDIR)) != NULL) { printf("%s\n", result); } if (errno) { perror("test_dir"); exit(1); } if (!OPENSSL_DIR_end(&ctx)) { perror("test_dir"); exit(2); } exit(0); }
int main() { OPENSSL_DIR_CTX *ctx = NULL; const char *result; while((result = OPENSSL_DIR_read(&ctx, CURRDIR)) != NULL) { TINYCLR_SSL_PRINTF("%s\n", result); } if (errno) { TINYCLR_SSL_PERROR("test_dir"); TINYCLR_SSL_EXIT(1); } if (!OPENSSL_DIR_end(&ctx)) { TINYCLR_SSL_PERROR("test_dir"); TINYCLR_SSL_EXIT(2); } TINYCLR_SSL_EXIT(0); }
static int def_load_bio(CONF *conf, BIO *in, long *line) { /* The macro BUFSIZE conflicts with a system macro in VxWorks */ #define CONFBUFSIZE 512 int bufnum = 0, i, ii; BUF_MEM *buff = NULL; char *s, *p, *end; int again; long eline = 0; char btmp[DECIMAL_SIZE(eline) + 1]; CONF_VALUE *v = NULL, *tv; CONF_VALUE *sv = NULL; char *section = NULL, *buf; char *start, *psection, *pname; void *h = (void *)(conf->data); STACK_OF(BIO) *biosk = NULL; #ifndef OPENSSL_NO_POSIX_IO char *dirpath = NULL; OPENSSL_DIR_CTX *dirctx = NULL; #endif if ((buff = BUF_MEM_new()) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); goto err; } section = OPENSSL_strdup("default"); if (section == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (_CONF_new_data(conf) == 0) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } sv = _CONF_new_section(conf, section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } bufnum = 0; again = 0; for (;;) { if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); goto err; } p = &(buff->data[bufnum]); *p = '\0'; read_retry: BIO_gets(in, p, CONFBUFSIZE - 1); p[CONFBUFSIZE - 1] = '\0'; ii = i = strlen(p); if (i == 0 && !again) { /* the currently processed BIO is at EOF */ BIO *parent; #ifndef OPENSSL_NO_POSIX_IO /* continue processing with the next file from directory */ if (dirctx != NULL) { BIO *next; if ((next = get_next_file(dirpath, &dirctx)) != NULL) { BIO_vfree(in); in = next; goto read_retry; } else { OPENSSL_free(dirpath); dirpath = NULL; } } #endif /* no more files in directory, continue with processing parent */ if ((parent = sk_BIO_pop(biosk)) == NULL) { /* everything processed get out of the loop */ break; } else { BIO_vfree(in); in = parent; goto read_retry; } } again = 0; while (i > 0) { if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) break; else i--; } /* * we removed some trailing stuff so there is a new line on the end. */ if (ii && i == ii) again = 1; /* long line */ else { p[i] = '\0'; eline++; /* another input line */ } /* we now have a line with trailing \r\n removed */ /* i is the number of bytes */ bufnum += i; v = NULL; /* check for line continuation */ if (bufnum >= 1) { /* * If we have bytes and the last char '\\' and second last char * is not '\\' */ p = &(buff->data[bufnum - 1]); if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { bufnum--; again = 1; } } if (again) continue; bufnum = 0; buf = buff->data; clear_comments(conf, buf); s = eat_ws(conf, buf); if (IS_EOF(conf, *s)) continue; /* blank line */ if (*s == '[') { char *ss; s++; start = eat_ws(conf, s); ss = start; again: end = eat_alpha_numeric(conf, ss); p = eat_ws(conf, end); if (*p != ']') { if (*p != '\0' && ss != p) { ss = p; goto again; } CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); goto err; } *end = '\0'; if (!str_copy(conf, NULL, §ion, start)) goto err; if ((sv = _CONF_get_section(conf, section)) == NULL) sv = _CONF_new_section(conf, section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } continue; } else { pname = s; end = eat_alpha_numeric(conf, s); if ((end[0] == ':') && (end[1] == ':')) { *end = '\0'; end += 2; psection = pname; pname = end; end = eat_alpha_numeric(conf, end); } else { psection = section; } p = eat_ws(conf, end); if (strncmp(pname, ".include", 8) == 0 && (p != pname + 8 || *p == '=')) { char *include = NULL; BIO *next; if (*p == '=') { p++; p = eat_ws(conf, p); } trim_ws(conf, p); if (!str_copy(conf, psection, &include, p)) goto err; /* get the BIO of the included file */ #ifndef OPENSSL_NO_POSIX_IO next = process_include(include, &dirctx, &dirpath); if (include != dirpath) { /* dirpath will contain include in case of a directory */ OPENSSL_free(include); } #else next = BIO_new_file(include, "r"); OPENSSL_free(include); #endif if (next != NULL) { /* push the currently processing BIO onto stack */ if (biosk == NULL) { if ((biosk = sk_BIO_new_null()) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } } if (!sk_BIO_push(biosk, in)) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } /* continue with reading from the included BIO */ in = next; } continue; } else if (*p != '=') { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); goto err; } *end = '\0'; p++; start = eat_ws(conf, p); trim_ws(conf, start); if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } v->name = OPENSSL_strdup(pname); v->value = NULL; if (v->name == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (!str_copy(conf, psection, &(v->value), start)) goto err; if (strcmp(psection, section) != 0) { if ((tv = _CONF_get_section(conf, psection)) == NULL) tv = _CONF_new_section(conf, psection); if (tv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } } else tv = sv; if (_CONF_add_string(conf, tv, v) == 0) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } v = NULL; } } BUF_MEM_free(buff); OPENSSL_free(section); /* * No need to pop, since we only get here if the stack is empty. * If this causes a BIO leak, THE ISSUE IS SOMEWHERE ELSE! */ sk_BIO_free(biosk); return 1; err: BUF_MEM_free(buff); OPENSSL_free(section); /* * Since |in| is the first element of the stack and should NOT be freed * here, we cannot use sk_BIO_pop_free(). Instead, we pop and free one * BIO at a time, making sure that the last one popped isn't. */ while (sk_BIO_num(biosk) > 0) { BIO *popped = sk_BIO_pop(biosk); BIO_vfree(in); in = popped; } sk_BIO_free(biosk); #ifndef OPENSSL_NO_POSIX_IO OPENSSL_free(dirpath); if (dirctx != NULL) OPENSSL_DIR_end(&dirctx); #endif if (line != NULL) *line = eline; BIO_snprintf(btmp, sizeof(btmp), "%ld", eline); ERR_add_error_data(2, "line ", btmp); if (h != conf->data) { CONF_free(conf->data); conf->data = NULL; } if (v != NULL) { OPENSSL_free(v->name); OPENSSL_free(v->value); OPENSSL_free(v); } return 0; }