209 lines
5.4 KiB
C
209 lines
5.4 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;
|
|
}
|
|
|
|
/*
|
|
* 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;
|
|
|
|
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);
|
|
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, " ")) != 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 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\" \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;
|
|
}
|