Skip to content

Commit

Permalink
context: add XKB_CONTEXT_NO_SECURE_GETENV flag (#312)
Browse files Browse the repository at this point in the history
This flag is useful for clients that may have relatively benign capabilities
set, like CAP_SYS_NICE, that also want to use the xkb configuration from the
environment and user configs in XDG_CONFIG_HOME.

Fixes: #308
Fixes: #129
Signed-off-by: Ran Benita <ran@unusedvar.com>
  • Loading branch information
rpigott committed Dec 16, 2022
1 parent 9d1043d commit b4e81ca
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 53 deletions.
10 changes: 9 additions & 1 deletion include/xkbcommon/xkbcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,9 +580,17 @@ enum xkb_context_flags {
XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
/**
* Don't take RMLVO names from the environment.
*
* @since 0.3.0
*/
XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1)
XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1),
/**
* Disable the use of secure_getenv for this context, so that privileged
* processes can use environment variables. Client uses at their own risk.
*
* @since 1.5.0
*/
XKB_CONTEXT_NO_SECURE_GETENV = (1 << 2)
};

/**
Expand Down
7 changes: 7 additions & 0 deletions include/xkbcommon/xkbregistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ enum rxkb_context_flags {
* on the lookup behavior.
*/
RXKB_CONTEXT_LOAD_EXOTIC_RULES = (1 << 1),
/**
* Disable the use of secure_getenv for this context, so that privileged
* processes can use environment variables. Client uses at their own risk.
*
* @since 1.5.0
*/
RXKB_CONTEXT_NO_SECURE_GETENV = (1 << 2)
};

/**
Expand Down
6 changes: 3 additions & 3 deletions src/compose/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ lex_include_string(struct scanner *s, struct xkb_compose_table *table,
scanner_buf_append(s, '%');
}
else if (scanner_chr(s, 'H')) {
const char *home = secure_getenv("HOME");
const char *home = xkb_context_getenv(table->ctx, "HOME");
if (!home) {
scanner_err(s, "%%H was used in an include statement, but the HOME environment variable is not set");
return TOK_ERROR;
Expand All @@ -273,7 +273,7 @@ lex_include_string(struct scanner *s, struct xkb_compose_table *table,
}
}
else if (scanner_chr(s, 'L')) {
char *path = get_locale_compose_file_path(table->locale);
char *path = get_locale_compose_file_path(table->ctx, table->locale);
if (!path) {
scanner_err(s, "failed to expand %%L to the locale Compose file");
return TOK_ERROR;
Expand All @@ -286,7 +286,7 @@ lex_include_string(struct scanner *s, struct xkb_compose_table *table,
free(path);
}
else if (scanner_chr(s, 'S')) {
const char *xlocaledir = get_xlocaledir_path();
const char *xlocaledir = get_xlocaledir_path(table->ctx);
if (!scanner_buf_appends(s, xlocaledir)) {
scanner_err(s, "include path after expanding %%S is too long");
return TOK_ERROR;
Expand Down
37 changes: 19 additions & 18 deletions src/compose/paths.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@

#include "config.h"

#include "xkbcommon/xkbcommon.h"
#include "utils.h"
#include "context.h"
#include "paths.h"
#include "utils.h"

enum resolve_name_direction {
LEFT_TO_RIGHT,
RIGHT_TO_LEFT,
};

const char *
get_xlocaledir_path(void)
get_xlocaledir_path(struct xkb_context *ctx)
{
const char *dir = secure_getenv("XLOCALEDIR");
const char *dir = xkb_context_getenv(ctx, "XLOCALEDIR");
if (!dir)
dir = XLOCALEDIR;
return dir;
Expand All @@ -47,8 +48,8 @@ get_xlocaledir_path(void)
* @filename is relative to the xlocaledir.
*/
static char *
resolve_name(const char *filename, enum resolve_name_direction direction,
const char *name)
resolve_name(struct xkb_context *ctx, const char *filename,
enum resolve_name_direction direction, const char *name)
{
int ret;
bool ok;
Expand All @@ -62,7 +63,7 @@ resolve_name(const char *filename, enum resolve_name_direction direction,
char *match;
size_t left_len, right_len, name_len;

xlocaledir = get_xlocaledir_path();
xlocaledir = get_xlocaledir_path(ctx);

ret = snprintf(path, sizeof(path), "%s/%s", xlocaledir, filename);
if (ret < 0 || (size_t) ret >= sizeof(path))
Expand Down Expand Up @@ -137,27 +138,27 @@ resolve_name(const char *filename, enum resolve_name_direction direction,
}

char *
resolve_locale(const char *locale)
resolve_locale(struct xkb_context *ctx, const char *locale)
{
char *alias = resolve_name("locale.alias", LEFT_TO_RIGHT, locale);
char *alias = resolve_name(ctx, "locale.alias", LEFT_TO_RIGHT, locale);
return alias ? alias : strdup(locale);
}

char *
get_xcomposefile_path(void)
get_xcomposefile_path(struct xkb_context *ctx)
{
return strdup_safe(secure_getenv("XCOMPOSEFILE"));
return strdup_safe(xkb_context_getenv(ctx, "XCOMPOSEFILE"));
}

char *
get_xdg_xcompose_file_path(void)
get_xdg_xcompose_file_path(struct xkb_context *ctx)
{
const char *xdg_config_home;
const char *home;

xdg_config_home = secure_getenv("XDG_CONFIG_HOME");
xdg_config_home = xkb_context_getenv(ctx, "XDG_CONFIG_HOME");
if (!xdg_config_home || xdg_config_home[0] != '/') {
home = secure_getenv("HOME");
home = xkb_context_getenv(ctx, "HOME");
if (!home)
return NULL;
return asprintf_safe("%s/.config/XCompose", home);
Expand All @@ -167,19 +168,19 @@ get_xdg_xcompose_file_path(void)
}

char *
get_home_xcompose_file_path(void)
get_home_xcompose_file_path(struct xkb_context *ctx)
{
const char *home;

home = secure_getenv("HOME");
home = xkb_context_getenv(ctx, "HOME");
if (!home)
return NULL;

return asprintf_safe("%s/.XCompose", home);
}

char *
get_locale_compose_file_path(const char *locale)
get_locale_compose_file_path(struct xkb_context *ctx, const char *locale)
{
char *resolved;
char *path;
Expand All @@ -198,15 +199,15 @@ get_locale_compose_file_path(const char *locale)
if (streq(locale, "C"))
locale = "en_US.UTF-8";

resolved = resolve_name("compose.dir", RIGHT_TO_LEFT, locale);
resolved = resolve_name(ctx, "compose.dir", RIGHT_TO_LEFT, locale);
if (!resolved)
return NULL;

if (resolved[0] == '/') {
path = resolved;
}
else {
const char *xlocaledir = get_xlocaledir_path();
const char *xlocaledir = get_xlocaledir_path(ctx);
path = asprintf_safe("%s/%s", xlocaledir, resolved);
free(resolved);
}
Expand Down
12 changes: 6 additions & 6 deletions src/compose/paths.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@
#define COMPOSE_RESOLVE_H

char *
resolve_locale(const char *locale);
resolve_locale(struct xkb_context *ctx, const char *locale);

const char *
get_xlocaledir_path(void);
get_xlocaledir_path(struct xkb_context *ctx);

char *
get_xcomposefile_path(void);
get_xcomposefile_path(struct xkb_context *ctx);

char *
get_xdg_xcompose_file_path(void);
get_xdg_xcompose_file_path(struct xkb_context *ctx);

char *
get_home_xcompose_file_path(void);
get_home_xcompose_file_path(struct xkb_context *ctx);

char *
get_locale_compose_file_path(const char *locale);
get_locale_compose_file_path(struct xkb_context *ctx, const char *locale);

#endif
10 changes: 5 additions & 5 deletions src/compose/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ xkb_compose_table_new(struct xkb_context *ctx,
struct xkb_compose_table *table;
struct compose_node dummy;

resolved_locale = resolve_locale(locale);
resolved_locale = resolve_locale(ctx, locale);
if (!resolved_locale)
return NULL;

Expand Down Expand Up @@ -174,31 +174,31 @@ xkb_compose_table_new_from_locale(struct xkb_context *ctx,
if (!table)
return NULL;

path = get_xcomposefile_path();
path = get_xcomposefile_path(ctx);
if (path) {
file = fopen(path, "rb");
if (file)
goto found_path;
}
free(path);

path = get_xdg_xcompose_file_path();
path = get_xdg_xcompose_file_path(ctx);
if (path) {
file = fopen(path, "rb");
if (file)
goto found_path;
}
free(path);

path = get_home_xcompose_file_path();
path = get_home_xcompose_file_path(ctx);
if (path) {
file = fopen(path, "rb");
if (file)
goto found_path;
}
free(path);

path = get_locale_compose_file_path(table->locale);
path = get_locale_compose_file_path(ctx, table->locale);
if (path) {
file = fopen(path, "rb");
if (file)
Expand Down
22 changes: 16 additions & 6 deletions src/context-priv.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@
#include "utils.h"
#include "context.h"

char *
xkb_context_getenv(struct xkb_context *ctx, const char *name)
{
if (ctx->use_secure_getenv) {
return secure_getenv(name);
} else {
return getenv(name);
}
}

unsigned int
xkb_context_num_failed_include_paths(struct xkb_context *ctx)
{
Expand Down Expand Up @@ -105,7 +115,7 @@ xkb_context_get_default_rules(struct xkb_context *ctx)
const char *env = NULL;

if (ctx->use_environment_names)
env = secure_getenv("XKB_DEFAULT_RULES");
env = xkb_context_getenv(ctx, "XKB_DEFAULT_RULES");

return env ? env : DEFAULT_XKB_RULES;
}
Expand All @@ -116,7 +126,7 @@ xkb_context_get_default_model(struct xkb_context *ctx)
const char *env = NULL;

if (ctx->use_environment_names)
env = secure_getenv("XKB_DEFAULT_MODEL");
env = xkb_context_getenv(ctx, "XKB_DEFAULT_MODEL");

return env ? env : DEFAULT_XKB_MODEL;
}
Expand All @@ -127,7 +137,7 @@ xkb_context_get_default_layout(struct xkb_context *ctx)
const char *env = NULL;

if (ctx->use_environment_names)
env = secure_getenv("XKB_DEFAULT_LAYOUT");
env = xkb_context_getenv(ctx, "XKB_DEFAULT_LAYOUT");

return env ? env : DEFAULT_XKB_LAYOUT;
}
Expand All @@ -136,12 +146,12 @@ static const char *
xkb_context_get_default_variant(struct xkb_context *ctx)
{
const char *env = NULL;
const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT");
const char *layout = xkb_context_getenv(ctx, "XKB_DEFAULT_LAYOUT");

/* We don't want to inherit the variant if they haven't also set a
* layout, since they're so closely paired. */
if (layout && ctx->use_environment_names)
env = secure_getenv("XKB_DEFAULT_VARIANT");
env = xkb_context_getenv(ctx, "XKB_DEFAULT_VARIANT");

return env ? env : DEFAULT_XKB_VARIANT;
}
Expand All @@ -152,7 +162,7 @@ xkb_context_get_default_options(struct xkb_context *ctx)
const char *env = NULL;

if (ctx->use_environment_names)
env = secure_getenv("XKB_DEFAULT_OPTIONS");
env = xkb_context_getenv(ctx, "XKB_DEFAULT_OPTIONS");

return env ? env : DEFAULT_XKB_OPTIONS;
}
Expand Down
17 changes: 9 additions & 8 deletions src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "utils.h"
#include "context.h"


/**
* Append one directory to the context's include path.
*/
Expand Down Expand Up @@ -77,14 +78,14 @@ xkb_context_include_path_append(struct xkb_context *ctx, const char *path)
const char *
xkb_context_include_path_get_extra_path(struct xkb_context *ctx)
{
const char *extra = secure_getenv("XKB_CONFIG_EXTRA_PATH");
const char *extra = xkb_context_getenv(ctx, "XKB_CONFIG_EXTRA_PATH");
return extra ? extra : DFLT_XKB_CONFIG_EXTRA_PATH;
}

const char *
xkb_context_include_path_get_system_path(struct xkb_context *ctx)
{
const char *root = secure_getenv("XKB_CONFIG_ROOT");
const char *root = xkb_context_getenv(ctx, "XKB_CONFIG_ROOT");
return root ? root : DFLT_XKB_CONFIG_ROOT;
}

Expand All @@ -98,9 +99,9 @@ xkb_context_include_path_append_default(struct xkb_context *ctx)
char *user_path;
int ret = 0;

home = secure_getenv("HOME");
home = xkb_context_getenv(ctx, "HOME");

xdg = secure_getenv("XDG_CONFIG_HOME");
xdg = xkb_context_getenv(ctx, "XDG_CONFIG_HOME");
if (xdg != NULL) {
user_path = asprintf_safe("%s/xkb", xdg);
if (user_path) {
Expand Down Expand Up @@ -289,13 +290,15 @@ xkb_context_new(enum xkb_context_flags flags)
ctx->log_fn = default_log_fn;
ctx->log_level = XKB_LOG_LEVEL_ERROR;
ctx->log_verbosity = 0;
ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
ctx->use_secure_getenv = !(flags & XKB_CONTEXT_NO_SECURE_GETENV);

/* Environment overwrites defaults. */
env = secure_getenv("XKB_LOG_LEVEL");
env = xkb_context_getenv(ctx, "XKB_LOG_LEVEL");
if (env)
xkb_context_set_log_level(ctx, log_level(env));

env = secure_getenv("XKB_LOG_VERBOSITY");
env = xkb_context_getenv(ctx, "XKB_LOG_VERBOSITY");
if (env)
xkb_context_set_log_verbosity(ctx, log_verbosity(env));

Expand All @@ -307,8 +310,6 @@ xkb_context_new(enum xkb_context_flags flags)
return NULL;
}

ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);

ctx->atom_table = atom_table_new();
if (!ctx->atom_table) {
xkb_context_unref(ctx);
Expand Down
4 changes: 4 additions & 0 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ struct xkb_context {
size_t text_next;

unsigned int use_environment_names : 1;
unsigned int use_secure_getenv : 1;
};

char *
xkb_context_getenv(struct xkb_context *ctx, const char *name);

unsigned int
xkb_context_num_failed_include_paths(struct xkb_context *ctx);

Expand Down
Loading

0 comments on commit b4e81ca

Please sign in to comment.