mirror of
https://github.com/X11Libre/xserver.git
synced 2026-01-26 14:03:17 +00:00
Allow the parseLine() function to use tabs alongside spaces to separate tokens. Without this patch, using tabs in the config file actually confuses the parser and makes it think that the tab is part of the option's name. Signed-off-by: Aggelos Tselios <aggelostselios777@gmail.com>
210 lines
5.6 KiB
C
210 lines
5.6 KiB
C
#include <dix-config.h>
|
|
|
|
#include <string.h>
|
|
#include <X11/Xdefs.h>
|
|
|
|
#include "os/auth.h"
|
|
|
|
#include "namespace.h"
|
|
|
|
struct Xnamespace ns_root = {
|
|
.allowMouseMotion = TRUE,
|
|
.allowShape = TRUE,
|
|
.allowTransparency = TRUE,
|
|
.allowXInput = TRUE,
|
|
.allowXKeyboard = TRUE,
|
|
.builtin = TRUE,
|
|
.name = NS_NAME_ROOT,
|
|
.refcnt = 1,
|
|
.superPower = TRUE,
|
|
};
|
|
|
|
struct Xnamespace ns_anon = {
|
|
.builtin = TRUE,
|
|
.name = NS_NAME_ANONYMOUS,
|
|
.refcnt = 1,
|
|
};
|
|
|
|
struct xorg_list ns_list = { 0 };
|
|
|
|
char *namespaceConfigFile = NULL;
|
|
|
|
static struct Xnamespace* select_ns(const char* name)
|
|
{
|
|
struct Xnamespace *walk;
|
|
xorg_list_for_each_entry(walk, &ns_list, entry) {
|
|
if (strcmp(walk->name, name)==0)
|
|
return walk;
|
|
}
|
|
|
|
struct Xnamespace *newns = calloc(1, sizeof(struct Xnamespace));
|
|
newns->name = strdup(name);
|
|
xorg_list_append(&newns->entry, &ns_list);
|
|
return newns;
|
|
}
|
|
|
|
#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \
|
|
'a' <= c && c <= 'f' ? c - 'a' + 10 : \
|
|
'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
|
|
|
|
// warning: no error checking, no buffer clearing
|
|
static int hex2bin(const char *in, char *out)
|
|
{
|
|
while (in[0] && in[1]) {
|
|
int top = atox(in[0]);
|
|
if (top == -1)
|
|
return 0;
|
|
int bottom = atox(in[1]);
|
|
if (bottom == -1)
|
|
return 0;
|
|
*out++ = (top << 4) | bottom;
|
|
in += 2;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Parse a single line from the configuration file,
|
|
* ignoring comments and newlines. Prints a warning if it finds an unknown token.
|
|
*/
|
|
static void parseLine(char *line, struct Xnamespace **walk_ns)
|
|
{
|
|
// trim newline and comments
|
|
char *c1 = strchr(line, '\n');
|
|
if (c1 != NULL)
|
|
*c1 = 0;
|
|
c1 = strchr(line, '#');
|
|
if (c1 != NULL)
|
|
*c1 = 0;
|
|
|
|
/* get the first token */
|
|
char *token = strtok(line, " \t");
|
|
|
|
if (token == NULL)
|
|
return;
|
|
|
|
/* if no "namespace" statement hasn't been issued yet, use root NS */
|
|
struct Xnamespace * curr = (*walk_ns ? *walk_ns : &ns_root);
|
|
|
|
if ((strcmp(token, "namespace") == 0) ||
|
|
(strcmp(token, "container") == 0)) /* "container" is deprecated ! */
|
|
{
|
|
if ((token = strtok(NULL, " ")) == NULL)
|
|
{
|
|
XNS_LOG("namespace missing id\n");
|
|
return;
|
|
}
|
|
|
|
curr = *walk_ns = select_ns(token);
|
|
return;
|
|
}
|
|
|
|
if (strcmp(token, "auth") == 0)
|
|
{
|
|
token = strtok(NULL, " \t");
|
|
if (token == NULL)
|
|
return;
|
|
|
|
struct auth_token *new_token = calloc(1, sizeof(struct auth_token));
|
|
if (new_token == NULL)
|
|
FatalError("Xnamespace: failed allocating token\n");
|
|
|
|
new_token->authProto = strdup(token);
|
|
token = strtok(NULL, " ");
|
|
|
|
new_token->authTokenLen = strlen(token)/2;
|
|
new_token->authTokenData = calloc(1, new_token->authTokenLen);
|
|
if (!new_token->authTokenData) {
|
|
free(new_token->authProto);
|
|
free(new_token);
|
|
return;
|
|
}
|
|
hex2bin(token, new_token->authTokenData);
|
|
|
|
new_token->authId = AddAuthorization(strlen(new_token->authProto),
|
|
new_token->authProto,
|
|
new_token->authTokenLen,
|
|
new_token->authTokenData);
|
|
|
|
xorg_list_append(&new_token->entry, &curr->auth_tokens);
|
|
return;
|
|
}
|
|
|
|
if (strcmp(token, "allow") == 0)
|
|
{
|
|
while ((token = strtok(NULL, " \t")) != NULL)
|
|
{
|
|
if (strcmp(token, "mouse-motion") == 0)
|
|
curr->allowMouseMotion = TRUE;
|
|
else if (strcmp(token, "shape") == 0)
|
|
curr->allowShape = TRUE;
|
|
else if (strcmp(token, "transparency") == 0)
|
|
curr->allowTransparency = TRUE;
|
|
else if (strcmp(token, "xinput") == 0)
|
|
curr->allowXInput = TRUE;
|
|
else if (strcmp(token, "xkeyboard") == 0)
|
|
curr->allowXKeyboard = TRUE;
|
|
else
|
|
XNS_LOG("unknown allow: %s\n", token);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (strcmp(token, "superpower") == 0)
|
|
{
|
|
curr->superPower = TRUE;
|
|
return;
|
|
}
|
|
|
|
XNS_LOG("unknown token \"%s\"\n", token);
|
|
}
|
|
|
|
Bool XnsLoadConfig(void)
|
|
{
|
|
xorg_list_append_ndup(&ns_root.entry, &ns_list);
|
|
xorg_list_append_ndup(&ns_anon.entry, &ns_list);
|
|
|
|
if (!namespaceConfigFile) {
|
|
XNS_LOG("no namespace config given - Xnamespace disabled\n");
|
|
return FALSE;
|
|
}
|
|
|
|
FILE *fp = fopen(namespaceConfigFile, "r");
|
|
if (fp == NULL) {
|
|
FatalError("failed loading namespace config: %s\n", namespaceConfigFile);
|
|
return FALSE;
|
|
}
|
|
|
|
struct Xnamespace *walk_ns = NULL;
|
|
char linebuf[1024];
|
|
while (fgets(linebuf, sizeof(linebuf), fp) != NULL)
|
|
parseLine(linebuf, &walk_ns);
|
|
|
|
fclose(fp);
|
|
|
|
XNS_LOG("loaded namespace config file: %s\n", namespaceConfigFile);
|
|
|
|
struct Xnamespace *ns;
|
|
xorg_list_for_each_entry(ns, &ns_list, entry) {
|
|
XNS_LOG("namespace: \"%s\" \n", ns->name);
|
|
struct auth_token *at;
|
|
xorg_list_for_each_entry(at, &ns->auth_tokens, entry) {
|
|
XNS_LOG(" auth: \"%s\" \"", at->authProto);
|
|
for (int i=0; i<at->authTokenLen; i++)
|
|
printf("%02X", (unsigned char)at->authTokenData[i]);
|
|
printf("\"\n");
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
struct Xnamespace *XnsFindByName(const char* name) {
|
|
struct Xnamespace *walk;
|
|
xorg_list_for_each_entry(walk, &ns_list, entry) {
|
|
if (strcmp(walk->name, name)==0)
|
|
return walk;
|
|
}
|
|
return NULL;
|
|
}
|