Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do I generate valid XDM-AUTHORIZATION-1 ?

345 views
Skip to first unread message

Nick Sayer

unread,
Jan 4, 1993, 8:54:23 PM1/4/93
to
Once again, X11R5, SunOS 4.1.3, ELC.

Through a little trial and lots of error, I've managed to get xdm to use
XDM-AUTHORIZATION-1 with my X terminal (an Xkernel sun3. I had to set
up a keyFile and add a -cookie argument to the sun3's Xsun).
Now for my ELC itself. If I attempt to create a random hex string
(like an MIT-MAGIC-COOKIE-1) and call that an XDM-AUTHORIZATION-1,
it fails (Xlib's 'not authorized' error). If I run xdm on the console
frame buffer, it will generate an auth file with BOTH
MIT-MAGIC-COOKIE-1 and XDM-AUTHORIZATION-1. Which is fine. If I
remove the xauth file and recreate it with just the XDM-AUTHORIZATION-1
lines XDM generated, that's fine too. If I then save one of these auth
cookies XDM generated, then manually start Xsun up with -auth pointing to
a file with the previously generated (by xdm) XDM-AUTHORIZATION-1,
that works. If I try to set up an xauth file with an XDM-AUTHORIZATION-1
made originally for any other server, that doesn't work.

So there appears to be some component of the XDM-AUTHORIZATION-1
widget that is dependent on the display ID. This is contrary to
the Xsecurity man page:

XDM-AUTHORIZATION-1
For sites in the US, Release 5 contains a DES-based
access control mechanism called XDM-AUTHORIZATION-1.
It is similar in usage to MIT-MAGIC-COOKIE-1 in that a
key is stored in the .Xauthority file and is shared
with the X server. However, this key consists of two
parts - a 56 bit DES encryption key and 64 bits of ran-
dom data used as the authenticator.

When connecting to the X server, the application gen-
erates 192 bits of data by combining the current time
in seconds (since 00:00 1/1/1970 GMT) along with 48
bits of "identifier". For TCP/IP connections, the
identifier is the address plus port number; for local
connections it is the process ID and 32 bits to form a
unique id (in case multiple connections to the same
server are made from a single process). This 192 bit
packet is then encrypted using the DES key and sent to
the X server, which is able to verify if the requestor
is authorized to connect by decrypting with the same
DES key and validating the authenticator and additional
data. This system is useful in many environments where
host-based access control is inappropriate and where
network security cannot be ensured.

It doesn't say anything special about one half of the key (56 bits really,
but the last byte is ignored), and the other half is totally random.

So, how do I generate valid XDM-AUTHORIZATION-1 keys for use in
conjunction with xinit?

By the way, is there a way around the -cookie / keyFile business to get
xdm to use XDM-AUTHORIZATION-1 with an XDMCP display?

--
Nick Sayer <mra...@quack.sac.ca.us> | "Do you have to keep tapping like that,
N6QQQ @ N0ARY.#NOCAL.CA.USA.NOAM | you bloated sack of protoplasm?!"
+1 408 249 9630, log in as 'guest' |
PGP 2.1 public key on request | -- Captain Hoek

Mike Glendinning

unread,
Jan 9, 1993, 12:36:03 PM1/9/93
to
It is possible to add hexkeys for XDM-AUTHORIZATION-1 using the
standard 'xauth' command. The trick is to leave the 8 most
significant bits of the DES key as zero.

As you pointed out, the 128-bit hexkey for XDM-AUTHORIZATION-1
is composed of two parts: 64 bits of random data and a 56-bit
DES key. The 56-bit key is stored in the lower end of a 64-bit
field. You specify the full 128 bits to 'xauth' with the
random data first.

For example, the following 'xauth' command generates a valid
hexkey for XDM-AUTHORIZATION-1:

xauth add :0 XDM-AUTHORIZATION-1 aabbccddeeffaabb00aabbccddeeffaa

^^ zeros!!

Note that the only "win" with XDM-AUTHORIZATION-1 as opposed to
MIT-MAGIC-COOKIE-1 is that the key is not transmitted
in the X connection information by each client and thus you
are not prone to networking snooping (people with PC's on
your Ethernet!). If you have a secure way of transmitting the
128-bit hexkey from the server machine to the client machine,
then great! Otherwise, there is no real benefit. Unfortunately,
since the key is stored in the Unix filesystem, you're limited by
the security provided there. And if you are using NFS, then you might
as well forget it anyway, as NFS provides almost No File Security!

Also, beware of trying to use *only* XDM-AUTHORIZATION-1. If you
do this, then R4 based clients will not be able to connect as
they don't know about XDM-AUTHORIZATION-1. Always add a key for
MIT-MAGIC-COOKIE-1 as well. You will also potentially get the same
problem with clients from other sources that contain their own Xlib
that doesn't know about XDM-AUTHORIZATION-1.

Personally, I have modified 'xauth' to add a "create" command
which will generate random hexkeys automatically. This is
much easier than getting "ksh" or "perl" to generate a random
cookie for use by the 'xauth' "add" command. With my changes
(included below), you can just say:

xauth create :0 && xauth create `hostname`:0

in order to generate a full set of authorization information for
display number 0 on the local host. The technique used is exactly
the same as the one used by 'xdm' (in fact, I borrowed the code from
there). If you just want to generate a random key for a particular
protocol, you can say something like:

xauth create :0 MIT-MAGIC-COOKIE-1

The abbreviation "." for "MIT-MAGIC-COOKIE-1" is supported.

I would appreciate some comments on these patches, as I am
rather surprised that nobody has done it before. Of course,
the 'xauth' "add" command is required, but isn't "create"
more useful?

By the way, these patches are for the X11R5pl21 version
of 'xauth'.

-Mike Glendinning, Ingres UK (mi...@ingres.com).


*** Imakefile.orig Thu Jan 7 16:46:53 1993
--- Imakefile Fri Jan 8 10:26:25 1993
***************
*** 1,9 ****
XCOMM $XConsortium: Imakefile,v 1.14 91/07/16 23:06:17 gildea Exp $
DEPLIBS = $(DEPXAUTHLIB) $(DEPXMULIB)
LOCAL_LIBRARIES = $(XAUTHLIB) $(XMULIB)
SRCS = xauth.c gethost.c process.c parsedpy.c
OBJS = xauth.o gethost.o process.o parsedpy.o
! DEFINES = ConnectionFlags $(SIGNAL_DEFINES)

ComplexProgramTarget(xauth)

--- 1,14 ----
XCOMM $XConsortium: Imakefile,v 1.14 91/07/16 23:06:17 gildea Exp $
+
+ #ifdef HasXdmAuth
+ XDMAUTH_DEFINES = -DHASXDMAUTH
+ #endif
+
DEPLIBS = $(DEPXAUTHLIB) $(DEPXMULIB)
LOCAL_LIBRARIES = $(XAUTHLIB) $(XMULIB)
SRCS = xauth.c gethost.c process.c parsedpy.c
OBJS = xauth.o gethost.o process.o parsedpy.o
! DEFINES = ConnectionFlags $(SIGNAL_DEFINES) $(XDMAUTH_DEFINES)

ComplexProgramTarget(xauth)

*** process.c.orig Thu Jan 7 16:46:53 1993
--- process.c Fri Jan 8 11:52:46 1993
***************
*** 40,47 ****
#define DEFAULT_PROTOCOL "MIT-MAGIC-COOKIE-1"
#endif

! #define SECURERPC "SUN-DES-1"

#define XAUTH_DEFAULT_RETRIES 10 /* number of competitors we expect */
#define XAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */
#define XAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */
--- 40,56 ----
#define DEFAULT_PROTOCOL "MIT-MAGIC-COOKIE-1"
#endif

! #define MITMAGICCOOKIE "MIT-MAGIC-COOKIE-1"
! #define XDMAUTHORIZATION "XDM-AUTHORIZATION-1"
! #define SECURERPC "SUN-DES-1"

+ #ifndef DEFAULT_RANDOM_FILE
+ #define DEFAULT_RANDOM_FILE "/dev/mem"
+ #endif
+
+ #define FILE_LIMIT 1024 /* no more than this many buffers */
+ #define AUTH_DATA_LEN 16 /* bytes of authorization data */
+
#define XAUTH_DEFAULT_RETRIES 10 /* number of competitors we expect */
#define XAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */
#define XAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */
***************
*** 86,96 ****

static int do_list(), do_merge(), do_extract(), do_add(), do_remove();
static int do_help(), do_source(), do_info(), do_exit();
! static int do_quit(), do_questionmark();

static CommandTable command_table[] = { /* table of known commands */
{ "add", 2, 3, do_add,
"add dpyname protoname hexkey add entry" },
{ "exit", 3, 4, do_exit,
"exit save changes and exit program" },
{ "extract", 3, 7, do_extract,
--- 95,107 ----

static int do_list(), do_merge(), do_extract(), do_add(), do_remove();
static int do_help(), do_source(), do_info(), do_exit();
! static int do_quit(), do_questionmark(), do_create();

static CommandTable command_table[] = { /* table of known commands */
{ "add", 2, 3, do_add,
"add dpyname protoname hexkey add entry" },
+ { "create", 2, 6, do_create,
+ "create dpyname [protoname] create random entry" },
{ "exit", 3, 4, do_exit,
"exit save changes and exit program" },
{ "extract", 3, 7, do_extract,
***************
*** 1091,1096 ****
--- 1102,1235 ----
return errors;
}

+ #ifdef HASXDMAUTH
+ static longtochars (l, c)
+ long l;
+ unsigned char *c;
+ {
+ c[0] = (l >> 24) & 0xff;
+ c[1] = (l >> 16) & 0xff;
+ c[2] = (l >> 8) & 0xff;
+ c[3] = l & 0xff;
+ }
+
+ static int sumfile (name, sum)
+ char *name;
+ long sum[2];
+ {
+ long buf[1024*2];
+ int cnt;
+ int fd;
+ int loops;
+ int reads;
+ int i;
+
+ fd = open (name, 0);
+ if (fd < 0)
+ return 0;
+ reads = FILE_LIMIT;
+ while ((cnt = read (fd, buf, sizeof (buf))) > 0 && --reads > 0) {
+ loops = cnt / (2 * sizeof (long));
+ for (i = 0; i < loops; i += 2) {
+ sum[0] += buf[i];
+ sum[1] += buf[i+1];
+ }
+ }
+ close (fd);
+ return 1;
+ }
+ #endif
+
+ static genauth(authstr, len)
+ char *authstr;
+ int len;
+ {
+ long ldata[2];
+
+ #ifdef ITIMER_REAL
+ {
+ struct timeval now;
+ struct timezone zone;
+ gettimeofday (&now, &zone);
+ ldata[0] = now.tv_sec;
+ ldata[1] = now.tv_usec;
+ }
+ #else
+ {
+ long time ();
+
+ ldata[0] = time ((long *) 0);
+ ldata[1] = getpid ();
+ }
+ #endif
+
+ #ifdef HASXDMAUTH
+ {
+ typedef unsigned char auth_cblock[8]; /* block size */
+ typedef struct auth_ks_struct { auth_cblock _; }
+ auth_wrapper_schedule[16];
+
+ int i, bit, authi;
+ char *authc;
+ auth_wrapper_schedule schedule;
+ unsigned char data[8];
+ static unsigned char key[8];
+ static int xdmcpauthinited = 0;
+
+ longtochars (ldata[0], data+0);
+ longtochars (ldata[1], data+4);
+ if (!xdmcpauthinited) {
+ char *name, *getenv();
+ long sum[2];
+ unsigned char tmpkey[8];
+
+ name = getenv ("RANDOM_FILE");
+ if (name == NULL)
+ name = DEFAULT_RANDOM_FILE;
+ if (!sumfile (name, sum)) {
+ sum[0] = time ((long *) 0);
+ sum[1] = time ((long *) 0);
+ }
+ longtochars (sum[0], tmpkey+0);
+ longtochars (sum[1], tmpkey+4);
+ tmpkey[0] = 0;
+ _XdmcpWrapperToOddParity (tmpkey, key);
+
+ xdmcpauthinited = 1;
+ }
+ _XdmcpAuthSetup (key, schedule);
+ for (i = 0; i < len; i++) {
+ authi = 0;
+ for (bit = 1; bit < 256; bit <<= 1) {
+ _XdmcpAuthDoIt (data, data, schedule, 1);
+ if (data[0] + data[1] & 0x4)
+ authi |= bit;
+ }
+ authc = hex_table[authi & 0xff];
+ authstr[i*2] = authc[0];
+ authstr[i*2+1] = authc[1];
+ }
+ authstr[len*2] = '\0';
+ }
+ #else
+ {
+ int i, seed, value;
+ char *authc;
+
+ seed = (ldata[0]) + (ldata[1] << 16);
+ srand (seed);
+ for (i = 0; i < len; i++)
+ {
+ value = rand ();
+ authc = hex_table[value & 0xff];
+ authstr[i*2] = authc[0];
+ authstr[i*2+1] = authc[1];
+ }
+ authstr[len*2] = '\0';
+ }
+ #endif
+ }
+
/* ARGSUSED */
static int remove_entry (inputfilename, lineno, auth, data)
char *inputfilename;
***************
*** 1466,1471 ****
--- 1605,1691 ----

xauth_modified = True;
return 0;
+ }
+
+ /*
+ * create displayname protocolname
+ */
+ static int do_create (inputfilename, lineno, argc, argv)
+ char *inputfilename;
+ int lineno;
+ int argc;
+ char **argv;
+ {
+ int p1, p2;
+ char *dpyname;
+ char *protoname;
+ char authstr[AUTH_DATA_LEN*2+1];
+ char *addcmds[5];
+ int errors;
+
+ if (argc < 2 || argc > 3 || !argv[1]) {
+ prefix (inputfilename, lineno);
+ badcommandline (argv[0]);
+ return 1;
+ }
+
+ dpyname = argv[1];
+
+ addcmds[0] = "create"; /* OK since do_add won't check! */
+ addcmds[1] = dpyname;
+ addcmds[2] = ""; /* protocol filled-in later on */
+ addcmds[3] = authstr;
+ addcmds[4] = NULL;
+
+ if (argc == 3 && argv[2]) {
+ protoname = argv[2];
+ if (strcmp (protoname, DEFAULT_PROTOCOL_ABBREV) == 0) {
+ protoname = DEFAULT_PROTOCOL;
+ }
+ p1 = (strcmp (protoname, MITMAGICCOOKIE) == 0);
+ #ifdef HASXDMAUTH
+ p2 = (strcmp (protoname, XDMAUTHORIZATION) == 0);
+ #else
+ p2 = 0;
+ #endif
+ if (p1 || p2) {
+ genauth(authstr, AUTH_DATA_LEN);
+ if (p2) {
+ authstr[16] = '0';
+ authstr[17] = '0';
+ }
+ addcmds[2] = protoname;
+ errors = do_add (inputfilename, lineno, 4, addcmds);
+ }
+ else {
+ prefix (inputfilename, lineno);
+ fprintf (stderr,
+ "don't know how to create protocol %s\n", protoname);
+ return 1;
+ }
+ }
+ else {
+
+ /*
+ * by default, generate both MIT-MAGIC-COOKIE-1 and XDM-AUTHORIZATION-1
+ */
+ genauth(authstr, AUTH_DATA_LEN);
+ addcmds[2] = MITMAGICCOOKIE;
+ errors = do_add (inputfilename, lineno, 4, addcmds);
+ #ifdef HASXDMAUTH
+ if (errors)
+ return errors;
+
+ genauth(authstr, AUTH_DATA_LEN);
+ authstr[16] = '0';
+ authstr[17] = '0';
+ addcmds[2] = XDMAUTHORIZATION;
+ errors = do_add (inputfilename, lineno, 4, addcmds);
+ #endif
+
+ }
+
+ return errors;
}

/*
*** xauth.man.orig Thu Jan 7 16:46:54 1993
--- xauth.man Fri Jan 8 09:35:28 1993
***************
*** 57,62 ****
--- 57,70 ----
A protocol name consisting of just a
single period is treated as an abbreviation for \fIMIT-MAGIC-COOKIE-1\fP.
.TP 8
+ .B "create \fIdisplayname \fR[\fIprotocolname\fP]"
+ An authorization entry for the indicated display using the given protocol
+ is created using a random number generator and added to the authorization file.
+ A protocol name consisting of just a
+ single period is treated as an abbreviation for \fIMIT-MAGIC-COOKIE-1\fP.
+ If the protocol name is not specified, then authorization entries are
+ created for all supported protocols.
+ .TP 8
.B "[n]extract \fIfilename displayname..."
Authorization entries for each of the specified displays are written to the
indicated file. If the \fInextract\fP command is used, the entries are written
***************
*** 111,117 ****
.B "?"
A short list of the valid commands is printed on the standard output.
.SH "DISPLAY NAMES"
! Display names for the \fIadd\fP, \fI[n]extract\fP, \fI[n]list\fP,
\fI[n]merge\fP, and \fIremove\fP commands use the same format as the
DISPLAY environment variable and the common \fI-display\fP command line
argument. Display-specific information (such as the screen number)
--- 119,125 ----
.B "?"
A short list of the valid commands is printed on the standard output.
.SH "DISPLAY NAMES"
! Display names for the \fIadd\fP, \fIcreate\fP, \fI[n]extract\fP, \fI[n]list\fP,
\fI[n]merge\fP, and \fIremove\fP commands use the same format as the
DISPLAY environment variable and the common \fI-display\fP command line
argument. Display-specific information (such as the screen number)
***************
*** 153,157 ****
Copyright 1989, Massachusetts Institute of Technology.
.br
See \fIX(1)\fP for a full statement of rights and permissions.
! .SH AUTHOR
Jim Fulton, MIT X Consortium
--- 161,167 ----
Copyright 1989, Massachusetts Institute of Technology.
.br
See \fIX(1)\fP for a full statement of rights and permissions.
! .SH AUTHORS
Jim Fulton, MIT X Consortium
+ .br
+ Mike Glendinning, Ingres Corporation

0 new messages