Xnamespace: initial config loader

This loads the configuration (simple text file) passed via command line.
For now just supporting static configuration, that's loaded on server
startup.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-03-19 10:50:56 +01:00
parent 9c4b4e54d1
commit f790bae8dc
4 changed files with 187 additions and 3 deletions

View File

@ -3,6 +3,8 @@
#include <string.h> #include <string.h>
#include <X11/Xdefs.h> #include <X11/Xdefs.h>
#include "os/auth.h"
#include "namespace.h" #include "namespace.h"
struct Xnamespace ns_root = { struct Xnamespace ns_root = {
@ -25,11 +27,165 @@ struct Xnamespace ns_anon = {
struct xorg_list ns_list = { 0 }; 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;
}
/*
* loadConfig
*
* Load the container config
*/
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, " ");
if (token == NULL)
return;
// if no "container" statement hasn't been issued yet, use root NS
struct Xnamespace * curr = (*walk_ns ? *walk_ns : &ns_root);
if (strcmp(token, "container") == 0)
{
if ((token = strtok(NULL, " ")) == NULL)
{
XNS_LOG("container missing id\n");
return;
}
curr = *walk_ns = select_ns(token);
return;
}
if (strcmp(token, "auth") == 0)
{
token = strtok(NULL, " ");
if (token == NULL)
return;
curr->authProto = strdup(token);
token = strtok(NULL, " ");
curr->authTokenLen = strlen(token)/2;
curr->authTokenData = calloc(1, curr->authTokenLen);
if (!curr->authTokenData) {
curr->authTokenLen = 0;
return;
}
hex2bin(token, curr->authTokenData);
AddAuthorization(strlen(curr->authProto),
curr->authProto,
curr->authTokenLen,
curr->authTokenData);
return;
}
if (strcmp(token, "allow") == 0)
{
while ((token = strtok(NULL, " ")) != 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) Bool XnsLoadConfig(void)
{ {
xorg_list_init(&ns_list); xorg_list_append_ndup(&ns_root.entry, &ns_list);
xorg_list_add(&ns_root.entry, &ns_list); xorg_list_append_ndup(&ns_anon.entry, &ns_list);
xorg_list_add(&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 container 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\" \"%s\" \"",
ns->name,
ns->authProto);
for (int i=0; i<ns->authTokenLen; i++)
printf("%02X", (unsigned char)ns->authTokenData[i]);
printf("\"\n");
}
return TRUE; return TRUE;
} }

View File

@ -0,0 +1,13 @@
# auth <proto> <hex-key>
auth MIT-MAGIC-COOKIE-1 46f8e62b78e58962de0ceefc05ad90b0
# container <name> <parent_name>
container xeyes root
auth MIT-MAGIC-COOKIE-1 46f8e62b78e58962de0ceefc05ad90b8
allow mouse-motion
allow shape
allow xinput
container xclock root
auth MIT-MAGIC-COOKIE-1 46f8e62b78e58962de0ceefc05ad90b7

View File

@ -25,6 +25,8 @@ extern Bool noXFixesExtension;
extern Bool noXFree86BigfontExtension; extern Bool noXFree86BigfontExtension;
extern Bool noNamespaceExtension; extern Bool noNamespaceExtension;
extern char *namespaceConfigFile;
void CompositeExtensionInit(void); void CompositeExtensionInit(void);
void DamageExtensionInit(void); void DamageExtensionInit(void);
void DbeExtensionInit(void); void DbeExtensionInit(void);

View File

@ -294,6 +294,9 @@ UseMsg(void)
ErrorF("+iglx Allow creating indirect GLX contexts\n"); ErrorF("+iglx Allow creating indirect GLX contexts\n");
ErrorF("-iglx Prohibit creating indirect GLX contexts (default)\n"); ErrorF("-iglx Prohibit creating indirect GLX contexts (default)\n");
ErrorF("-I ignore all remaining arguments\n"); ErrorF("-I ignore all remaining arguments\n");
#ifdef CONFIG_NAMESPACE
ErrorF("-namespace <conf> Enable NAMESPACE extension with given config file\n");
#endif /* CONFIG_NAMESPACE */
LockServerUseMsg(); LockServerUseMsg();
ErrorF("-maxclients n set maximum number of clients (power of two)\n"); ErrorF("-maxclients n set maximum number of clients (power of two)\n");
ErrorF("-nolisten string don't listen on protocol\n"); ErrorF("-nolisten string don't listen on protocol\n");
@ -692,6 +695,16 @@ ProcessCommandLine(int argc, char *argv[])
UseMsg(); UseMsg();
} }
} }
#ifdef CONFIG_NAMESPACE
else if (strcmp(argv[i], "-namespace") == 0) {
if (++i < argc) {
namespaceConfigFile = argv[i];
noNamespaceExtension = FALSE;
}
else
UseMsg();
}
#endif
#ifdef XINERAMA #ifdef XINERAMA
else if (strcmp(argv[i], "+xinerama") == 0) { else if (strcmp(argv[i], "+xinerama") == 0) {
noPanoramiXExtension = FALSE; noPanoramiXExtension = FALSE;