X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=crypto%2Fconf%2Fconf_def.c;h=594f7c5e5a32d63d27c92eb09540b08373af48a7;hb=9d5560331d86c6463e965321f774e4eed582ce0b;hp=d689502e317fa8d24f898e2e52e8f5a290fa8a5e;hpb=b524b808a1d1ba204dbdcbb42de4e3bddb3472ac;p=openssl.git diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c index d689502e31..594f7c5e5a 100644 --- a/crypto/conf/conf_def.c +++ b/crypto/conf/conf_def.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html @@ -27,12 +27,17 @@ # endif #endif +#ifndef S_ISDIR +# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) +#endif + /* * The maximum length we can grow a value to after variable expansion. 64k * should be more than enough for all reasonable uses. */ #define MAX_CONF_VALUE_LENGTH 65536 +static int is_keytype(const CONF *conf, char c, unsigned short type); static char *eat_ws(CONF *conf, char *p); static void trim_ws(CONF *conf, char *start); static char *eat_alpha_numeric(CONF *conf, char *p); @@ -84,12 +89,12 @@ static CONF_METHOD WIN32_method = { def_load }; -CONF_METHOD *NCONF_default() +CONF_METHOD *NCONF_default(void) { return &default_method; } -CONF_METHOD *NCONF_WIN32() +CONF_METHOD *NCONF_WIN32(void) { return &WIN32_method; } @@ -343,10 +348,15 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) psection = section; } p = eat_ws(conf, end); - if (strncmp(pname, ".include", 8) == 0 && p != pname + 8) { + 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; @@ -419,12 +429,26 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) } BUF_MEM_free(buff); OPENSSL_free(section); - sk_BIO_pop_free(biosk, BIO_vfree); + /* + * 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); - sk_BIO_pop_free(biosk, BIO_vfree); + /* + * 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) @@ -558,7 +582,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) s++; cp = section; e = np = s; - while (IS_ALPHA_NUMERIC(conf, *e)) + while (IS_ALNUM(conf, *e)) e++; if ((e[0] == ':') && (e[1] == ':')) { cp = np; @@ -567,7 +591,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) *rrp = '\0'; e += 2; np = e; - while (IS_ALPHA_NUMERIC(conf, *e)) + while (IS_ALNUM(conf, *e)) e++; } r = *e; @@ -655,7 +679,7 @@ static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx, return NULL; } - if ((st.st_mode & S_IFDIR) == S_IFDIR) { + if (S_ISDIR(st.st_mode)) { if (*dirctx != NULL) { CONFerr(CONF_F_PROCESS_INCLUDE, CONF_R_RECURSIVE_DIRECTORY_INCLUDE); @@ -685,6 +709,7 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) namelen = strlen(filename); + if ((namelen > 5 && strcasecmp(filename + namelen - 5, ".conf") == 0) || (namelen > 4 && strcasecmp(filename + namelen - 4, ".cnf") == 0)) { size_t newlen; @@ -697,10 +722,25 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) CONFerr(CONF_F_GET_NEXT_FILE, ERR_R_MALLOC_FAILURE); break; } - OPENSSL_strlcat(newpath, path, newlen); -#ifndef OPENSSL_SYS_VMS - OPENSSL_strlcat(newpath, "/", newlen); +#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"); @@ -716,6 +756,30 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) } #endif +static int is_keytype(const CONF *conf, char c, unsigned short type) +{ + const unsigned short * keytypes = (const unsigned short *) conf->meth_data; + unsigned char key = (unsigned char)c; + +#ifdef CHARSET_EBCDIC +# if CHAR_BIT > 8 + if (key > 255) { + /* key is out of range for os_toascii table */ + return 0; + } +# endif + /* convert key from ebcdic to ascii */ + key = os_toascii[key]; +#endif + + if (key > 127) { + /* key is not a seven bit ascii character */ + return 0; + } + + return (keytypes[key] & type) ? 1 : 0; +} + static char *eat_ws(CONF *conf, char *p) { while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) @@ -743,7 +807,7 @@ static char *eat_alpha_numeric(CONF *conf, char *p) p = scan_esc(conf, p); continue; } - if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) + if (!IS_ALNUM_PUNCT(conf, *p)) return p; p++; }