Update source files for deprecation at 3.0
[openssl.git] / crypto / conf / conf_def.c
index 676540cc6c35b8e6b77bd1570fd95ec39827850b..a8581d7320ea72341f774545e8cc5d4b59445abc 100644 (file)
@@ -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
@@ -54,7 +54,9 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx);
 
 static CONF *def_create(CONF_METHOD *meth);
 static int def_init_default(CONF *conf);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
 static int def_init_WIN32(CONF *conf);
+#endif
 static int def_destroy(CONF *conf);
 static int def_destroy_data(CONF *conf);
 static int def_load(CONF *conf, const char *name, long *eline);
@@ -76,6 +78,12 @@ static CONF_METHOD default_method = {
     def_load
 };
 
+CONF_METHOD *NCONF_default(void)
+{
+    return &default_method;
+}
+
+#ifndef OPENSSL_NO_DEPRECATED_3_0
 static CONF_METHOD WIN32_method = {
     "WIN32",
     def_create,
@@ -89,15 +97,11 @@ static CONF_METHOD WIN32_method = {
     def_load
 };
 
-CONF_METHOD *NCONF_default(void)
-{
-    return &default_method;
-}
-
 CONF_METHOD *NCONF_WIN32(void)
 {
     return &WIN32_method;
 }
+#endif
 
 static CONF *def_create(CONF_METHOD *meth)
 {
@@ -124,6 +128,7 @@ static int def_init_default(CONF *conf)
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_0
 static int def_init_WIN32(CONF *conf)
 {
     if (conf == NULL)
@@ -135,6 +140,7 @@ static int def_init_WIN32(CONF *conf)
 
     return 1;
 }
+#endif
 
 static int def_destroy(CONF *conf)
 {
@@ -348,24 +354,48 @@ 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;
+                const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE");
+                char *include_path = NULL;
 
+                if (*p == '=') {
+                    p++;
+                    p = eat_ws(conf, p);
+                }
                 trim_ws(conf, p);
                 if (!str_copy(conf, psection, &include, p))
                     goto err;
+
+                if (include_dir != NULL) {
+                    size_t newlen = strlen(include_dir) + strlen(include) + 2;
+
+                    include_path = OPENSSL_malloc(newlen);
+                    OPENSSL_strlcpy(include_path, include_dir, newlen);
+                    OPENSSL_strlcat(include_path, "/", newlen);
+                    OPENSSL_strlcat(include_path, include, newlen);
+                } else {
+                    include_path = include;
+                }
+
                 /* get the BIO of the included file */
 #ifndef OPENSSL_NO_POSIX_IO
-                next = process_include(include, &dirctx, &dirpath);
-                if (include != dirpath) {
+                next = process_include(include_path, &dirctx, &dirpath);
+                if (include_path != dirpath) {
                     /* dirpath will contain include in case of a directory */
                     OPENSSL_free(include);
+                    if (include_path != include)
+                        OPENSSL_free(include_path);
                 }
 #else
-                next = BIO_new_file(include, "r");
+                next = BIO_new_file(include_path, "r");
                 OPENSSL_free(include);
+                if (include_path != include)
+                    OPENSSL_free(include_path);
 #endif
+
                 if (next != NULL) {
                     /* push the currently processing BIO onto stack */
                     if (biosk == NULL) {
@@ -424,12 +454,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)
@@ -650,12 +694,13 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from)
 static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx,
                             char **dirpath)
 {
-    struct stat st = { 0 };
+    struct stat st;
     BIO *next;
 
     if (stat(include, &st) < 0) {
-        SYSerr(SYS_F_STAT, errno);
-        ERR_add_error_data(1, include);
+        ERR_raise_data(ERR_LIB_SYS, errno,
+                       "calling stat(%s)",
+                       include);
         /* missing include file is not fatal error */
         return NULL;
     }