Xnamespace: assign incoming clients to namespaces

The association is done by matching client's and namespace's
authentication token.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2024-01-25 16:38:10 +01:00
parent 9f8ef921ad
commit 0698743fde
5 changed files with 99 additions and 2 deletions

View File

@ -0,0 +1,45 @@
#define HOOK_NAME "clienstate"
#include <dix-config.h>
#include "dix/registry_priv.h"
#include "os/client_priv.h"
#include "os/auth.h"
#include "namespace.h"
#include "hooks.h"
void hookClientState(CallbackListPtr *pcbl, void *unused, void *calldata)
{
XNS_HOOK_HEAD(NewClientInfoRec);
switch (client->clientState) {
case ClientStateInitial:
// better assign *someting* than null -- clients can't do anything yet anyways
XnamespaceAssignClient(subj, &ns_anon);
break;
case ClientStateRunning:
subj->authId = AuthorizationIDOfClient(client);
short unsigned int name_len = 0, data_len = 0;
const char * name = NULL;
char * data = NULL;
if (AuthorizationFromID(subj->authId, &name_len, &name, &data_len, &data)) {
XnamespaceAssignClient(subj, XnsFindByAuth(name_len, name, data_len, data));
} else {
XNS_HOOK_LOG("no auth data - assuming anon\n");
}
break;
case ClientStateRetained:
XnamespaceAssignClient(subj, NULL);
break;
case ClientStateGone:
XnamespaceAssignClient(subj, NULL);
break;
default:
XNS_HOOK_LOG("unknown state =%d\n", client->clientState);
break;
}
}

29
Xext/namespace/hooks.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __XSERVER_NAMESPACE_HOOKS_H
#define __XSERVER_NAMESPACE_HOOKS_H
#include "dix/registry_priv.h"
#include "include/misc.h"
#include "namespace.h"
#define XNS_HOOK_LOG(...) do { \
printf("XNS [" HOOK_NAME "] (#%d@%d) {%s} <%s>: ", \
(client ? client->index : -1), \
(client ? client->sequence : -1), \
(subj ? (subj->ns ? subj->ns->name : "(no ns)") : "<no client>"), \
LookupRequestName(client ? client->majorOp : 0, \
client ? client->minorOp : 0)); \
printf(__VA_ARGS__); \
} while (0)
#define XNS_HOOK_HEAD(t) \
t *param = calldata; \
ClientPtr client = param->client; \
if (!client) { \
/* XNS_LOG("hook %s NULL client\n", HOOK_NAME); */ \
} \
struct XnamespaceClientPriv *subj = XnsClientPriv(client);
void hookClientState(CallbackListPtr *pcbl, void *unused, void *calldata);
#endif /* __XSERVER_NAMESPACE_HOOKS_H */

View File

@ -2,6 +2,7 @@ libxserver_namespace = static_library(
'libxserver_namespace', 'libxserver_namespace',
[ [
'config.c', 'config.c',
'hook-clientstate.c',
'namespace.c', 'namespace.c',
], ],
include_directories: inc, include_directories: inc,

View File

@ -8,6 +8,7 @@
#include "miext/extinit_priv.h" #include "miext/extinit_priv.h"
#include "namespace.h" #include "namespace.h"
#include "hooks.h"
Bool noNamespaceExtension = TRUE; Bool noNamespaceExtension = TRUE;
@ -24,8 +25,9 @@ NamespaceExtensionInit(void)
return; return;
} }
if (!dixRegisterPrivateKey if (!(dixRegisterPrivateKey(&namespaceClientPrivKeyRec, PRIVATE_CLIENT,
(&namespaceClientPrivKeyRec, PRIVATE_CLIENT, sizeof(struct XnamespaceClientPriv))) sizeof(struct XnamespaceClientPriv)) &&
AddCallback(&ClientStateCallback, hookClientState, NULL)))
FatalError("NamespaceExtensionInit: allocation failure\n"); FatalError("NamespaceExtensionInit: allocation failure\n");
/* Do the serverClient */ /* Do the serverClient */
@ -54,3 +56,19 @@ void XnamespaceAssignClientByName(struct XnamespaceClientPriv *priv, const char
XnamespaceAssignClient(priv, newns); XnamespaceAssignClient(priv, newns);
} }
struct Xnamespace* XnsFindByAuth(size_t szAuthProto, const char* authProto, size_t szAuthToken, const char* authToken)
{
struct Xnamespace *walk;
xorg_list_for_each_entry(walk, &ns_list, entry) {
int protoLen = walk->authProto ? strlen(walk->authProto) : 0;
if ((protoLen == szAuthProto) &&
(walk->authTokenLen == szAuthToken) &&
(memcmp(walk->authTokenData, authToken, szAuthToken)==0) &&
(memcmp(walk->authProto, authProto, szAuthProto)==0))
return walk;
}
// default to anonymous if credentials aren't assigned to specific NS
return &ns_anon;
}

View File

@ -14,6 +14,9 @@ struct Xnamespace {
const char *name; const char *name;
Bool builtin; Bool builtin;
Bool superPower; Bool superPower;
const char *authProto;
char *authTokenData;
size_t authTokenLen;
size_t refcnt; size_t refcnt;
}; };
@ -34,6 +37,7 @@ extern DevPrivateKeyRec namespaceClientPrivKeyRec;
Bool XnsLoadConfig(void); Bool XnsLoadConfig(void);
struct Xnamespace *XnsFindByName(const char* name); struct Xnamespace *XnsFindByName(const char* name);
struct Xnamespace* XnsFindByAuth(size_t szAuthProto, const char* authProto, size_t szAuthToken, const char* authToken);
void XnamespaceAssignClient(struct XnamespaceClientPriv *priv, struct Xnamespace *ns); void XnamespaceAssignClient(struct XnamespaceClientPriv *priv, struct Xnamespace *ns);
void XnamespaceAssignClientByName(struct XnamespaceClientPriv *priv, const char *name); void XnamespaceAssignClientByName(struct XnamespaceClientPriv *priv, const char *name);