Add .includedir pragma

Also add a negative test, and fix typo's.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15090)
This commit is contained in:
Rich Salz 2021-04-30 12:18:00 -04:00 committed by Tomas Mraz
parent 3fb985fd04
commit f7050588bc
7 changed files with 45 additions and 15 deletions

View File

@ -23,8 +23,8 @@ OpenSSL 3.0
### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
* Add ".pragma abspath:true" to prevent relative file inclusion in
config files.
* Add "abspath" and "includedir" pragma's to config files, to prevent,
or modify relative pathname inclusion.
* Rich Salz *

View File

@ -146,6 +146,7 @@ void _CONF_free_data(CONF *conf)
* with
*/
OPENSSL_free(conf->includedir);
lh_CONF_VALUE_doall(conf->data, value_free_stack_doall);
lh_CONF_VALUE_free(conf->data);
}

View File

@ -192,11 +192,11 @@ static int def_load(CONF *conf, const char *name, long *line)
/* Parse a boolean value and fill in *flag. Return 0 on error. */
static int parsebool(const char *pval, int *flag)
{
if (strcmp(pval, "on") == 0
|| strcmp(pval, "true") == 0) {
if (strcasecmp(pval, "on") == 0
|| strcasecmp(pval, "true") == 0) {
*flag = 1;
} else if (strcmp(pval, "off") == 0
|| strcmp(pval, "false") == 0) {
} else if (strcasecmp(pval, "off") == 0
|| strcasecmp(pval, "false") == 0) {
*flag = 0;
} else {
ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA);
@ -414,6 +414,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
* Known pragmas:
*
* dollarid takes "on", "true or "off", "false"
* abspath takes "on", "true or "off", "false"
* includedir directory prefix
*/
if (strcmp(p, "dollarid") == 0) {
if (!parsebool(pval, &conf->flag_dollarid))
@ -421,7 +423,13 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
} else if (strcmp(p, "abspath") == 0) {
if (!parsebool(pval, &conf->flag_abspath))
goto err;
} else if (strcmp(p, "includedir") == 0) {
if ((conf->includedir = OPENSSL_strdup(pval)) == NULL) {
ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE);
goto err;
}
}
/*
* We *ignore* any unknown pragma.
*/
@ -433,6 +441,9 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE");
char *include_path = NULL;
if (include_dir == NULL)
include_dir = conf->includedir;
if (*p == '=') {
p++;
p = eat_ws(conf, p);
@ -441,11 +452,6 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
if (!str_copy(conf, psection, &include, p))
goto err;
if (conf->flag_abspath && !ossl_is_absolute_path(include)) {
ERR_raise(ERR_LIB_CONF, CONF_R_RELATIVE_PATH);
goto err;
}
if (include_dir != NULL && !ossl_is_absolute_path(include)) {
size_t newlen = strlen(include_dir) + strlen(include) + 2;
@ -465,6 +471,12 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
include_path = include;
}
if (conf->flag_abspath
&& !ossl_is_absolute_path(include_path)) {
ERR_raise(ERR_LIB_CONF, CONF_R_RELATIVE_PATH);
goto err;
}
/* get the BIO of the included file */
#ifndef OPENSSL_NO_POSIX_IO
next = process_include(include_path, &dirctx, &dirpath);
@ -544,6 +556,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
*/
sk_BIO_free(biosk);
return 1;
err:
BUF_MEM_free(buff);
OPENSSL_free(section);

View File

@ -48,7 +48,7 @@ while scanning a directory, and that file has an B<.include> directive
that specifies a directory, that is also ignored.
As a general rule, the B<pathname> should be an absolute path; this can
be enforced with the B<relpath> pragma, described below.
be enforced with the B<abspath> and B<includedir> pragmas, described below.
The environment variable B<OPENSSL_CONF_INCLUDE>, if it exists,
is prepended to all relative pathnames.
If the pathname is still relative, it is interpreted based on the
@ -57,7 +57,7 @@ current working directory.
To require all file inclusions to name absolute paths, use the following
directive:
.progma [=] abspath:value
.pragma [=] abspath:value
The default behavior, where the B<value> is B<false> or B<off>, is to allow
relative paths. To require all B<.include> pathnames to be absolute paths,
@ -76,6 +76,13 @@ C<foo> followed by the expansion of the variable C<bar>. If B<value> is
B<true> or B<on>, then C<foo$bar> is a single seven-character name nad
variable expansions must be specified using braces or parentheses.
.pragma [=] includedir:value
If a relative pathname is specified in the B<.include> directive, and
the B<OPENSSL_CONF_INCLUDE> environment variable doesn't exist, then
the value of the B<includedir> pragma, if it exists, is prepended to the
pathname.
=head2 Settings
A configuration file is divided into a number of I<sections>. A section

View File

@ -119,7 +119,9 @@ struct conf_st {
CONF_METHOD *meth;
void *meth_data;
LHASH_OF(CONF_VALUE) *data;
unsigned int flag_dollarid:1;
int flag_dollarid;
int flag_abspath;
char *includedir;
OSSL_LIB_CTX *libctx;
};

View File

@ -13,7 +13,7 @@ plan skip_all => "test_includes doesn't work without posix-io"
delete $ENV{OPENSSL_CONF_INCLUDE};
plan tests => # The number of tests being performed
5
6
+ ($^O eq "VMS" ? 2 : 0);
ok(run(test(["conf_include_test", data_file("includes.cnf")])), "test directory includes");
@ -27,3 +27,4 @@ if ($^O eq "VMS") {
"test file includes, VMS syntax");
}
ok(run(test(["conf_include_test", "-f", data_file("includes-broken.cnf")])), "test broken includes");
ok(run(test(["conf_include_test", "-f", data_file("incdir.cnf")])), "test includedir");

View File

@ -0,0 +1,6 @@
#
# Set includedir and expect to fail
#
.pragma includedir:/
.include includes.cnf