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:
parent
9f8ef921ad
commit
0698743fde
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 */
|
|
@ -2,6 +2,7 @@ libxserver_namespace = static_library(
|
|||
'libxserver_namespace',
|
||||
[
|
||||
'config.c',
|
||||
'hook-clientstate.c',
|
||||
'namespace.c',
|
||||
],
|
||||
include_directories: inc,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "miext/extinit_priv.h"
|
||||
|
||||
#include "namespace.h"
|
||||
#include "hooks.h"
|
||||
|
||||
Bool noNamespaceExtension = TRUE;
|
||||
|
||||
|
@ -24,8 +25,9 @@ NamespaceExtensionInit(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!dixRegisterPrivateKey
|
||||
(&namespaceClientPrivKeyRec, PRIVATE_CLIENT, sizeof(struct XnamespaceClientPriv)))
|
||||
if (!(dixRegisterPrivateKey(&namespaceClientPrivKeyRec, PRIVATE_CLIENT,
|
||||
sizeof(struct XnamespaceClientPriv)) &&
|
||||
AddCallback(&ClientStateCallback, hookClientState, NULL)))
|
||||
FatalError("NamespaceExtensionInit: allocation failure\n");
|
||||
|
||||
/* Do the serverClient */
|
||||
|
@ -54,3 +56,19 @@ void XnamespaceAssignClientByName(struct XnamespaceClientPriv *priv, const char
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ struct Xnamespace {
|
|||
const char *name;
|
||||
Bool builtin;
|
||||
Bool superPower;
|
||||
const char *authProto;
|
||||
char *authTokenData;
|
||||
size_t authTokenLen;
|
||||
size_t refcnt;
|
||||
};
|
||||
|
||||
|
@ -34,6 +37,7 @@ extern DevPrivateKeyRec namespaceClientPrivKeyRec;
|
|||
|
||||
Bool XnsLoadConfig(void);
|
||||
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 XnamespaceAssignClientByName(struct XnamespaceClientPriv *priv, const char *name);
|
||||
|
||||
|
|
Loading…
Reference in New Issue