From 0ce87af283067625c37a04bc3396c2289f1a83b3 Mon Sep 17 00:00:00 2001 From: gildea Date: Mon, 10 Jul 1995 21:18:07 +0000 Subject: authorization security fixes. CERT VU#12212. --- xc/lib/Xau/AuDispose.c | 7 +++-- xc/lib/Xau/AuFileName.c | 4 +-- xc/lib/Xau/AuRead.c | 8 ++++-- xc/lib/Xau/Xauth.h | 3 ++- xc/programs/Xserver/include/site.h | 4 +-- xc/programs/Xserver/os/xdmauth.c | 55 ++++++++++++++++++++++++++++++-------- xc/programs/xdm/auth.c | 52 +++++++++++++++++++++++++++++------ xc/programs/xdm/dm.c | 10 ++++--- xc/programs/xdm/dm.h | 5 +++- xc/programs/xdm/genauth.c | 34 ++++++++++++++++++----- xc/programs/xdm/protodpy.c | 6 +++-- xc/programs/xdm/xdm.man | 8 ++++-- xc/programs/xdm/xdmauth.c | 9 +++++-- 13 files changed, 160 insertions(+), 45 deletions(-) diff --git a/xc/lib/Xau/AuDispose.c b/xc/lib/Xau/AuDispose.c index fbfb4e0dc..3f9f7a368 100644 --- a/xc/lib/Xau/AuDispose.c +++ b/xc/lib/Xau/AuDispose.c @@ -1,4 +1,4 @@ -/* $XConsortium: AuDispose.c,v 1.3 91/01/08 15:08:21 gildea Exp $ */ +/* $XConsortium: AuDispose.c,v 1.4 94/04/17 20:15:41 gildea Exp gildea $ */ /* @@ -37,7 +37,10 @@ Xauth *auth; if (auth->address) (void) free (auth->address); if (auth->number) (void) free (auth->number); if (auth->name) (void) free (auth->name); - if (auth->data) (void) free (auth->data); + if (auth->data) { + (void) bzero (auth->data, auth->data_length); + (void) free (auth->data); + } free ((char *) auth); } return; diff --git a/xc/lib/Xau/AuFileName.c b/xc/lib/Xau/AuFileName.c index ca6b5b692..4018d849e 100644 --- a/xc/lib/Xau/AuFileName.c +++ b/xc/lib/Xau/AuFileName.c @@ -1,4 +1,4 @@ -/* $XConsortium: AuFileName.c,v 1.3 93/08/16 16:02:01 rws Exp $ */ +/* $XConsortium: AuFileName.c,v 1.4 94/04/17 20:15:42 rws Exp gildea $ */ /* @@ -28,12 +28,12 @@ in this Software without prior written authorization from the X Consortium. */ #include +#include char * XauFileName () { char *name, *malloc (), *getenv (); - char *strcat (), *strcpy (); static char *buf; static int bsize; #ifdef WIN32 diff --git a/xc/lib/Xau/AuRead.c b/xc/lib/Xau/AuRead.c index 968915a7c..7724b503f 100644 --- a/xc/lib/Xau/AuRead.c +++ b/xc/lib/Xau/AuRead.c @@ -1,4 +1,4 @@ -/* $XConsortium: AuRead.c,v 1.5 91/01/08 15:09:31 gildea Exp $ */ +/* $XConsortium: AuRead.c,v 1.6 94/04/17 20:15:44 gildea Exp gildea $ */ /* @@ -60,6 +60,7 @@ FILE *file; if (!data) return 0; if (fread (data, (int) sizeof (char), (int) len, file) != len) { + bzero (data, len); free (data); return 0; } @@ -101,7 +102,10 @@ FILE *auth_file; if (local.address) free (local.address); if (local.number) free (local.number); if (local.name) free (local.name); - if (local.data) free (local.data); + if (local.data) { + bzero (local.data, local.data_length); + free (local.data); + } return 0; } *ret = local; diff --git a/xc/lib/Xau/Xauth.h b/xc/lib/Xau/Xauth.h index 8e6ddce28..4356549af 100644 --- a/xc/lib/Xau/Xauth.h +++ b/xc/lib/Xau/Xauth.h @@ -1,4 +1,4 @@ -/* $XConsortium: Xauth.h,v 1.15 94/04/02 17:14:48 gildea Exp $ */ +/* $XConsortium: Xauth.h,v 1.16 94/04/17 20:15:46 gildea Exp gildea $ */ /* @@ -31,6 +31,7 @@ in this Software without prior written authorization from the X Consortium. #define _Xauth_h # include +# include # include diff --git a/xc/programs/Xserver/include/site.h b/xc/programs/Xserver/include/site.h index fa16d8d36..6a2d35790 100644 --- a/xc/programs/Xserver/include/site.h +++ b/xc/programs/Xserver/include/site.h @@ -1,4 +1,4 @@ -/* $XConsortium: site.h,v 1.23 93/09/25 17:47:08 rws Exp $ */ +/* $XConsortium: site.h,v 1.24 94/04/17 20:26:10 rws Exp gildea $ */ /************************************************************ Copyright (c) 1987 X Consortium @@ -63,7 +63,7 @@ SOFTWARE. * by the vendor. */ #ifndef VENDOR_RELEASE -#define VENDOR_RELEASE 6000 +#define VENDOR_RELEASE 6001 #endif /* diff --git a/xc/programs/Xserver/os/xdmauth.c b/xc/programs/Xserver/os/xdmauth.c index d3e61bce0..46ff6575f 100644 --- a/xc/programs/Xserver/os/xdmauth.c +++ b/xc/programs/Xserver/os/xdmauth.c @@ -1,4 +1,4 @@ -/* $XConsortium: xdmauth.c,v 1.12 94/03/28 16:25:58 gildea Exp $ */ +/* $XConsortium: xdmauth.c,v 1.13 94/04/17 20:27:08 gildea Exp gildea $ */ /* Copyright (c) 1988 X Consortium @@ -37,7 +37,9 @@ from the X Consortium. */ #include "X.h" +#include "Xtrans.h" #include "os.h" +#include "osdep.h" #include "dixstruct.h" #ifdef HASXDMAUTH @@ -145,7 +147,7 @@ XdmAuthenticationInit (cookie, cookie_len) { if (cookie_len > 2 + 2 * 8) cookie_len = 2 + 2 * 8; - HexToBinary (cookie + 2, privateKey.data, cookie_len - 2); + HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2); } else { @@ -186,6 +188,7 @@ static long clockOffset; static Bool gotClock; #define TwentyMinutes (20 * 60) +#define TwentyFiveMinutes (25 * 60) static Bool XdmClientAuthCompare (a, b) @@ -237,7 +240,7 @@ XdmClientAuthTimeout (now) for (client = xdmClients; client; client=next) { next = client->next; - if (abs (now - client->time) > TwentyMinutes) + if (abs (now - client->time) > TwentyFiveMinutes) { if (prev) prev->next = next; @@ -251,14 +254,16 @@ XdmClientAuthTimeout (now) } static XdmClientAuthPtr -XdmAuthorizationValidate (plain, length, rho, reason) - char *plain; +XdmAuthorizationValidate (plain, length, rho, xclient, reason) + unsigned char *plain; int length; XdmAuthKeyPtr rho; + ClientPtr xclient; char **reason; { XdmClientAuthPtr client, existing; long now; + int i; if (length != (192 / 8)) { if (reason) @@ -276,6 +281,34 @@ XdmAuthorizationValidate (plain, length, rho, reason) *reason = "Invalid XDM-AUTHORIZATION-1 key value"; return NULL; } + for (i = 18; i < 24; i++) + if (plain[i] != 0) { + xfree (client); + if (reason) + *reason = "Invalid XDM-AUTHORIZATION-1 key value"; + return NULL; + } + if (xclient) { + int family, addr_len; + Xtransaddr *addr; + + if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn, + &family, &addr_len, &addr) == 0 + && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) { +#ifdef TCPCONN + if (family == FamilyInternet && + memcmp((char *)addr, client->client, 4) != 0) { + xfree (client); + xfree (addr); + if (reason) + *reason = "Invalid XDM-AUTHORIZATION-1 key value"; + return NULL; + + } +#endif + xfree (addr); + } + } now = time(0); if (!gotClock) { @@ -360,17 +393,17 @@ XdmCheckCookie (cookie_length, cookie, xclient, reason) { XdmAuthorizationPtr auth; XdmClientAuthPtr client; - char *plain; + unsigned char *plain; /* Auth packets must be a multiple of 8 bytes long */ if (cookie_length & 7) return (XID) -1; - plain = (char *) xalloc (cookie_length); + plain = (unsigned char *) xalloc (cookie_length); if (!plain) return (XID) -1; for (auth = xdmAuth; auth; auth=auth->next) { XdmcpUnwrap (cookie, &auth->key, plain, cookie_length); - if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, reason)) + if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason)) { client->next = xdmClients; xdmClients = client; @@ -410,14 +443,14 @@ char *cookie; { XdmAuthorizationPtr auth; XdmClientAuthPtr client; - char *plain; + unsigned char *plain; - plain = (char *) xalloc (cookie_length); + plain = (unsigned char *) xalloc (cookie_length); if (!plain) return (XID) -1; for (auth = xdmAuth; auth; auth=auth->next) { XdmcpUnwrap (cookie, &auth->key, plain, cookie_length); - if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL)) + if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL)) { xfree (client); xfree (cookie); diff --git a/xc/programs/xdm/auth.c b/xc/programs/xdm/auth.c index c01cde8fc..e14c0c117 100644 --- a/xc/programs/xdm/auth.c +++ b/xc/programs/xdm/auth.c @@ -1,4 +1,4 @@ -/* $XConsortium: auth.c,v 1.57 94/10/07 19:46:21 converse Exp kaleb $ */ +/* $XConsortium: auth.c,v 1.58 94/11/21 18:33:11 kaleb Exp gildea $ */ /* Copyright (c) 1988 X Consortium @@ -42,6 +42,12 @@ from the X Consortium. #include #include #include + +#include +#ifdef X_NOT_STDC_ENV +extern int errno; +#endif + #include #ifndef ESIX # include @@ -87,7 +93,7 @@ extern Xauth *MitGetAuth (); extern int XdmInitAuth (); extern Xauth *XdmGetAuth (); #ifdef XDMCP -extern int XdmGetXdmcpAuth (); +extern void XdmGetXdmcpAuth (); #else #define XdmGetXdmcpAuth NULL #endif @@ -108,7 +114,7 @@ struct AuthProtocol { char *name; int (*InitAuth)(); Xauth *(*GetAuth)(); - int (*GetXdmcpAuth)(); + void (*GetXdmcpAuth)(); int inited; }; @@ -265,6 +271,9 @@ CleanUpFileName (src, dst, len) *dst = '\0'; } +static char authdir1[] = "authdir"; +static char authdir2[] = "authfiles"; + static MakeServerAuthFile (d) struct display *d; @@ -276,13 +285,16 @@ MakeServerAuthFile (d) #define NAMELEN 255 #endif char cleanname[NAMELEN]; + int r; + struct stat statb; if (d->clientAuthFile && *d->clientAuthFile) len = strlen (d->clientAuthFile) + 1; else { CleanUpFileName (d->name, cleanname, NAMELEN - 8); - len = strlen (authDir) + strlen (cleanname) + 12; + len = strlen (authDir) + strlen (authdir1) + strlen (authdir2) + + strlen (cleanname) + 14; } if (d->authFile) free (d->authFile); @@ -293,7 +305,31 @@ MakeServerAuthFile (d) strcpy (d->authFile, d->clientAuthFile); else { - sprintf (d->authFile, "%s/A%s-XXXXXX", authDir, cleanname); + sprintf (d->authFile, "%s/%s", authDir, authdir1); + r = stat(d->authFile, &statb); + if (r == 0) { + if (statb.st_uid != 0) + (void) chown(d->authFile, 0, statb.st_gid); + if ((statb.st_mode & 0077) != 0) + (void) chmod(d->authFile, statb.st_mode & 0700); + } else { + if (errno == ENOENT) + r = mkdir(d->authFile, 0700); + if (r < 0) { + free (d->authFile); + d->authFile = NULL; + return FALSE; + } + } + sprintf (d->authFile, "%s/%s/%s", authDir, authdir1, authdir2); + r = mkdir(d->authFile, 0700); + if (r < 0 && errno != EEXIST) { + free (d->authFile); + d->authFile = NULL; + return FALSE; + } + sprintf (d->authFile, "%s/%s/%s/A%s-XXXXXX", + authDir, authdir1, authdir2, cleanname); (void) mktemp (d->authFile); } return TRUE; @@ -600,10 +636,10 @@ writeAuth (file, auth) FILE *file; Xauth *auth; { -#if 0 /* too verbose */ + if (debugLevel >= 15) { /* normally too verbose */ Debug ("writeAuth: doWrite = %d\n", doWrite); dumpAuth (auth); /* does Debug only */ -#endif + } if (doWrite) XauWriteAuth (file, auth); } @@ -745,7 +781,7 @@ DefineSelf (fd, file, auth) if (IA_SIN(&ifaddr)->sin_addr.s_addr == htonl(0x7f000001) ) continue; - writeAddr (FamilyInternet, 4, &(IA_SIN(&ifaddr)->sin_addr), file, auth); + writeAddr (FamilyInternet, 4, (char *)&(IA_SIN(&ifaddr)->sin_addr), file, auth); } close(ipfd); diff --git a/xc/programs/xdm/dm.c b/xc/programs/xdm/dm.c index c00f4ed1d..d68b0d502 100644 --- a/xc/programs/xdm/dm.c +++ b/xc/programs/xdm/dm.c @@ -1,4 +1,4 @@ -/* $XConsortium: dm.c,v 1.69 94/03/30 21:27:40 gildea Exp $ */ +/* $XConsortium: dm.c,v 1.70 94/04/17 20:03:36 gildea Exp gildea $ */ /* Copyright (c) 1988 X Consortium @@ -151,9 +151,11 @@ char **argv; if (debugLevel == 0) InitErrorLog (); - /* Clean up any old Authorization files */ - sprintf(cmdbuf, "/bin/rm -f %s/A*", authDir); - system(cmdbuf); + if (nofork_session == 0) { + /* Clean up any old Authorization files */ + sprintf(cmdbuf, "/bin/rm -f %s/authdir/authfiles/A*", authDir); + system(cmdbuf); + } #ifdef XDMCP init_session_id (); diff --git a/xc/programs/xdm/dm.h b/xc/programs/xdm/dm.h index 8430cd548..e728089bf 100644 --- a/xc/programs/xdm/dm.h +++ b/xc/programs/xdm/dm.h @@ -1,4 +1,4 @@ -/* $XConsortium: dm.h,v 1.64 94/10/07 19:43:37 converse Exp kaleb $ */ +/* $XConsortium: dm.h,v 1.65 94/12/12 15:35:36 kaleb Exp gildea $ */ /* Copyright (c) 1988 X Consortium @@ -323,6 +323,9 @@ extern void SetUserAuthorization(); extern void RemoveUserAuthorization(); extern void CleanUpFileName(); +/* in protodpy.c */ +extern void DisposeProtoDisplay(); + /* * CloseOnFork flags */ diff --git a/xc/programs/xdm/genauth.c b/xc/programs/xdm/genauth.c index 52ca80bb5..2c7398a77 100644 --- a/xc/programs/xdm/genauth.c +++ b/xc/programs/xdm/genauth.c @@ -1,4 +1,4 @@ -/* $XConsortium: genauth.c,v 1.21 94/11/21 18:33:11 kaleb Exp kaleb $ */ +/* $XConsortium: genauth.c,v 1.22 94/11/21 19:58:57 kaleb Exp gildea $ */ /* Copyright (c) 1988 X Consortium @@ -129,6 +129,28 @@ InitXdmcpWrapper () #endif +#ifndef HASXDMAUTH +/* A random number generator that is more unpredictable + than that shipped with some systems. + This code is taken from the C standard. */ + +static unsigned long int next = 1; + +static int +xdm_rand() +{ + next = next * 1103515245 + 12345; + return (unsigned int)(next/65536) % 32768; +} + +static void +xdm_srand(seed) + unsigned int seed; +{ + next = seed; +} +#endif /* no HASXDMAUTH */ + GenerateAuthData (auth, len) char *auth; int len; @@ -140,8 +162,8 @@ int len; struct timeval now; X_GETTIMEOFDAY (&now); - ldata[0] = now.tv_sec; - ldata[1] = now.tv_usec; + ldata[0] = now.tv_usec; + ldata[1] = now.tv_sec; } #else { @@ -183,11 +205,11 @@ int len; int i; seed = (ldata[0]) + (ldata[1] << 16); - srand (seed); + xdm_srand (seed); for (i = 0; i < len; i++) { - value = rand (); - auth[i] = value & 0xff; + value = xdm_rand (); + auth[i] = (value & 0xff00) >> 8; } value = len; if (value > sizeof (key)) diff --git a/xc/programs/xdm/protodpy.c b/xc/programs/xdm/protodpy.c index 1c6e9bce2..5911a4a86 100644 --- a/xc/programs/xdm/protodpy.c +++ b/xc/programs/xdm/protodpy.c @@ -1,5 +1,5 @@ /* - * $XConsortium: protodpy.c,v 1.13 94/01/17 19:09:55 rws Exp $ + * $XConsortium: protodpy.c,v 1.14 94/04/17 20:03:42 rws Exp gildea $ * Copyright (c) 1989 X Consortium @@ -142,6 +142,7 @@ NewProtoDisplay (address, addrlen, displayNumber, return pdpy; } +void DisposeProtoDisplay (pdpy) struct protoDisplay *pdpy; { @@ -160,11 +161,12 @@ DisposeProtoDisplay (pdpy) prev->next = pdpy->next; else protoDisplays = pdpy->next; - XdmcpDisposeARRAY8 (&pdpy->connectionAddress); + bzero(&pdpy->key, sizeof(pdpy->key)); if (pdpy->fileAuthorization) XauDisposeAuth (pdpy->fileAuthorization); if (pdpy->xdmcpAuthorization) XauDisposeAuth (pdpy->xdmcpAuthorization); + XdmcpDisposeARRAY8 (&pdpy->connectionAddress); free ((char *) pdpy->address); free ((char *) pdpy); } diff --git a/xc/programs/xdm/xdm.man b/xc/programs/xdm/xdm.man index bd7df61ab..047e6e574 100644 --- a/xc/programs/xdm/xdm.man +++ b/xc/programs/xdm/xdm.man @@ -1,4 +1,4 @@ -.\" $XConsortium: xdm.man,v 1.38 94/10/18 17:47:33 gildea Exp gildea $ +.\" $XConsortium: xdm.man,v 1.39 95/05/04 00:03:58 gildea Exp gildea $ .\" Copyright (c) 1988, 1994 X Consortium .\" .\" Permission is hereby granted, free of charge, to any person obtaining @@ -290,10 +290,12 @@ uses file locking to keep multiple display managers from running amok. On System V, this uses the \fIlockf\fP library call, while on BSD it uses \fIflock.\fP .IP "\fBDisplayManager.authDir\fP" -This names a directory in which +This names a directory under which .I xdm stores authorization files while initializing the session. The default value is \fI/lib/X11/xdm.\fP +Can be overridden for specific displays by +DisplayManager.\fIDISPLAY\fP.authFile. .IP \fBDisplayManager.autoRescan\fP This boolean controls whether .I xdm @@ -513,6 +515,8 @@ to the server, using the \fB\-auth\fP server command line option. It should be kept in a directory which is not world-writable as it could easily be removed, disabling the authorization mechanism in the server. +If not specified, a name is generated from DisplayManager.authDir and +the name of the display. .IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.authComplain\fP" If set to ``false,'' disables the use of the \fBunsecureGreeting\fP in the login window. diff --git a/xc/programs/xdm/xdmauth.c b/xc/programs/xdm/xdmauth.c index 83ce04520..44b4f4251 100644 --- a/xc/programs/xdm/xdmauth.c +++ b/xc/programs/xdm/xdmauth.c @@ -1,4 +1,4 @@ -/* $XConsortium: xdmauth.c,v 1.11 94/01/09 18:07:19 gildea Exp $ */ +/* $XConsortium: xdmauth.c,v 1.12 94/04/17 20:03:50 gildea Exp gildea $ */ /* Copyright (c) 1988 X Consortium @@ -151,6 +151,7 @@ XdmGetAuth (namelen, name) #ifdef XDMCP +void XdmGetXdmcpAuth (pdpy,authorizationNameLen, authorizationName) struct protoDisplay *pdpy; unsigned short authorizationNameLen; @@ -251,7 +252,8 @@ XdmGetKey (pdpy, displayID) { if (line[0] == '#' || sscanf (line, "%s %s", id, key) != 2) continue; - Debug ("Key entry \"%s\" \"%s\"\n", id, key); + bzero(line, sizeof(line)); + Debug ("Key entry for \"%s\" %d bytes\n", id, strlen(key)); if (strlen (id) == displayID->length && !strncmp (id, (char *)displayID->data, displayID->length)) { @@ -263,10 +265,13 @@ XdmGetKey (pdpy, displayID) key[keylen++] = '\0'; pdpy->key.data[0] = '\0'; memmove( pdpy->key.data + 1, key, 7); + bzero(key, sizeof(key)); fclose (keys); return TRUE; } } + bzero(line, sizeof(line)); + bzero(key, sizeof(key)); fclose (keys); return FALSE; } -- cgit v1.2.3