#ifdef K5AUTH
# include <krb5/krb5.h>
#endif
# include <X11/X.h>
# include <X11/Xauth.h>
# include "misc.h"
# include "osdep.h"
# include "dixstruct.h"
# include <sys/types.h>
# include <sys/stat.h>
#ifdef XCSECURITY
#define _SECURITY_SERVER
# include "extensions/security.h"
#endif
#ifdef WIN32
#include "Xw32defs.h"
#endif
struct protocol {
unsigned short name_length;
char *name;
AuthAddCFunc Add;
AuthCheckFunc Check;
AuthRstCFunc Reset;
AuthToIDFunc ToID;
AuthFromIDFunc FromID;
AuthRemCFunc Remove;
#ifdef XCSECURITY
AuthGenCFunc Generate;
#endif
};
static struct protocol protocols[] = {
{ (unsigned short) 18, "MIT-MAGIC-COOKIE-1",
MitAddCookie, MitCheckCookie, MitResetCookie,
MitToID, MitFromID, MitRemoveCookie,
#ifdef XCSECURITY
MitGenerateCookie
#endif
},
#ifdef HASXDMAUTH
{ (unsigned short) 19, "XDM-AUTHORIZATION-1",
XdmAddCookie, XdmCheckCookie, XdmResetCookie,
XdmToID, XdmFromID, XdmRemoveCookie,
#ifdef XCSECURITY
NULL
#endif
},
#endif
#ifdef SECURE_RPC
{ (unsigned short) 9, "SUN-DES-1",
SecureRPCAdd, SecureRPCCheck, SecureRPCReset,
SecureRPCToID, SecureRPCFromID,SecureRPCRemove,
#ifdef XCSECURITY
NULL
#endif
},
#endif
#ifdef K5AUTH
{ (unsigned short) 14, "MIT-KERBEROS-5",
K5Add, K5Check, K5Reset,
K5ToID, K5FromID, K5Remove,
#ifdef XCSECURITY
NULL
#endif
},
#endif
#ifdef XCSECURITY
{ (unsigned short) XSecurityAuthorizationNameLen,
XSecurityAuthorizationName,
NULL, AuthSecurityCheck, NULL,
NULL, NULL, NULL,
NULL
},
#endif
};
# define NUM_AUTHORIZATION (sizeof (protocols) /\
sizeof (struct protocol))
static char *authorization_file = (char *)NULL;
static Bool ShouldLoadAuth = TRUE;
void
InitAuthorization (char *file_name)
{
authorization_file = file_name;
}
static int
LoadAuthorization (void)
{
FILE *f;
Xauth *auth;
int i;
int count = 0;
ShouldLoadAuth = FALSE;
if (!authorization_file)
return 0;
f = Fopen (authorization_file, "r");
if (!f)
return -1;
while ((auth = XauReadAuth (f)) != 0) {
for (i = 0; i < NUM_AUTHORIZATION; i++) {
if (protocols[i].name_length == auth->name_length &&
memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 &&
protocols[i].Add)
{
++count;
(*protocols[i].Add) (auth->data_length, auth->data,
FakeClientID(0));
}
}
XauDisposeAuth (auth);
}
Fclose (f);
return count;
}
#ifdef XDMCP
void
RegisterAuthorizations (void)
{
int i;
for (i = 0; i < NUM_AUTHORIZATION; i++)
XdmcpRegisterAuthorization (protocols[i].name,
(int)protocols[i].name_length);
}
#endif
XID
CheckAuthorization (
unsigned int name_length,
char *name,
unsigned int data_length,
char *data,
ClientPtr client,
char **reason)
{
int i;
struct stat buf;
static time_t lastmod = 0;
static Bool loaded = FALSE;
if (!authorization_file || stat(authorization_file, &buf))
{
if (lastmod != 0) {
lastmod = 0;
ShouldLoadAuth = TRUE;
}
}
else if (buf.st_mtime > lastmod)
{
lastmod = buf.st_mtime;
ShouldLoadAuth = TRUE;
}
if (ShouldLoadAuth)
{
int loadauth = LoadAuthorization();
if (loadauth > 0)
{
DisableLocalHost();
loaded = TRUE;
}
else if (loadauth == 0 || !loaded)
EnableLocalHost ();
}
if (name_length) {
for (i = 0; i < NUM_AUTHORIZATION; i++) {
if (protocols[i].name_length == name_length &&
memcmp (protocols[i].name, name, (int) name_length) == 0)
{
return (*protocols[i].Check) (data_length, data, client, reason);
}
*reason = "Protocol not supported by server\n";
}
} else *reason = "No protocol specified\n";
return (XID) ~0L;
}
void
ResetAuthorization (void)
{
int i;
for (i = 0; i < NUM_AUTHORIZATION; i++)
if (protocols[i].Reset)
(*protocols[i].Reset)();
ShouldLoadAuth = TRUE;
}
XID
AuthorizationToID (
unsigned short name_length,
char *name,
unsigned short data_length,
char *data)
{
int i;
for (i = 0; i < NUM_AUTHORIZATION; i++) {
if (protocols[i].name_length == name_length &&
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
protocols[i].ToID)
{
return (*protocols[i].ToID) (data_length, data);
}
}
return (XID) ~0L;
}
int
AuthorizationFromID (
XID id,
unsigned short *name_lenp,
char **namep,
unsigned short *data_lenp,
char **datap)
{
int i;
for (i = 0; i < NUM_AUTHORIZATION; i++) {
if (protocols[i].FromID &&
(*protocols[i].FromID) (id, data_lenp, datap)) {
*name_lenp = protocols[i].name_length;
*namep = protocols[i].name;
return 1;
}
}
return 0;
}
int
RemoveAuthorization (
unsigned short name_length,
char *name,
unsigned short data_length,
char *data)
{
int i;
for (i = 0; i < NUM_AUTHORIZATION; i++) {
if (protocols[i].name_length == name_length &&
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
protocols[i].Remove)
{
return (*protocols[i].Remove) (data_length, data);
}
}
return 0;
}
int
AddAuthorization (unsigned name_length, char *name, unsigned data_length, char *data)
{
int i;
for (i = 0; i < NUM_AUTHORIZATION; i++) {
if (protocols[i].name_length == name_length &&
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
protocols[i].Add)
{
return (*protocols[i].Add) (data_length, data, FakeClientID(0));
}
}
return 0;
}
#ifdef XCSECURITY
XID
GenerateAuthorization(
unsigned name_length,
char *name,
unsigned data_length,
char *data,
unsigned *data_length_return,
char **data_return)
{
int i;
for (i = 0; i < NUM_AUTHORIZATION; i++) {
if (protocols[i].name_length == name_length &&
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
protocols[i].Generate)
{
return (*protocols[i].Generate) (data_length, data,
FakeClientID(0), data_length_return, data_return);
}
}
return -1;
}
static unsigned long int next = 1;
static int
xdm_rand(void)
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
static void
xdm_srand(unsigned int seed)
{
next = seed;
}
void
GenerateRandomData (int len, char *buf)
{
static int seed;
int value;
int i;
seed += GetTimeInMillis();
xdm_srand (seed);
for (i = 0; i < len; i++)
{
value = xdm_rand ();
buf[i] ^= (value & 0xff00) >> 8;
}
}
#endif