summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-25 19:29:12 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-25 19:29:12 +0000
commitca56bbdb0d398371332467534deaefdb77883bd7 (patch)
treec2d0009eccfd0d8d2e7cae9932885a7a0a6699bc
parent19bd1c5e3910088ac0e92ca005427192a223c8a0 (diff)
XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folksxf86-4_3_99_16
-rw-r--r--access.c177
-rw-r--r--auth.c160
-rw-r--r--choose.c32
-rw-r--r--chooser.c135
-rw-r--r--config/Xaccess24
-rw-r--r--config/Xresources.cpp20
-rw-r--r--dm.c19
-rw-r--r--dm.h22
-rw-r--r--dm_auth.h15
-rw-r--r--dpylist.c3
-rw-r--r--genauth.c499
-rw-r--r--greet.h28
-rw-r--r--greeter/Login.c10
-rw-r--r--greeter/Login.h12
-rw-r--r--greeter/greet.c29
-rw-r--r--greeter/verify.c47
-rw-r--r--mitauth.c12
-rw-r--r--netaddr.c41
-rw-r--r--resource.c92
-rw-r--r--server.c20
-rw-r--r--session.c202
-rw-r--r--socket.c461
-rw-r--r--streams.c29
-rw-r--r--xdm.man.cpp138
-rw-r--r--xdmauth.c68
-rw-r--r--xdmcp.c428
26 files changed, 2170 insertions, 553 deletions
diff --git a/access.c b/access.c
index e6984b1..567129e 100644
--- a/access.c
+++ b/access.c
@@ -2,6 +2,7 @@
* $Xorg: access.c,v 1.5 2001/02/09 02:05:40 xorgcvs Exp $
*
Copyright 1990, 1998 The Open Group
+Copyright 2002 Sun Microsystems, Inc. All rights reserved.
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@@ -19,14 +20,14 @@ OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-Except as contained in this notice, the name of The Open Group shall not be
+Except as contained in this notice, the name of a copyright holder shall not be
used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
+in this Software without prior written authorization from the copyright holder.
*
* Author: Keith Packard, MIT X Consortium
*/
-/* $XFree86: xc/programs/xdm/access.c,v 3.10 2002/12/10 23:36:43 tsi Exp $ */
+/* $XFree86: xc/programs/xdm/access.c,v 3.12 2003/07/18 15:53:28 tsi Exp $ */
/*
* Access control for XDMCP - keep a database of allowable display addresses
@@ -53,12 +54,15 @@ in this Software without prior written authorization from The Open Group.
#define CHOOSER_STRING "CHOOSER"
#define BROADCAST_STRING "BROADCAST"
#define NOBROADCAST_STRING "NOBROADCAST"
+#define LISTEN_STRING "LISTEN"
+#define WILDCARD_STRING "*"
#define HOST_ALIAS 0
#define HOST_ADDRESS 1
#define HOST_BROADCAST 2
#define HOST_CHOOSER 3
#define HOST_NOBROADCAST 4
+#define HOST_ANYADDR 5
typedef struct _hostEntry {
struct _hostEntry *next;
@@ -67,11 +71,13 @@ typedef struct _hostEntry {
char *aliasName;
ARRAY8 hostAddress;
} entry;
+ int hopCount;
} HostEntry;
#define DISPLAY_ALIAS 0
#define DISPLAY_PATTERN 1
#define DISPLAY_ADDRESS 2
+#define DISPLAY_LISTEN 3
typedef struct _displayEntry {
struct _displayEntry *next;
@@ -101,11 +107,37 @@ getLocalAddress (void)
if (!haveLocalAddress)
{
+#if defined(IPv6) && defined(AF_INET6)
+ struct addrinfo *ai;
+
+ if (getaddrinfo(localHostname(), NULL, NULL, &ai) != 0) {
+ XdmcpAllocARRAY8 (&localAddress, 4);
+ localAddress.data[0] = 127;
+ localAddress.data[1] = 0;
+ localAddress.data[2] = 0;
+ localAddress.data[3] = 1;
+ } else {
+ if (ai->ai_addr->sa_family == AF_INET) {
+ XdmcpAllocARRAY8 (&localAddress, sizeof(struct in_addr));
+ memcpy(localAddress.data,
+ &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
+ sizeof(struct in_addr));
+ } else if (ai->ai_addr->sa_family == AF_INET6) {
+ XdmcpAllocARRAY8 (&localAddress, sizeof(struct in6_addr));
+ memcpy(localAddress.data,
+ &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
+ sizeof(struct in6_addr));
+ }
+ freeaddrinfo(ai);
+ }
+#else
struct hostent *hostent;
hostent = gethostbyname (localHostname());
XdmcpAllocARRAY8 (&localAddress, hostent->h_length);
memmove( localAddress.data, hostent->h_addr, hostent->h_length);
+#endif
+
}
return &localAddress;
}
@@ -140,6 +172,9 @@ FreeDisplayEntry (DisplayEntry *d)
case DISPLAY_ADDRESS:
XdmcpDisposeARRAY8 (&d->entry.displayAddress.clientAddress);
break;
+ case DISPLAY_LISTEN:
+ /* do nothing - this case doesn't use the d->entry union */
+ break;
}
for (h = d->hosts; h; h = next) {
next = h->next;
@@ -217,7 +252,8 @@ ReadWord (FILE *file, int EOFatEOL)
continue;
}
default:
- *wordp++ = c;
+ if (wordp < &(wordBuffer[WORD_LEN]))
+ *wordp++ = c;
break;
}
quoted = FALSE;
@@ -230,13 +266,13 @@ ReadHostEntry (FILE *file)
{
char *hostOrAlias;
HostEntry *h;
- struct hostent *hostent;
tryagain:
hostOrAlias = ReadWord (file, TRUE);
if (!hostOrAlias)
return NULL;
h = (HostEntry *) malloc (sizeof (DisplayEntry));
+ h->hopCount = 1;
if (*hostOrAlias == ALIAS_CHARACTER)
{
h->type = HOST_ALIAS;
@@ -259,24 +295,64 @@ tryagain:
{
h->type = HOST_NOBROADCAST;
}
+ else if (!strcmp (hostOrAlias, WILDCARD_STRING))
+ {
+ h->type = HOST_ANYADDR;
+ h->entry.hostAddress.length = 0;
+ }
else
{
+ void *addr=NULL;
+ size_t addr_length=0;
+#if defined(IPv6) && defined(AF_INET6)
+ struct addrinfo *ai;
+#else
+ struct hostent *hostent = gethostbyname (hostOrAlias);
+#endif
+ char *hops = strrchr(hostOrAlias, '/');
+
+ if (hops) {
+ *(hops++) = '\0';
+ h->hopCount = strtol(hops, NULL, 10);
+ if (h->hopCount < 1)
+ h->hopCount = 1;
+ }
+
+#if defined(IPv6) && defined(AF_INET6)
+ if (getaddrinfo(hostOrAlias, NULL, NULL, &ai) == 0) {
+ if (ai->ai_addr->sa_family == AF_INET) {
+ addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
+ addr_length = sizeof(struct in_addr);
+ } else if (ai->ai_addr->sa_family == AF_INET6) {
+ addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
+ addr_length = sizeof(struct in6_addr);
+ }
+ }
+#else
+ if (hostent) {
+ addr = &(hostent->h_addr);
+ addr_length = hostent->h_length;
+ }
+#endif
h->type = HOST_ADDRESS;
- hostent = gethostbyname (hostOrAlias);
- if (!hostent)
+
+ if (!addr)
{
Debug ("No such host %s\n", hostOrAlias);
LogError ("Access file \"%s\", host \"%s\" not found\n", accessFile, hostOrAlias);
free ((char *) h);
goto tryagain;
}
- if (!XdmcpAllocARRAY8 (&h->entry.hostAddress, hostent->h_length))
+ if (!XdmcpAllocARRAY8 (&h->entry.hostAddress, addr_length))
{
LogOutOfMem ("ReadHostEntry\n");
free ((char *) h);
return NULL;
}
- memmove( h->entry.hostAddress.data, hostent->h_addr, hostent->h_length);
+ memmove( h->entry.hostAddress.data, addr, addr_length);
+#if defined(IPv6) && defined(AF_INET6)
+ freeaddrinfo(ai);
+#endif
}
return h;
}
@@ -301,7 +377,6 @@ ReadDisplayEntry (FILE *file)
DisplayEntry *d;
struct _display *display;
HostEntry *h, **prev;
- struct hostent *hostent;
displayOrAlias = ReadWord (file, FALSE);
if (!displayOrAlias)
@@ -321,6 +396,10 @@ ReadDisplayEntry (FILE *file)
}
strcpy (d->entry.aliasName, displayOrAlias);
}
+ else if (!strcmp(displayOrAlias, LISTEN_STRING))
+ {
+ d->type = DISPLAY_LISTEN;
+ }
else
{
if (*displayOrAlias == NEGATE_CHARACTER)
@@ -341,21 +420,48 @@ ReadDisplayEntry (FILE *file)
}
else
{
+ void *addr = NULL;
+ size_t addr_length = 0;
+ int addrtype = 0;
+
+#if defined(IPv6) && defined(AF_INET6)
+ struct addrinfo *ai;
+
+ if (getaddrinfo(displayOrAlias, NULL, NULL, &ai) == 0) {
+ addrtype = ai->ai_addr->sa_family;
+ if (addrtype == AF_INET) {
+ addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
+ addr_length = sizeof(struct in_addr);
+ } else if (addrtype == AF_INET6) {
+ addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
+ addr_length = sizeof(struct in6_addr);
+ }
+ }
+#else
+ struct hostent *hostent;
+
if ((hostent = gethostbyname (displayOrAlias)) == NULL)
{
+ addr = &(hostent->h_addr);
+ addrtype = hostent->h_addrtype;
+ addr_length = hostent->h_length;
+ }
+#endif
+ if (addr == NULL)
+ {
LogError ("Access file %s, display %s unknown\n", accessFile, displayOrAlias);
free ((char *) d);
return NULL;
}
d->type = DISPLAY_ADDRESS;
display = &d->entry.displayAddress;
- if (!XdmcpAllocARRAY8 (&display->clientAddress, hostent->h_length))
+ if (!XdmcpAllocARRAY8 (&display->clientAddress, addr_length))
{
free ((char *) d);
return NULL;
}
- memmove( display->clientAddress.data, hostent->h_addr, hostent->h_length);
- switch (hostent->h_addrtype)
+ memmove( display->clientAddress.data, addr, addr_length);
+ switch (addrtype)
{
#ifdef AF_UNIX
case AF_UNIX:
@@ -367,6 +473,11 @@ ReadDisplayEntry (FILE *file)
display->connectionType = FamilyInternet;
break;
#endif
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ display->connectionType = FamilyInternet6;
+ break;
+#endif
#ifdef AF_DECnet
case AF_DECnet:
display->connectionType = FamilyDECnet;
@@ -388,6 +499,14 @@ ReadDisplayEntry (FILE *file)
} else if (h->type == HOST_NOBROADCAST) {
FreeHostEntry (h);
d->notBroadcast = 1;
+ } else if (h->type == HOST_ANYADDR) {
+ if (d->type == DISPLAY_LISTEN) {
+ *prev = h;
+ prev = &h->next;
+ } else {
+ Debug("Wildcard host specified in Xaccess for type other than LISTEN -- ignoring\n");
+ FreeHostEntry (h);
+ }
} else {
*prev = h;
prev = &h->next;
@@ -574,6 +693,7 @@ int ForEachMatchingIndirectHost (
{
switch (d->type) {
case DISPLAY_ALIAS:
+ case DISPLAY_LISTEN:
continue;
case DISPLAY_PATTERN:
if (!clientName)
@@ -628,6 +748,7 @@ int UseChooser (
{
switch (d->type) {
case DISPLAY_ALIAS:
+ case DISPLAY_LISTEN:
continue;
case DISPLAY_PATTERN:
if (!clientName)
@@ -675,6 +796,7 @@ void ForEachChooserHost (
{
switch (d->type) {
case DISPLAY_ALIAS:
+ case DISPLAY_LISTEN:
continue;
case DISPLAY_PATTERN:
if (!clientName)
@@ -734,6 +856,7 @@ int AcceptableDisplayAddress (
continue;
switch (d->type) {
case DISPLAY_ALIAS:
+ case DISPLAY_LISTEN:
continue;
case DISPLAY_PATTERN:
if (!clientName)
@@ -759,4 +882,32 @@ int AcceptableDisplayAddress (
&& (type == BROADCAST_QUERY ? d->notBroadcast == 0 : 1);
}
+void ForEachListenAddr (
+ ListenFunc listenfunction,
+ ListenFunc mcastfunction,
+ void **closure)
+{
+ DisplayEntry *d;
+ HostEntry *h;
+ int listenFound = 0;
+
+ for (d = database; d != NULL ; d = d->next)
+ {
+ if (d->type == DISPLAY_LISTEN) {
+ listenFound = 1;
+ h = d->hosts;
+ if (h != NULL) {
+ (*listenfunction) (&h->entry.hostAddress, closure);
+ }
+ for (h = h->next; h != NULL; h = h->next) {
+ (*mcastfunction) (&h->entry.hostAddress, closure);
+ }
+ }
+ }
+ if (!listenFound) {
+ (*listenfunction) (NULL, closure);
+ }
+}
+
+
#endif /* XDMCP */
diff --git a/auth.c b/auth.c
index e5e57b8..057580a 100644
--- a/auth.c
+++ b/auth.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/auth.c,v 3.27 2002/12/10 22:37:17 tsi Exp $ */
+/* $XFree86: xc/programs/xdm/auth.c,v 3.30 2003/11/16 16:35:02 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -88,7 +88,21 @@ from The Open Group.
#include <net/if.h>
#endif /* __GNU__ */
-#if ((defined(SVR4) && !defined(sun)) || defined(ISC)) && defined(SIOCGIFCONF)
+/* Solaris provides an extended interface SIOCGLIFCONF. Other systems
+ * may have this as well, but the code has only been tested on Solaris
+ * so far, so we only enable it there. Other platforms may be added as
+ * needed.
+ *
+ * Test for Solaris commented out -- TSI @ UQV 2003.06.13
+ */
+#ifdef SIOCGLIFCONF
+/* #if defined(sun) */
+#define USE_SIOCGLIFCONF
+/* #endif */
+#endif
+
+#if ((defined(SVR4) && !defined(sun)) || defined(ISC)) && \
+ defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
#define SYSV_SIOCGIFCONF
#endif
@@ -270,7 +284,7 @@ static int
MakeServerAuthFile (struct display *d)
{
int len;
-#ifdef SYSV
+#if defined(SYSV) && !defined(SVR4)
#define NAMELEN 14
#else
#define NAMELEN 255
@@ -700,6 +714,52 @@ DefineLocal (FILE *file, Xauth *auth)
#endif
}
+#ifdef HAS_GETIFADDRS
+#include <ifaddrs.h>
+
+static void
+DefineSelf(int fd, FILE *file, Xauth *auth)
+{
+ struct ifaddrs *ifap, *ifr;
+ char *addr;
+ int family, len;
+
+ Debug("DefineSelf\n");
+ if (getifaddrs(&ifap) < 0)
+ return;
+ for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) {
+ len = sizeof(*(ifr->ifa_addr));
+ family = ConvertAddr((XdmcpNetaddr)(ifr->ifa_addr), &len, &addr);
+ if (family == -1 || family == FamilyLocal)
+ continue;
+ /*
+ * don't write out 'localhost' entries, as
+ * they may conflict with other local entries.
+ * DefineLocal will always be called to add
+ * the local entry anyway, so this one can
+ * be tossed.
+ */
+ if (family == FamilyInternet && len == 4 &&
+ addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1)
+ {
+ Debug ("Skipping localhost address\n");
+ continue;
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ if(family == FamilyInternet6) {
+ if (IN6_IS_ADDR_LOOPBACK(((struct in6_addr *)addr))) {
+ Debug ("Skipping IPv6 localhost address\n");
+ continue;
+ }
+ }
+#endif
+ writeAddr(family, len, addr, file, auth);
+ }
+ Debug("DefineSelf done\n");
+}
+#else /* GETIFADDRS */
+
#ifdef SYSV_SIOCGIFCONF
/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */
@@ -851,7 +911,13 @@ DefineSelf (int fd, FILE *file, Xauth *auth)
#else /* WINTCP */
-#ifdef SIOCGIFCONF
+#if defined(SIOCGIFCONF) || defined (USE_SIOCGLIFCONF)
+
+#ifdef USE_SIOCGLIFCONF
+#define ifr_type struct lifreq
+#else
+#define ifr_type struct ifreq
+#endif
/* Handle variable length ifreq in BNR2 and later */
#ifdef VARIABLE_IFREQ
@@ -859,7 +925,7 @@ DefineSelf (int fd, FILE *file, Xauth *auth)
(p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
#else
-#define ifr_size(p) (sizeof (struct ifreq))
+#define ifr_size(p) (sizeof (ifr_type))
#endif
/* Define this host for access control. Find all the hosts the OS knows about
@@ -869,42 +935,92 @@ static void
DefineSelf (int fd, FILE *file, Xauth *auth)
{
char buf[2048], *cp, *cplim;
- struct ifconf ifc;
int len;
char *addr;
int family;
- register struct ifreq *ifr;
+ register ifr_type *ifr;
+#ifdef USE_SIOCGLIFCONF
+ int n;
+ void * bufptr = buf;
+ size_t buflen = sizeof(buf);
+ struct lifconf ifc;
+#ifdef SIOCGLIFNUM
+ struct lifnum ifn;
+#endif
+#else
+ struct ifconf ifc;
+#endif
+#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF)
+ ifn.lifn_family = AF_UNSPEC;
+ ifn.lifn_flags = 0;
+ if (ioctl (fd, (int) SIOCGLIFNUM, (char *) &ifn) < 0)
+ LogError ("Failed getting interface count");
+ if (buflen < (ifn.lifn_count * sizeof(struct lifreq))) {
+ buflen = ifn.lifn_count * sizeof(struct lifreq);
+ bufptr = malloc(buflen);
+ }
+#endif
+
+#ifdef USE_SIOCGLIFCONF
+ ifc.lifc_family = AF_UNSPEC;
+ ifc.lifc_flags = 0;
+ ifc.lifc_len = buflen;
+ ifc.lifc_buf = bufptr;
+
+#define IFC_IOCTL_REQ SIOCGLIFCONF
+#define IFC_IFC_REQ ifc.lifc_req
+#define IFC_IFC_LEN ifc.lifc_len
+#define IFR_IFR_ADDR ifr->lifr_addr
+#define IFR_IFR_NAME ifr->lifr_name
+
+#else
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
- if (ifioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
- LogError ("Trouble getting network interface configuration");
+#define IFC_IOCTL_REQ SIOCGIFCONF
#ifdef ISC
#define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf
#else
#define IFC_IFC_REQ ifc.ifc_req
#endif
+#define IFC_IFC_LEN ifc.ifc_len
+#define IFR_IFR_ADDR ifr->ifr_addr
+#define IFR_IFR_NAME ifr->ifr_name
+#endif
- cplim = (char *) IFC_IFC_REQ + ifc.ifc_len;
+ if (ifioctl (fd, IFC_IOCTL_REQ, (char *) &ifc) < 0) {
+ LogError ("Trouble getting network interface configuration");
+
+#ifdef USE_SIOCGLIFCONF
+ if (bufptr != buf) {
+ free(bufptr);
+ }
+#endif
+ return;
+ }
+
+ cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
{
- ifr = (struct ifreq *) cp;
+ ifr = (ifr_type *) cp;
#ifdef DNETCONN
/*
* this is ugly but SIOCGIFCONF returns decnet addresses in
* a different form from other decnet calls
*/
- if (ifr->ifr_addr.sa_family == AF_DECnet) {
+ if (IFR_IFR_ADDR.sa_family == AF_DECnet) {
len = sizeof (struct dn_naddr);
addr = (char *)ifr->ifr_addr.sa_data;
family = FamilyDECnet;
} else
#endif
{
- if (ConvertAddr ((XdmcpNetaddr) &ifr->ifr_addr, &len, &addr) < 0)
+ family = ConvertAddr ((XdmcpNetaddr) &IFR_IFR_ADDR, &len, &addr);
+ if (family < 0)
continue;
+
if (len == 0)
{
Debug ("Skipping zero length address\n");
@@ -917,14 +1033,21 @@ DefineSelf (int fd, FILE *file, Xauth *auth)
* the local entry anyway, so this one can
* be tossed.
*/
- if (len == 4 &&
+ if (family == FamilyInternet && len == 4 &&
addr[0] == 127 && addr[1] == 0 &&
addr[2] == 0 && addr[3] == 1)
{
Debug ("Skipping localhost address\n");
continue;
}
- family = FamilyInternet;
+#if defined(IPv6) && defined(AF_INET6)
+ if(family == FamilyInternet6) {
+ if (IN6_IS_ADDR_LOOPBACK(((struct in6_addr *)addr))) {
+ Debug ("Skipping IPv6 localhost address\n");
+ continue;
+ }
+ }
+#endif
}
Debug ("DefineSelf: write network address, length %d\n", len);
writeAddr (family, len, addr, file, auth);
@@ -974,10 +1097,11 @@ DefineSelf (int fd, int file, int auth)
}
}
+
#endif /* SIOCGIFCONF else */
#endif /* WINTCP else */
#endif /* STREAMSCONN && !SYSV_SIOCGIFCONF else */
-
+#endif /* HAS_GETIFADDRS */
static void
setAuthNumber (Xauth *auth, char *name)
@@ -1022,7 +1146,11 @@ writeLocalAuth (FILE *file, Xauth *auth, char *name)
t_close (fd);
#endif
#ifdef TCPCONN
+#if defined(IPv6) && defined(AF_INET6)
+ fd = socket (AF_INET6, SOCK_STREAM, 0);
+#else
fd = socket (AF_INET, SOCK_STREAM, 0);
+#endif
DefineSelf (fd, file, auth);
close (fd);
#endif
diff --git a/choose.c b/choose.c
index e4b94d8..24bc596 100644
--- a/choose.c
+++ b/choose.c
@@ -26,7 +26,7 @@ in this Software without prior written authorization from The Open Group.
* Author: Keith Packard, MIT X Consortium
*/
-/* $XFree86: xc/programs/xdm/choose.c,v 3.15 2001/12/14 20:01:20 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/choose.c,v 3.17 2003/07/09 15:27:38 tsi Exp $ */
/*
* choose.c
@@ -43,6 +43,7 @@ in this Software without prior written authorization from The Open Group.
#include <sys/types.h>
#include "dm_socket.h"
+#include <arpa/inet.h>
#ifndef X_NO_SYS_UN
#ifndef Lynx
@@ -197,19 +198,29 @@ FormatChooserArgument (char *buf, int len)
netfamily = NetaddrFamily((XdmcpNetaddr)addr_buf);
switch (netfamily) {
case AF_INET:
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+#endif
{
char *port;
int portlen;
- ARRAY8Ptr localAddress;
+ ARRAY8Ptr localAddress = getLocalAddress ();
+
+#if defined(IPv6) && defined(AF_INET6)
+ if (localAddress->length == 16)
+ netfamily = AF_INET6;
+ else
+ netfamily = AF_INET;
+#endif
port = NetaddrPort((XdmcpNetaddr)addr_buf, &portlen);
result_buf[0] = netfamily >> 8;
result_buf[1] = netfamily & 0xFF;
result_buf[2] = port[0];
result_buf[3] = port[1];
- localAddress = getLocalAddress ();
- memmove( (char *)result_buf+4, (char *)localAddress->data, 4);
- result_len = 8;
+ memmove( (char *)result_buf+4, (char *)localAddress->data,
+ localAddress->length);
+ result_len = 4 + localAddress->length;
}
break;
#ifdef AF_DECnet
@@ -280,13 +291,17 @@ RegisterIndirectChoice (
{
ChoicePtr c;
int insert;
+#if 0
int found = 0;
+#endif
Debug ("Got indirect choice back\n");
for (c = choices; c; c = c->next) {
if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
connectionType == c->connectionType) {
+#if 0
found = 1;
+#endif
break;
}
}
@@ -372,6 +387,13 @@ AddChooserHost (
{
*argp = parseArgs (*argp, "BROADCAST");
}
+#if defined(IPv6) && defined(AF_INET6)
+ else if ( (addr->length == 16) &&
+ (inet_ntop(AF_INET6, addr->data, hostbuf, sizeof(hostbuf))))
+ {
+ *argp = parseArgs (*argp, hostbuf);
+ }
+#endif
else if (ARRAY8ToDottedDecimal (addr, hostbuf, sizeof (hostbuf)))
{
*argp = parseArgs (*argp, hostbuf);
diff --git a/chooser.c b/chooser.c
index 4e63ee7..4d47a12 100644
--- a/chooser.c
+++ b/chooser.c
@@ -26,7 +26,7 @@ in this Software without prior written authorization from The Open Group.
* Author: Keith Packard, MIT X Consortium
*/
-/* $XFree86: xc/programs/xdm/chooser.c,v 3.24 2001/12/14 20:01:20 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/chooser.c,v 3.26 2003/07/18 15:53:28 tsi Exp $ */
/*
* Chooser - display a menu of names and let the user select one
@@ -194,6 +194,9 @@ typedef struct _hostName {
static HostName *hostNamedb;
static int socketFD;
+#if defined(IPv6) && defined(AF_INET6)
+static int socket6FD;
+#endif
static int pingTry;
@@ -262,13 +265,22 @@ static void
PingHosts (XtPointer closure, XtIntervalId *id)
{
HostAddr *hosts;
+ int sfd = socketFD;
for (hosts = hostAddrdb; hosts; hosts = hosts->next)
{
+#if defined(IPv6) && defined(AF_INET6)
+ if ( ((struct sockaddr *) hosts->addr)->sa_family == AF_INET6 )
+ sfd = socket6FD;
+ else
+ sfd = socketFD;
+#endif
if (hosts->type == QUERY)
- XdmcpFlush (socketFD, &directBuffer, (XdmcpNetaddr) hosts->addr, hosts->addrlen);
+ XdmcpFlush (sfd, &directBuffer,
+ (XdmcpNetaddr) hosts->addr, hosts->addrlen);
else
- XdmcpFlush (socketFD, &broadcastBuffer, (XdmcpNetaddr) hosts->addr, hosts->addrlen);
+ XdmcpFlush (sfd, &broadcastBuffer,
+ (XdmcpNetaddr) hosts->addr, hosts->addrlen);
}
if (++pingTry < TRIES)
XtAddTimeOut (PING_INTERVAL, PingHosts, (XtPointer) 0);
@@ -321,6 +333,13 @@ AddHostname (ARRAY8Ptr hostname, ARRAY8Ptr status, struct sockaddr *addr, int wi
hostAddr.length = 4;
connectionType = FamilyInternet;
break;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ hostAddr.data = (CARD8 *) &((struct sockaddr_in6 *) addr)->sin6_addr;
+ hostAddr.length = 16;
+ connectionType = FamilyInternet6;
+ break;
+#endif
default:
hostAddr.data = (CARD8 *) "";
hostAddr.length = 0;
@@ -350,11 +369,14 @@ AddHostname (ARRAY8Ptr hostname, ARRAY8Ptr status, struct sockaddr *addr, int wi
switch (addr->sa_family)
{
case AF_INET:
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+#endif
{
struct hostent *hostent;
char *host;
- hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, AF_INET);
+ hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, addr->sa_family);
if (hostent)
{
XdmcpDisposeARRAY8 (hostname);
@@ -464,11 +486,16 @@ ReceivePacket (XtPointer closure, int *source, XtInputId *id)
ARRAY8 hostname;
ARRAY8 status;
int saveHostname = 0;
+#if defined(IPv6) && defined(AF_INET6)
+ struct sockaddr_storage addr;
+#else
struct sockaddr addr;
+#endif
int addrlen;
+ int sfd = * (int *) closure;
addrlen = sizeof (addr);
- if (!XdmcpFill (socketFD, &buffer, (XdmcpNetaddr) &addr, &addrlen))
+ if (!XdmcpFill (sfd, &buffer, (XdmcpNetaddr) &addr, &addrlen))
return;
if (!XdmcpReadHeader (&buffer, &header))
return;
@@ -486,7 +513,8 @@ ReceivePacket (XtPointer closure, int *source, XtInputId *id)
if (header.length == 6 + authenticationName.length +
hostname.length + status.length)
{
- if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
+ if (AddHostname (&hostname, &status, (struct sockaddr *) &addr,
+ header.opcode == (int) WILLING))
saveHostname = 1;
}
}
@@ -498,7 +526,8 @@ ReceivePacket (XtPointer closure, int *source, XtInputId *id)
{
if (header.length == 4 + hostname.length + status.length)
{
- if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
+ if (AddHostname (&hostname, &status, (struct sockaddr *) &addr,
+ header.opcode == (int) WILLING))
saveHostname = 1;
}
@@ -558,7 +587,9 @@ RegisterHostaddr (struct sockaddr *addr, int len, xdmOpCode type)
static void
RegisterHostname (char *name)
{
+#if !defined(IPv6) || !defined(AF_INET6)
struct hostent *hostent;
+#endif
struct sockaddr_in in_addr;
struct ifconf ifc;
register struct ifreq *ifr;
@@ -673,13 +704,48 @@ RegisterHostname (char *name)
}
else
{
-
- /* address as hex string, e.g., "12180022" (depreciated) */
+ /* address as hex string, e.g., "12180022" (deprecated) */
if (strlen(name) == 8 &&
FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
{
in_addr.sin_family = AF_INET;
+ in_addr.sin_port = htons (XDM_UDP_PORT);
+#ifdef BSD44SOCKETS
+ in_addr.sin_len = sizeof(in_addr);
+#endif
+ RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
+ QUERY);
}
+#if defined(IPv6) && defined(AF_INET6)
+ else {
+ char sport[8];
+ struct addrinfo *ai, *nai, hints;
+ bzero(&hints,sizeof(hints));
+ hints.ai_socktype = SOCK_DGRAM;
+ sprintf(sport, "%d", XDM_UDP_PORT);
+ if (getaddrinfo(name, sport, &hints, &ai) == 0) {
+ for (nai = ai ; nai != NULL ; nai = nai->ai_next) {
+ if ((nai->ai_family == AF_INET) ||
+ (nai->ai_family == AF_INET6)) {
+ if (((nai->ai_family == AF_INET) &&
+ IN_MULTICAST(((struct sockaddr_in *) nai->ai_addr)
+ ->sin_addr.s_addr))
+ || ((nai->ai_family == AF_INET6) &&
+ IN6_IS_ADDR_MULTICAST(
+ &((struct sockaddr_in6 *) nai->ai_addr)
+ ->sin6_addr)))
+ {
+ RegisterHostaddr(nai->ai_addr, nai->ai_addrlen,
+ BROADCAST_QUERY);
+ } else {
+ RegisterHostaddr(nai->ai_addr, nai->ai_addrlen,
+ QUERY);
+ }
+ }
+ }
+ }
+ }
+#else
/* Per RFC 1123, check first for IP address in dotted-decimal form */
else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
in_addr.sin_family = AF_INET;
@@ -699,6 +765,7 @@ RegisterHostname (char *name)
#endif
RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
QUERY);
+#endif /* IPv6 */
}
}
#else /* __GNU__ */
@@ -718,12 +785,30 @@ RegisterHostname (char *name)
else
{
- /* address as hex string, e.g., "12180022" (depreciated) */
+ /* address as hex string, e.g., "12180022" (deprecated) */
if (strlen(name) == 8 &&
FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
{
in_addr.sin_family = AF_INET;
- }
+ in_addr.sin_port = htons (XDM_UDP_PORT);
+ RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
+ QUERY);
+ } else {
+#if defined(IPv6) && defined(AF_INET6)
+ char sport[8];
+ struct addrinfo *ai, *nai, hints;
+ bzero(&hints,sizeof(hints));
+ hints.ai_socktype = SOCK_DGRAM;
+ sprintf(sport, "%d", XDM_UDP_PORT);
+ if (getaddrinfo(name, sport, &hints, &ai) == 0) {
+ for (nai = ai ; nai != NULL ; nai = nai->ai_next) {
+ if ((nai->ai_family == AF_INET) ||
+ (nai->ai_family == AF_INET6)) {
+ RegisterHostaddr(nai->ai_addr, nai->ai_addrlen, QUERY);
+ }
+ }
+ }
+#else
/* Per RFC 1123, check first for IP address in dotted-decimal form */
else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
in_addr.sin_family = AF_INET;
@@ -740,6 +825,9 @@ RegisterHostname (char *name)
in_addr.sin_port = htons (XDM_UDP_PORT);
RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
QUERY);
+#endif
+ }
+
}
}
#endif /* __GNU__ */
@@ -820,6 +908,9 @@ InitXDMCP (char **argv)
#else
if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
return 0;
+#if defined(IPv6) && defined(AF_INET6)
+ socket6FD = socket (AF_INET6, SOCK_DGRAM, 0);
+#endif
#endif
#ifndef STREAMSCONN
#ifdef SO_BROADCAST
@@ -830,7 +921,11 @@ InitXDMCP (char **argv)
#endif
XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
- (XtPointer) 0);
+ (XtPointer) &socketFD);
+#if defined(IPv6) && defined(AF_INET6)
+ XtAddInput (socket6FD, (XtPointer) XtInputReadMask, ReceivePacket,
+ (XtPointer) &socket6FD);
+#endif
while (*argv)
{
RegisterHostname (*argv);
@@ -847,6 +942,9 @@ Choose (HostName *h)
if (app_resources.xdmAddress)
{
struct sockaddr_in in_addr;
+#if defined(IPv6) && defined(AF_INET6)
+ struct sockaddr_in6 in6_addr;
+#endif
struct sockaddr *addr = NULL;
int family;
int len = 0;
@@ -871,6 +969,19 @@ Choose (HostName *h)
addr = (struct sockaddr *) &in_addr;
len = sizeof (in_addr);
break;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ bzero(&in6_addr, sizeof(in6_addr));
+#ifdef SIN6_LEN
+ in6_addr.sin6_len = sizeof(in6_addr);
+#endif
+ in6_addr.sin6_family = family;
+ memmove( &in6_addr.sin6_port, xdm + 2, 2);
+ memmove( &in6_addr.sin6_addr, xdm + 4, 16);
+ addr = (struct sockaddr *) &in6_addr;
+ len = sizeof (in6_addr);
+ break;
+#endif
}
#if defined(STREAMSCONN)
if ((fd = t_open ("/dev/tcp", O_RDWR, NULL)) == -1)
diff --git a/config/Xaccess b/config/Xaccess
index c83cc18..f0672ef 100644
--- a/config/Xaccess
+++ b/config/Xaccess
@@ -1,6 +1,5 @@
# $Xorg: Xaccess,v 1.3 2000/08/17 19:54:17 cpqbld Exp $
-#
-# $XFree86: xc/programs/xdm/config/Xaccess,v 1.3 2001/01/17 23:45:24 dawes Exp $
+# $XFree86: xc/programs/xdm/config/Xaccess,v 1.4 2003/07/09 15:27:40 tsi Exp $
#
# Access control file for XDMCP connections
#
@@ -24,6 +23,10 @@
#
# %name list of hosts ...
#
+# To control which addresses xdm listens for requests on:
+#
+# LISTEN address [list of multicast groups ... ]
+#
# The first form tells xdm which displays to respond to itself.
# The second form tells xdm to forward indirect queries from hosts matching
# the specified pattern to the indicated list of hosts.
@@ -32,6 +35,9 @@
# address and display the results on the terminal.
# The fourth form is similar to the third, except instead of using the
# broadcast address, it sends DirectQuerys to each of the hosts in the list
+# The fifth form tells xdm which addresses to listen for incoming connections
+# on. If present, xdm will only listen for connections on the specified
+# interfaces and/or multicast groups.
#
# In all cases, xdm uses the first entry which matches the terminal;
# for IndirectQuery messages only entries with right hand sides can
@@ -68,3 +74,17 @@
#%hostlist host-a host-b
#* CHOOSER %hostlist #
+
+#
+# If you have a machine with multiple network interfaces or IP addresses
+# you can control which interfaces accept XDMCP packets by listing a LISTEN
+# line for each interface you want to listen on. You can additionally list
+# one or more multicast groups after each address to listen on those groups
+# on that address.
+#
+# If no LISTEN is specified, the default is the same as "LISTEN *" - listen on
+# all unicast interfaces, but not for multicast packets. If any LISTEN lines
+# are specified, then only the listed interfaces will be listened on.
+#
+
+#LISTEN * ff02::1
diff --git a/config/Xresources.cpp b/config/Xresources.cpp
index d64de52..46d2cf0 100644
--- a/config/Xresources.cpp
+++ b/config/Xresources.cpp
@@ -3,7 +3,7 @@
!
!
!
-! $XFree86: xc/programs/xdm/config/Xres.cpp,v 1.6 2003/01/04 03:11:31 dawes Exp $
+! $XFree86: xc/programs/xdm/config/Xres.cpp,v 1.7 2003/11/15 03:25:22 dawes Exp $
!
#define BS \ /* cpp can be trickier than m4 */
#define NLBS \n\ /* don't remove these comments */
@@ -28,19 +28,19 @@ xlogin*namePrompt: \040\040\040\040\040\040\040Login:
#endif /* XPM */
xlogin*fail: Login incorrect
#ifdef XPM
-/**/#if WIDTH > 800
+XHASHif WIDTH > 800
xlogin*greetFont: -adobe-helvetica-bold-o-normal--24-240-75-75-p-138-iso8859-1
xlogin*font: -adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1
xlogin*promptFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1
xlogin*failFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1
-/**/#else
+XHASHelse
xlogin*greetFont: -adobe-helvetica-bold-o-normal--17-120-100-100-p-92-iso8859-1
xlogin*font: -adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1
xlogin*promptFont: -adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1
xlogin*failFont: -adobe-helvetica-bold-o-normal--14-140-75-75-p-82-iso8859-1
-/**/#endif
+XHASHendif
#endif /* XPM */
-/**/#ifdef COLOR
+XHASHifdef COLOR
#ifndef XPM
xlogin*greetColor: CadetBlue
#else
@@ -56,7 +56,7 @@ xlogin*greetColor: Blue3
xlogin*failColor: red
*Foreground: black
*Background: #fffff0
-/**/#else
+XHASHelse
#ifdef XPM
xlogin*borderWidth: 3
xlogin*frameWidth: 0
@@ -68,13 +68,13 @@ xlogin*borderWidth: 3
xlogin*Foreground: black
xlogin*Background: white
#endif /* XPM */
-/**/#endif
+XHASHendif
#ifdef XPM
-/**/#if PLANES >= 8
+XHASHif PLANES >= 8
xlogin*logoFileName: BITMAPDIR/**//XDM_PIXMAP
-/**/#else
+XHASHelse
xlogin*logoFileName: BITMAPDIR/**//XDM_BWPIXMAP
-/**/#endif
+XHASHendif
xlogin*useShape: true
xlogin*logoPadding: 10
#endif /* XPM */
diff --git a/dm.c b/dm.c
index 09834e6..c953b98 100644
--- a/dm.c
+++ b/dm.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/dm.c,v 3.21 2002/12/07 20:31:04 herrb Exp $ */
+/* $XFree86: xc/programs/xdm/dm.c,v 3.23 2003/09/17 05:48:32 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -73,7 +73,7 @@ from The Open Group.
#endif
-#if defined(SVR4) && !defined(SCO)
+#if defined(SVR4) && !defined(SCO) && !defined(sun)
extern FILE *fdopen();
#endif
@@ -86,7 +86,7 @@ static void SetConfigFileTime (void);
static void StartDisplays (void);
static void TerminateProcess (int pid, int signal);
-int Rescan;
+volatile int Rescan;
static long ServersModTime, ConfigModTime, AccessFileModTime;
int nofork_session = 0;
@@ -157,7 +157,9 @@ main (int argc, char **argv)
snprintf(cmdbuf, sizeof(cmdbuf), "/bin/rm -f %s/authdir/authfiles/A*", authDir);
system(cmdbuf);
}
-
+#if!defined(ARC4_RANDOM) && !defined(DEV_RANDOM)
+ AddOtherEntropy ();
+#endif
#ifdef XDMCP
init_session_id ();
CreateWellKnownSockets ();
@@ -177,9 +179,13 @@ main (int argc, char **argv)
SetAccessFileTime ();
#ifdef XDMCP
ScanAccessDatabase ();
+ UpdateListenSockets ();
#endif
ScanServers ();
StartDisplays ();
+#if !defined(ARC4_RANDOM) && !defined(DEV_RANDOM)
+ AddOtherEntropy();
+#endif
(void) Signal (SIGHUP, RescanNotify);
#ifndef UNRELIABLE_SIGNALS
(void) Signal (SIGCHLD, ChildNotify);
@@ -281,6 +287,7 @@ RescanServers (void)
SetAccessFileTime ();
#ifdef XDMCP
ScanAccessDatabase ();
+ UpdateListenSockets ();
#endif
StartDisplays ();
}
@@ -339,6 +346,7 @@ RescanIfMod (void)
LogInfo ("Rereading access file %s\n", accessFile);
AccessFileModTime = statb.st_mtime;
ScanAccessDatabase ();
+ UpdateListenSockets();
}
}
#endif
@@ -517,6 +525,9 @@ WaitForChild (void)
" removing display %s\n",d->name);
LogError("Server crash rate too high:"
" removing display %s\n",d->name);
+#if !defined(ARC4_RANDOM) && !defined(DEV_RANDOM)
+ AddTimerEntropy();
+#endif
RemoveDisplay (d);
} else
d->lastCrash = Time;
diff --git a/dm.h b/dm.h
index 1df6f88..483ce20 100644
--- a/dm.h
+++ b/dm.h
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/dm.h,v 3.29 2002/05/31 18:46:10 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/dm.h,v 3.33 2003/11/19 03:57:10 dawes Exp $ */
/*
* xdm - display manager daemon
@@ -186,6 +186,7 @@ struct display {
int useChooser; /* Run the chooser for this display */
ARRAY8 clientAddr; /* for chooser picking */
CARD16 connectionType; /* ... */
+ int xdmcpFd;
#endif
/* server management resources */
int serverAttempts; /* number of attempts at running X */
@@ -279,6 +280,7 @@ struct greet_info {
#endif
typedef void (*ChooserFunc)(CARD16 connectionType, ARRAY8Ptr addr, char *closure);
+typedef void (*ListenFunc)(ARRAY8Ptr addr, void **closure);
struct verify_info {
int uid; /* user id */
@@ -318,7 +320,12 @@ extern int removeDomainname;
extern char *keyFile;
extern char *accessFile;
extern char **exportList;
+#if !defined(ARC4_RANDOM)
extern char *randomFile;
+extern char *prngdSocket;
+extern int prngdPort;
+#endif
+
extern char *greeterLib;
extern char *willing;
extern int choiceTimeout; /* chooser choice timeout */
@@ -352,6 +359,8 @@ extern int ForEachMatchingIndirectHost (ARRAY8Ptr clientAddress, CARD16 connecti
extern int ScanAccessDatabase (void);
extern int UseChooser (ARRAY8Ptr clientAddress, CARD16 connectionType);
extern void ForEachChooserHost (ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure);
+extern void ForEachListenAddr(ListenFunc listenfunction,
+ ListenFunc mcastfcuntion, void **closure);
/* in choose.c */
extern ARRAY8Ptr IndirectChoice (ARRAY8Ptr clientAddress, CARD16 connectionType);
@@ -439,9 +448,12 @@ extern int StartServer (struct display *d);
extern int WaitForServer (struct display *d);
extern void ResetServer (struct display *d);
-/* socket.c */
+/* socket.c or streams.c */
extern int GetChooserAddr (char *addr, int *lenp);
extern void CreateWellKnownSockets (void);
+extern void UpdateListenSockets (void);
+extern void CloseListenSockets (void);
+extern void ProcessListenSockets (fd_set *readmask);
/* in util.c */
extern char *localHostname (void);
@@ -467,6 +479,7 @@ extern void WaitForChild (void);
extern void WaitForSomething (void);
extern void init_session_id(void);
extern void registerHostname(char *name, int namelen);
+extern void ProcessRequestSocket(int fd);
/*
* CloseOnFork flags
@@ -497,6 +510,11 @@ extern void registerHostname(char *name, int namelen);
#define Jmp_buf sigjmp_buf
#endif
+#ifndef HAS_SNPRINTF
+#include <X11/Xmu/SysUtil.h>
+#define snprintf XmuSnprintf
+#endif
+
typedef SIGVAL (*SIGFUNC)(int);
SIGVAL (*Signal(int, SIGFUNC Handler))(int);
diff --git a/dm_auth.h b/dm_auth.h
index 8f606ea..abbe93d 100644
--- a/dm_auth.h
+++ b/dm_auth.h
@@ -1,5 +1,5 @@
/*
- * $XFree86: xc/programs/xdm/dm_auth.h,v 1.2 2000/05/31 07:15:11 eich Exp $
+ * $XFree86: xc/programs/xdm/dm_auth.h,v 1.4 2003/10/27 21:39:06 herrb Exp $
*/
/************************************************************
@@ -50,6 +50,9 @@ extern void XdmGetXdmcpAuth (
struct protoDisplay *pdpy,
unsigned short authorizationNameLen,
char *authorizationName);
+extern int XdmCheckAuthentication (struct protoDisplay *pdpy,
+ ARRAY8Ptr displayID, ARRAY8Ptr authenticationName,
+ ARRAY8Ptr authenticationData);
#else
#define XdmGetXdmcpAuth NULL
#endif
@@ -87,6 +90,14 @@ extern void SetLocalAuthorization (struct display *d);
extern void SetUserAuthorization (struct display *d, struct verify_info *verify);
/* genauth.c */
-extern void GenerateAuthData (char *auth, int len);
+extern int GenerateAuthData (char *auth, int len);
+#if !defined(ARC4_RANDOM)
+extern void AddPreGetEntropy (void);
+extern void AddOtherEntropy (void);
+extern void AddTimerEntropy (void);
+#endif
+
+/* prngc.c */
+extern int get_prngd_bytes(char *, int, unsigned short, char *);
#endif /* _DM_AUTH_H_ */
diff --git a/dpylist.c b/dpylist.c
index cbd8009..3b749a1 100644
--- a/dpylist.c
+++ b/dpylist.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/dpylist.c,v 1.5 2001/12/14 20:01:21 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/dpylist.c,v 1.6 2003/07/09 15:27:38 tsi Exp $ */
/*
* xdm - display manager daemon
@@ -258,6 +258,7 @@ NewDisplay (char *name, char *class)
d->clientAddr.data = NULL;
d->clientAddr.length = 0;
d->connectionType = 0;
+ d->xdmcpFd = -1;
#endif
d->version = 1; /* registered with The Open Group */
displays = d;
diff --git a/genauth.c b/genauth.c
index 0568e6f..0e50226 100644
--- a/genauth.c
+++ b/genauth.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/genauth.c,v 3.15 2002/10/06 18:12:29 herrb Exp $ */
+/* $XFree86: xc/programs/xdm/genauth.c,v 3.20 2003/10/17 20:20:02 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -45,7 +45,13 @@ from The Open Group.
#include <time.h>
#define Time_t time_t
+#ifdef HASXDMAUTH
static unsigned char key[8];
+#endif
+
+#ifdef DEV_RANDOM
+extern char *randomDevice;
+#endif
#ifdef HASXDMAUTH
@@ -53,7 +59,10 @@ typedef unsigned char auth_cblock[8]; /* block size */
typedef struct auth_ks_struct { auth_cblock _; } auth_wrapper_schedule[16];
-extern void _XdmcpWrapperToOddParity();
+extern int _XdmcpAuthSetup(unsigned char *, auth_wrapper_schedule);
+extern int _XdmcpAuthDoIt(unsigned char *, unsigned char *,
+ auth_wrapper_schedule, int);
+extern void _XdmcpWrapperToOddParity(unsigned char *, unsigned char *);
static void
longtochars (long l, unsigned char *c)
@@ -66,66 +75,293 @@ longtochars (long l, unsigned char *c)
#endif
-# define FILE_LIMIT 1024 /* no more than this many buffers */
+#ifdef POLL_DEV_RANDOM
+#include <poll.h>
+static int
+pollRandomDevice (int fd)
+{
+ struct pollfd fds;
+
+ fds.fd = fd;
+ fds.events = POLLIN | POLLRDNORM;
+ /* Wait up to 5 seconds for entropy to accumulate */
+ return poll(&fds, 1, 5000);
+}
+#else
+#define pollRandomDevice(fd) 1
+#endif
+
+#if !defined(ARC4_RANDOM)
+
+/* ####################################################################### */
+
+/*
+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
+ * rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+static unsigned int epool[32], erotate, eadd_ptr;
+
+static void
+add_entropy (unsigned const int *in, int nwords)
+{
+ static unsigned const int twist_table[8] = {
+ 0, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
+ 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
+ unsigned i, w;
+ int new_rotate;
+
+ while (nwords--) {
+ w = *in++;
+ w = (w<<erotate | w>>(32-erotate)) & 0xffffffff;
+ i = eadd_ptr = (eadd_ptr - 1) & 31;
+ new_rotate = erotate + 14;
+ if (i)
+ new_rotate = erotate + 7;
+ erotate = new_rotate & 31;
+ w ^= epool[(i + 26) & 31];
+ w ^= epool[(i + 20) & 31];
+ w ^= epool[(i + 14) & 31];
+ w ^= epool[(i + 7) & 31];
+ w ^= epool[(i + 1) & 31];
+ w ^= epool[i];
+ epool[i] = (w >> 3) ^ twist_table[w & 7];
+ }
+}
+
+/* ####################################################################### */
+
+/*
+ * This code implements something close to the MD5 message-digest
+ * algorithm. This code is based on code written by Colin Plumb
+ * in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ */
+
+/* The four core functions - F1 is optimized somewhat */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1 (z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define pmd5_step(f, w, x, y, z, data, s) \
+ ( w += (f(x, y, z) + data) & 0xffffffff, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.
+ */
+static void
+pmd5_hash (unsigned int *out, unsigned const int in[16])
+{
+ unsigned int a, b, c, d;
+
+ a = out[0];
+ b = out[1];
+ c = out[2];
+ d = out[3];
+
+ pmd5_step(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ pmd5_step(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ pmd5_step(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ pmd5_step(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ pmd5_step(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ pmd5_step(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ pmd5_step(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ pmd5_step(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ pmd5_step(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ pmd5_step(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ pmd5_step(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ pmd5_step(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ pmd5_step(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ pmd5_step(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ pmd5_step(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ pmd5_step(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ pmd5_step(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ pmd5_step(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ pmd5_step(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ pmd5_step(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ pmd5_step(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ pmd5_step(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ pmd5_step(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ pmd5_step(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ pmd5_step(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ pmd5_step(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ pmd5_step(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ pmd5_step(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ pmd5_step(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ pmd5_step(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ pmd5_step(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ pmd5_step(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ pmd5_step(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ pmd5_step(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ pmd5_step(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ pmd5_step(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ pmd5_step(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ pmd5_step(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ pmd5_step(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ pmd5_step(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ pmd5_step(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ pmd5_step(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ pmd5_step(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ pmd5_step(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ pmd5_step(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ pmd5_step(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ pmd5_step(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ pmd5_step(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ pmd5_step(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ pmd5_step(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ pmd5_step(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ pmd5_step(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ pmd5_step(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ pmd5_step(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ pmd5_step(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ pmd5_step(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ pmd5_step(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ pmd5_step(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ pmd5_step(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ pmd5_step(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ pmd5_step(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ pmd5_step(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ pmd5_step(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ pmd5_step(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ out[0] += a;
+ out[1] += b;
+ out[2] += c;
+ out[3] += d;
+}
+
+/* ####################################################################### */
+
-#if !defined(ARC4_RANDOM) && !defined(DEV_RANDOM)
static int
-sumFile (char *name, long sum[2])
+sumFile (const char *name, int len, int whence, off_t offset)
{
- long buf[1024*2];
- int cnt;
- int fd;
- int loops;
- int reads;
- int i;
- int ret_status = 0;
-
- fd = open (name, O_RDONLY);
- if (fd < 0) {
- LogError("Cannot open randomFile \"%s\", errno = %d\n", name, errno);
- return 0;
+ int fd, cnt, readlen = 0;
+ unsigned char buf[0x1000];
+
+ if ((fd = open (name, O_RDONLY)) < 0) {
+ Debug("cannot open entropy source \"%s\", errno=%d\n", name, errno);
+ return -1;
}
-#ifdef FRAGILE_DEV_MEM
- if (strcmp(name, "/dev/mem") == 0) lseek (fd, (off_t) 0x100000, SEEK_SET);
-#endif
- reads = FILE_LIMIT;
- sum[0] = 0;
- sum[1] = 0;
- while ((cnt = read (fd, (char *) 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];
- ret_status = 1;
+ lseek (fd, offset, whence);
+ while (readlen < len) {
+ if (!(cnt = read (fd, buf, sizeof (buf))))
+ break;
+ if (cnt < 0) {
+ close (fd);
+ Debug("cannot read entropy source \"%s\", errno=%d\n",
+ name, errno);
+ return -1;
}
+ readlen += cnt;
+ add_entropy((unsigned*)buf, (cnt + 3) / 4);
}
- if (cnt < 0)
- LogError("Cannot read randomFile \"%s\", errno = %d\n", name, errno);
close (fd);
- return ret_status;
+ Debug("read %d bytes from entropy source \"%s\"\n", readlen, name);
+ return readlen;
+}
+
+void
+AddTimerEntropy (void)
+{
+ struct timeval now;
+ X_GETTIMEOFDAY (&now);
+ add_entropy((unsigned*)&now, sizeof(now)/sizeof(unsigned));
+}
+
+#define BSIZ 0x10000
+
+void
+AddOtherEntropy (void)
+{
+ AddTimerEntropy();
+ /* XXX -- setup-specific ... use some common ones */
+ sumFile ("/var/log/messages", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/syslog", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/debug", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/kern.log", 0x1000, SEEK_END, -0x1000);
+ sumFile ("/var/log/daemon.log", 0x1000, SEEK_END, -0x1000);
}
+
+void
+AddPreGetEntropy (void)
+{
+ static long offset;
+ long readlen;
+
+ AddTimerEntropy();
+ if ((readlen = sumFile (randomFile, BSIZ, SEEK_SET, offset)) == BSIZ) {
+ offset += readlen;
+#ifdef FRAGILE_DEV_MEM
+ if (!strcmp (randomFile, "/dev/mem")) {
+ if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */
+ offset = 0x100000;
+ else if (offset == 0xf00000) /* skip 15-16MB memory hole */
+ offset = 0x1000000;
+ }
#endif
+ return;
+ } else if (readlen >= 0 && offset) {
+ if ((offset = sumFile (randomFile, BSIZ, SEEK_SET, 0)) == BSIZ)
+ return;
+ }
+ LogError("Cannot read randomFile \"%s\"; X cookies may be easily guessable\n", randomFile);
+}
+#endif /* !ARC4_RANDOM && !DEV_RANDOM */
+
#ifdef HASXDMAUTH
static void
InitXdmcpWrapper (void)
{
+ u_int32_t sum[4];
#ifdef ARC4_RANDOM
- u_int32_t sum[2];
-
sum[0] = arc4random();
sum[1] = arc4random();
*(u_char *)sum = 0;
- _XdmcpWrapperToOddParity(sum, key);
+ _XdmcpWrapperToOddParity((unsigned char *)sum, key);
+#else
+ unsigned char tmpkey[8];
-#elif defined(DEV_RANDOM)
+#ifdef DEV_RANDOM
int fd;
- unsigned char tmpkey[8];
- if ((fd = open(DEV_RANDOM, O_RDONLY)) >= 0) {
- if (read(fd, tmpkey, 8) == 8) {
+ if ((fd = open(randomDevice, O_RDONLY)) >= 0) {
+ if (pollRandomDevice(fd) && read(fd, tmpkey, 8) == 8) {
tmpkey[0] = 0;
_XdmcpWrapperToOddParity(tmpkey, key);
close(fd);
@@ -133,15 +369,27 @@ InitXdmcpWrapper (void)
} else {
close(fd);
}
+ } else {
+ LogError("Cannot open randomDevice \"%s\", errno = %d\n",
+ randomDevice, errno);
}
-#else
- long sum[2];
- unsigned char tmpkey[8];
-
- if (!sumFile (randomFile, sum)) {
- sum[0] = time ((Time_t *) 0);
- sum[1] = time ((Time_t *) 0);
+#endif
+ /* Try some pseudo-random number genrator daemon next */
+ if (prngdSocket != NULL || prngdPort != 0) {
+ if (get_prngd_bytes(tmpkey, sizeof(tmpkey), prngdPort,
+ prngdSocket) == 0) {
+ tmpkey[0] = 0;
+ _XdmcpWrapperToOddParity(tmpkey, key);
+ return;
+ }
}
+ /* Fall back if no other source of random number was found */
+ AddPreGetEntropy();
+ pmd5_hash (sum, epool);
+ add_entropy (sum, 1);
+ pmd5_hash (sum, epool + 16);
+ add_entropy (sum + 2, 1);
+
longtochars (sum[0], tmpkey+0);
longtochars (sum[1], tmpkey+4);
tmpkey[0] = 0;
@@ -151,115 +399,84 @@ InitXdmcpWrapper (void)
#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(void)
-{
- next = next * 1103515245 + 12345;
- return (unsigned int)(next/65536) % 32768;
-}
-
-static void
-xdm_srand(unsigned int seed)
-{
- next = seed;
-}
-#endif /* no HASXDMAUTH */
-void
+int
GenerateAuthData (char *auth, int len)
{
+#ifdef HASXDMAUTH
+ int i, bit;
+ auth_wrapper_schedule schedule;
+ unsigned char data[8];
+ static int xdmcpAuthInited;
long ldata[2];
#ifdef ITIMER_REAL
- {
- struct timeval now;
+ struct timeval now;
- X_GETTIMEOFDAY (&now);
- ldata[0] = now.tv_usec;
- ldata[1] = now.tv_sec;
- }
+ X_GETTIMEOFDAY (&now);
+ ldata[0] = now.tv_usec;
+ ldata[1] = now.tv_sec;
#else
- {
-#ifndef __UNIXOS2__
- long time ();
-#endif
-
- ldata[0] = time ((long *) 0);
- ldata[1] = getpid ();
- }
+ ldata[0] = time ((long *) 0);
+ ldata[1] = getpid ();
#endif
-#ifdef HASXDMAUTH
- {
- int bit;
- int i;
- auth_wrapper_schedule schedule;
- unsigned char data[8];
- static int xdmcpAuthInited;
- longtochars (ldata[0], data+0);
- longtochars (ldata[1], data+4);
- if (!xdmcpAuthInited)
- {
- InitXdmcpWrapper ();
- xdmcpAuthInited = 1;
+ longtochars (ldata[0], data+0);
+ longtochars (ldata[1], data+4);
+ if (!xdmcpAuthInited)
+ {
+ InitXdmcpWrapper ();
+ xdmcpAuthInited = 1;
+ }
+ _XdmcpAuthSetup (key, schedule);
+ for (i = 0; i < len; i++) {
+ auth[i] = 0;
+ for (bit = 1; bit < 256; bit <<= 1) {
+ _XdmcpAuthDoIt (data, data, schedule, 1);
+ if ((data[0] + data[1]) & 0x4)
+ auth[i] |= bit;
}
- _XdmcpAuthSetup (key, schedule);
- for (i = 0; i < len; i++) {
- auth[i] = 0;
- for (bit = 1; bit < 256; bit <<= 1) {
- _XdmcpAuthDoIt (data, data, schedule, 1);
- if ((data[0] + data[1]) & 0x4)
- auth[i] |= bit;
- }
- }
}
-#else
- {
- int seed;
- int value;
- int i;
- static long localkey[2] = {0,0};
-
- if ( (localkey[0] == 0) && (localkey[1] == 0) ) {
+#else /* !XDMAUTH */
#ifdef ARC4_RANDOM
- localkey[0] = arc4random();
- localkey[1] = arc4random();
-#elif defined(DEV_RANDOM)
- int fd;
+ unsigned int *rnd = (unsigned*)auth;
+ int i;
+
+ for (i = 0; i < len; i += 4)
+ rnd[i / 4] = arc4random();
+ return 1;
+#else /* !ARC4_RANDOM */
+ unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
+#ifdef DEV_RANDOM
+ int fd;
- if ((fd = open(DEV_RANDOM, O_RDONLY)) >= 0) {
- if (read(fd, (char *)localkey, 8) != 8) {
- localkey[0] = 1;
- }
- close(fd);
- } else {
- localkey[0] = 1;
- }
-#else
- if (!sumFile (randomFile, localkey)) {
- localkey[0] = 1; /* To keep from continually calling sumFile() */
- }
-#endif
+ if ((fd = open(randomDevice, O_RDONLY)) >= 0) {
+ if (pollRandomDevice(fd) &&
+ read(fd, auth, len) == len) {
+ close(fd);
+ return 1;
}
-
- seed = (ldata[0]+localkey[0]) + ((ldata[1]+localkey[1]) << 16);
- xdm_srand (seed);
- for (i = 0; i < len; i++)
- {
- value = xdm_rand ();
- auth[i] = (value & 0xff00) >> 8;
- }
- value = len;
- if (value > sizeof (key))
- value = sizeof (key);
- memmove( (char *) key, auth, value);
+ close(fd);
+ LogError("Cannot read randomDevice \"%s\", errno=%d\n",
+ randomDevice, errno);
+ } else
+ LogError("Cannot open randomDevice \"%s\", errno = %d\n",
+ randomDevice, errno);
+#endif /* DEV_RANDOM */
+ /* Try some pseudo-random number genrator daemon next */
+ if (prngdSocket != NULL || prngdPort != 0) {
+ if (get_prngd_bytes(auth, len, prngdPort, prngdSocket) == 0) {
+ return 1;
+ }
}
-#endif
+ /* Fallback if not able to get from /dev/random */
+ AddPreGetEntropy();
+ pmd5_hash (tmp, epool);
+ add_entropy (tmp, 1);
+ pmd5_hash (tmp, epool + 16);
+ add_entropy (tmp + 2, 1);
+ memcpy (auth, tmp, len);
+ return 1;
+#endif /* !ARC4_RANDOM */
+#endif /* !HASXDMAUTH */
}
diff --git a/greet.h b/greet.h
index e826d40..238d587 100644
--- a/greet.h
+++ b/greet.h
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/greet.h,v 1.8 2001/12/14 20:01:22 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/greet.h,v 1.10 2003/09/21 13:03:03 herrb Exp $ */
/*
* greet.h - interface to xdm's dynamically-loadable modular greeter
@@ -37,7 +37,7 @@ from The Open Group.
/*
* Do this rather than break a build over a const-mismatch
*/
-#if defined(__linux__) || defined(CSRG_BASED)
+#if defined(__linux__) || defined(CSRG_BASED) || (defined(sun) && defined(SVR4))
#define CRYPT_ARGS const char *s1, const char *s2
#define GETSPNAM_ARGS const char *name
#define GETPWNAM_ARGS const char *name
@@ -120,25 +120,11 @@ typedef enum {
* option such as SECURE_RPC or K5AUTH.
*/
-extern greet_user_rtn GreetUser(
-#if NeedFunctionPrototypes
- struct display *d,
- Display **dpy,
- struct verify_info *verify,
- struct greet_info *greet,
- struct dlfuncs *dlfcns
-#endif
-);
-
-typedef greet_user_rtn (*GreetUserProc)(
-#if NeedFunctionPrototypes
- struct display *,
- Display **,
- struct verify_info *,
- struct greet_info *,
- struct dlfuncs *dlfcns
-#endif
-);
+extern greet_user_rtn GreetUser(struct display *, Display **,
+ struct verify_info *, struct greet_info *, struct dlfuncs *);
+
+typedef greet_user_rtn (*GreetUserProc)(struct display *, Display **,
+ struct verify_info *, struct greet_info *, struct dlfuncs *dlfcns);
#ifdef GREET_LIB
/*
diff --git a/greeter/Login.c b/greeter/Login.c
index df91b0d..f8c983b 100644
--- a/greeter/Login.c
+++ b/greeter/Login.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/greeter/Login.c,v 3.16 2002/10/06 20:42:16 herrb Exp $ */
+/* $XFree86: xc/programs/xdm/greeter/Login.c,v 3.18 2003/07/09 15:27:40 tsi Exp $ */
/*
* xdm - display manager daemon
@@ -137,7 +137,12 @@ static XtResource resources[] = {
{XtNpasswdPrompt, XtCPasswdPrompt, XtRString, sizeof (char *),
offset(passwdPrompt), XtRString, "Password: "},
{XtNfail, XtCFail, XtRString, sizeof (char *),
- offset(fail), XtRString, "Login incorrect"},
+ offset(fail), XtRString,
+#if defined(sun) && defined(SVR4)
+ "Login incorrect or not on system console if root"},
+#else
+ "Login incorrect"},
+#endif
{XtNfailTimeout, XtCFailTimeout, XtRInt, sizeof (int),
offset(failTimeout), XtRImmediate, (XtPointer) 10},
{XtNnotifyDone, XtCCallback, XtRFunction, sizeof (XtPointer),
@@ -1108,7 +1113,6 @@ static void Initialize (
w->login.logoValid = False;
goto SkipXpmLoad;
}
- else
myAttributes.valuemask |= XpmReturnPixels;
myAttributes.valuemask |= XpmReturnExtensions;
diff --git a/greeter/Login.h b/greeter/Login.h
index 08578f3..ecbb5d5 100644
--- a/greeter/Login.h
+++ b/greeter/Login.h
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/greeter/Login.h,v 3.7 2002/10/06 20:42:16 herrb Exp $ */
+/* $XFree86: xc/programs/xdm/greeter/Login.h,v 3.8 2003/11/19 04:44:00 dawes Exp $ */
/*
* xdm - display manager daemon
@@ -114,7 +114,15 @@ from The Open Group.
/* notifyDone interface definition */
-#ifndef __OpenBSD__
+#ifdef __OpenBSD__
+#include <sys/param.h>
+/* 2.8 (200012) doesn't have _PW_NAME_LEN */
+#if OpenBSD > 200012
+#define HAVE_PW_NAME_LEN
+#endif
+#endif
+
+#ifndef HAVE_PW_NAME_LEN
#define NAME_LEN 32
#define PASSWORD_LEN 32
#else
diff --git a/greeter/greet.c b/greeter/greet.c
index 5af88e8..e0b9c06 100644
--- a/greeter/greet.c
+++ b/greeter/greet.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/greeter/greet.c,v 3.16 2002/10/06 20:42:16 herrb Exp $ */
+/* $XFree86: xc/programs/xdm/greeter/greet.c,v 3.17 2003/07/09 15:27:40 tsi Exp $ */
/*
* xdm - display manager daemon
@@ -145,8 +145,10 @@ GreetDone (
data->name, strlen (data->passwd));
switch (status) {
case NOTIFY_OK:
- strcpy (name, data->name);
- strcpy (password, data->passwd);
+ strncpy (name, data->name, sizeof(name));
+ name[sizeof(name)-1] = '\0';
+ strncpy (password, data->passwd, sizeof(password));
+ password[sizeof(password)-1] = '\0';
bzero (data->passwd, PASSWORD_LEN);
code = 0;
done = 1;
@@ -280,6 +282,9 @@ CloseGreet (struct display *d)
Debug ("Greet connection closed\n");
}
+#define WHITESPACE 0
+#define ARGUMENT 1
+
static int
Greet (struct display *d, struct greet_info *greet)
{
@@ -306,7 +311,23 @@ Greet (struct display *d, struct greet_info *greet)
Debug ("Done dispatch %s\n", d->name);
if (code == 0)
{
- greet->name = name;
+ char *ptr;
+ unsigned int c,state = WHITESPACE;
+
+ /*
+ * Process the name string to get rid of white spaces.
+ */
+ for (ptr = name; state == WHITESPACE; ptr++)
+ {
+ c = (unsigned int)(*ptr);
+ if (c == ' ')
+ continue;
+
+ state = ARGUMENT;
+ break;
+ }
+
+ greet->name = ptr;
greet->password = password;
XtSetArg (arglist[0], XtNsessionArgument, (char *) &(greet->string));
XtSetArg (arglist[1], XtNallowNullPasswd, (char *) &(greet->allow_null_passwd));
diff --git a/greeter/verify.c b/greeter/verify.c
index 182fef4..0fcb320 100644
--- a/greeter/verify.c
+++ b/greeter/verify.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/greeter/verify.c,v 3.24 2002/11/26 01:16:09 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/greeter/verify.c,v 3.26 2003/11/19 04:44:00 dawes Exp $ */
/*
* xdm - display manager daemon
@@ -79,6 +79,10 @@ static char *envvars[] = {
#ifdef KERBEROS
#include <sys/param.h>
#include <kerberosIV/krb.h>
+/* OpenBSD 2.8 needs this. */
+#ifdef OpenBSD && OpenBSD <= 200012
+#include <kerberosIV/kafs.h>
+#endif
static char krbtkfile[MAXPATHLEN];
#endif
@@ -304,6 +308,47 @@ Verify (struct display *d, struct greet_info *greet, struct verify_info *verify)
char **argv;
Debug ("Verify %s ...\n", greet->name);
+
+#if defined(sun) && defined(SVR4)
+ /* Solaris: If CONSOLE is set to /dev/console in /etc/default/login,
+ then root can only login on system console */
+
+# define SOLARIS_LOGIN_DEFAULTS "/etc/default/login"
+
+ if (strcmp(greet->name, "root") == 0) {
+ char *console = NULL, *tmp = NULL;
+ FILE *fs;
+
+ if ((fs= fopen(SOLARIS_LOGIN_DEFAULTS, "r")) != NULL)
+ {
+ char str[120];
+ while (!feof(fs))
+ {
+ fgets(str, 120, fs);
+ if(str[0] == '#' || strlen(str) < 8)
+ continue;
+ if((tmp = strstr(str, "CONSOLE=")) != NULL)
+ console = strdup((tmp+8));
+ }
+ fclose(fs);
+ if ( console != NULL &&
+ (strncmp(console, "/dev/console", 12) == 0) &&
+ (strncmp(d->name,":0",2) != 0) )
+ {
+ Debug("Not on system console\n");
+ bzero(greet->password, strlen(greet->password));
+ XFree(console);
+ return 0;
+ }
+ Xfree(console);
+ }
+ else
+ {
+ Debug("Could not open %s\n", SOLARIS_LOGIN_DEFAULTS);
+ }
+ }
+#endif
+
#ifndef USE_PAM
p = getpwnam (greet->name);
endpwent();
diff --git a/mitauth.c b/mitauth.c
index 6c0ad9c..2b2dd31 100644
--- a/mitauth.c
+++ b/mitauth.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/mitauth.c,v 1.4 2001/12/14 20:01:22 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/mitauth.c,v 1.6 2003/09/17 05:48:32 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -45,14 +45,12 @@ from The Open Group.
# define AUTH_DATA_LEN 16 /* bytes of authorization data */
static char auth_name[256];
-static int auth_name_len;
void
MitInitAuth (unsigned short name_len, char *name)
{
if (name_len > 256)
name_len = 256;
- auth_name_len = name_len;
memmove( auth_name, name, name_len);
}
@@ -85,7 +83,13 @@ MitGetAuth (unsigned short namelen, char *name)
}
memmove( (char *)new->name, name, namelen);
new->name_length = namelen;
- GenerateAuthData (new->data, AUTH_DATA_LEN);
+ if (!GenerateAuthData (new->data, AUTH_DATA_LEN))
+ {
+ free((char *) new->name);
+ free((char *) new->data);
+ free((char *) new);
+ return (Xauth *) 0;
+ }
new->data_length = AUTH_DATA_LEN;
return new;
}
diff --git a/netaddr.c b/netaddr.c
index 02cde08..776e23a 100644
--- a/netaddr.c
+++ b/netaddr.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/netaddr.c,v 3.6 2001/12/14 20:01:22 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/netaddr.c,v 3.8 2003/07/18 15:53:28 tsi Exp $ */
/*
* xdm - X display manager
@@ -85,6 +85,11 @@ char * NetaddrPort(XdmcpNetaddr netaddrp, int *lenp)
case AF_INET:
*lenp = 2;
return (char *)&(((struct sockaddr_in *)netaddrp)->sin_port);
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ *lenp = 2;
+ return (char *)&(((struct sockaddr_in6 *)netaddrp)->sin6_port);
+#endif
default:
*lenp = 0;
return NULL;
@@ -112,6 +117,19 @@ char * NetaddrAddress(XdmcpNetaddr netaddrp, int *lenp)
case AF_INET:
*lenp = sizeof (struct in_addr);
return (char *) &(((struct sockaddr_in *)netaddrp)->sin_addr);
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ {
+ struct in6_addr *a = &(((struct sockaddr_in6 *)netaddrp)->sin6_addr);
+ if (IN6_IS_ADDR_V4MAPPED(a)) {
+ *lenp = sizeof (struct in_addr);
+ return ((char *) &(a->s6_addr))+12;
+ } else {
+ *lenp = sizeof (struct in6_addr);
+ return (char *) &(a->s6_addr);
+ }
+ }
+#endif
#endif
#ifdef DNETCONN
case AF_DECnet:
@@ -163,6 +181,14 @@ int ConvertAddr (XdmcpNetaddr saddr, int *len, char **addr)
case AF_INET:
retval = FamilyInternet;
break;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ if (*len == sizeof(struct in_addr))
+ retval = FamilyInternet;
+ else
+ retval = FamilyInternet6;
+ break;
+#endif
#endif
#ifdef DNETCONN
case AF_DECnet:
@@ -231,8 +257,21 @@ PrintSockAddr (struct sockaddr *a, int len)
Debug ("port %d, host %d.%d.%d.%d\n",
(p[0] << 8) + p[1], t[0], t[1], t[2], t[3]);
break;
+#endif
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ {
+ char astr[INET6_ADDRSTRLEN] = "";
+
+ inet_ntop(a->sa_family, &((struct sockaddr_in6 *) a)->sin6_addr,
+ astr, sizeof(astr));
+ p = (unsigned char *) &((struct sockaddr_in6 *) a)->sin6_port;
+
+ Debug ("port %d, host %s\n", (p[0] << 8) + p[1], astr);
+ break;
}
#endif
+ }
}
#endif
diff --git a/resource.c b/resource.c
index 982dd8e..e9b1e6c 100644
--- a/resource.c
+++ b/resource.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/resource.c,v 3.10 2002/12/07 20:31:04 herrb Exp $ */
+/* $XFree86: xc/programs/xdm/resource.c,v 3.12 2003/09/17 05:48:32 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -57,7 +57,17 @@ int removeDomainname;
char *keyFile;
char *accessFile;
char **exportList;
+#if !defined(ARC4_RANDOM)
char *randomFile;
+#endif
+#ifdef DEV_RANDOM
+char *randomDevice;
+#endif
+#if !defined(ARC4_RANDOM)
+char *prngdSocket;
+int prngdPort;
+#endif
+
char *greeterLib;
char *willing;
int choiceTimeout; /* chooser choice timeout */
@@ -72,6 +82,7 @@ int choiceTimeout; /* chooser choice timeout */
* parameters set util/imake.includes/site.def (or *.macros in that directory
* if it is server-specific). DO NOT CHANGE THESE DEFINITIONS!
*/
+#ifndef __EMX__
#ifndef DEF_SERVER_LINE
#define DEF_SERVER_LINE ":0 local /usr/bin/X11/X :0"
#endif
@@ -119,15 +130,74 @@ int choiceTimeout; /* chooser choice timeout */
#define DEF_ACCESS_FILE ""
#endif
#ifndef DEF_RANDOM_FILE
-# ifdef linux
-# define DEF_RANDOM_FILE "/dev/urandom"
-# else
-# define DEF_RANDOM_FILE "/dev/mem"
-# endif
+#define DEF_RANDOM_FILE "/dev/mem"
+#endif
+#ifndef DEF_PRNGD_SOCKET
+#define DEF_PRNGD_SOCKET "/tmp/entropy"
+#endif
+#ifndef DEF_PRNGD_PORT
+#define DEF_PRNGD_PORT "0"
#endif
#ifndef DEF_GREETER_LIB
#define DEF_GREETER_LIB "/usr/lib/X11/xdm/libXdmGreet.so"
#endif
+#else
+/* unfortunately I have to declare all of them, because there is a limit
+ * in argument size in OS/2
+ * but everything needs to be fixed again
+ */
+#define DEF_SERVER_LINE ":0 local /XFree86/bin/X :0"
+#ifndef XRDB_PROGRAM
+#define XRDB_PROGRAM "/XFree86/bin/xrdb"
+#endif
+#ifndef DEF_SESSION
+#define DEF_SESSION "/XFree86/bin/xterm -ls"
+#endif
+#ifndef DEF_USER_PATH
+#define DEF_USER_PATH "c:\\os2;c:\\os2\apps;\\XFree86\\bin"
+#endif
+#ifndef DEF_SYSTEM_PATH
+#define DEF_SYSTEM_PATH "c:\\os2;c:\\os2\apps;\\XFree86\\bin"
+#endif
+#ifndef DEF_SYSTEM_SHELL
+#define DEF_SYSTEM_SHELL "sh"
+#endif
+#ifndef DEF_FAILSAFE_CLIENT
+#define DEF_FAILSAFE_CLIENT "/XFree86/bin/xterm"
+#endif
+#ifndef DEF_XDM_CONFIG
+#define DEF_XDM_CONFIG "/XFree86/lib/X11/xdm/xdm-config"
+#endif
+#ifndef DEF_CHOOSER
+#define DEF_CHOOSER "/XFree86/lib/X11/xdm/chooser"
+#endif
+#ifndef DEF_AUTH_NAME
+#ifdef HASXDMAUTH
+#define DEF_AUTH_NAME "XDM-AUTHORIZATION-1 MIT-MAGIC-COOKIE-1"
+#else
+#define DEF_AUTH_NAME "MIT-MAGIC-COOKIE-1"
+#endif
+#endif
+#ifndef DEF_AUTH_DIR
+#define DEF_AUTH_DIR "/XFree86/lib/X11/xdm"
+#endif
+#ifndef DEF_USER_AUTH_DIR
+#define DEF_USER_AUTH_DIR "/tmp"
+#endif
+#ifndef DEF_KEY_FILE
+#define DEF_KEY_FILE ""
+#endif
+#ifndef DEF_ACCESS_FILE
+#define DEF_ACCESS_FILE ""
+#endif
+#ifndef DEF_RANDOM_FILE
+#define DEF_RANDOM_FILE ""
+#endif
+#ifndef DEF_GREETER_LIB
+#define DEF_GREETER_LIB "/XFree86/lib/X11/xdm/libXdmGreet.so"
+#endif
+
+#endif /* __EMX__ */
#define DEF_UDP_PORT "177" /* registered XDMCP port, dont change */
@@ -163,8 +233,18 @@ struct dmResources {
DEF_ACCESS_FILE} ,
{ "exportList", "ExportList", DM_ARGV, (char **) &exportList,
""} ,
+#if !defined(ARC4_RANDOM)
{ "randomFile", "RandomFile", DM_STRING, &randomFile,
DEF_RANDOM_FILE} ,
+{ "prgndSocket", "PrngdSocket", DM_STRING, &prngdSocket,
+ DEF_PRNGD_SOCKET},
+{ "prngdPort", "PrngdPort", DM_INT, (char **) &prngdPort,
+ DEF_PRNGD_PORT},
+#endif
+#ifdef DEV_RANDOM
+{ "randomDevice", "RandomDevice", DM_STRING, &randomDevice,
+ DEV_RANDOM} ,
+#endif
{ "greeterLib", "GreeterLib", DM_STRING, &greeterLib,
DEF_GREETER_LIB} ,
{ "choiceTimeout","ChoiceTimeout",DM_INT, (char **) &choiceTimeout,
diff --git a/server.c b/server.c
index 2ee5bba..d537ddc 100644
--- a/server.c
+++ b/server.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/server.c,v 3.13 2001/12/14 20:01:23 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/server.c,v 3.14 2003/04/12 16:42:14 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -190,14 +190,26 @@ serverPause (unsigned t, int serverPid)
#endif
for (;;) {
#if defined(SYSV) && defined(X_NOT_POSIX)
+ /*
+ * wait() is unsafe. Other Xserver or xdm processes may
+ * exit at this time and this will remove the wait status.
+ * This means the main loop will not restart the display.
+ */
pid = wait ((waitType *) 0);
#else
if (!receivedUsr1)
- pid = wait ((waitType *) 0);
- else
#ifndef X_NOT_POSIX
- pid = waitpid (-1, (int *) 0, WNOHANG);
+ pid = waitpid (serverPid, (int *) 0, 0);
+ else
+ pid = waitpid (serverPid, (int *) 0, WNOHANG);
#else
+ /*
+ * If you have wait4() but not waitpid(), use that instead
+ * of wait() and wait3() to make this code safe. See
+ * above comment.
+ */
+ pid = wait ((waitType *) 0);
+ else
pid = wait3 ((waitType *) 0, WNOHANG,
(struct rusage *) 0);
#endif /* X_NOT_POSIX */
diff --git a/session.c b/session.c
index 9befc15..58274a4 100644
--- a/session.c
+++ b/session.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/session.c,v 3.33 2001/12/14 20:01:23 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/session.c,v 3.36 2003/09/29 21:00:08 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -54,23 +54,24 @@ from The Open Group.
#ifdef SECURE_RPC
# include <rpc/rpc.h>
# include <rpc/key_prot.h>
+extern int key_setnet(struct key_netstarg *arg);
#endif
#ifdef K5AUTH
# include <krb5/krb5.h>
#endif
#ifndef GREET_USER_STATIC
-#include <dlfcn.h>
-#ifndef RTLD_NOW
-#define RTLD_NOW 1
-#endif
+# include <dlfcn.h>
+# ifndef RTLD_NOW
+# define RTLD_NOW 1
+# endif
#endif
static int runAndWait (char **args, char **environ);
-#if defined(CSRG_BASED) || defined(__osf__) || defined(__DARWIN__) || defined(__QNXNTO__)
-#include <sys/types.h>
-#include <grp.h>
+#if defined(CSRG_BASED) || defined(__osf__) || defined(__DARWIN__) || defined(__QNXNTO__) || defined(sun) || defined(__GLIBC__)
+# include <sys/types.h>
+# include <grp.h>
#else
/* should be in <grp.h> */
extern void setgrent(void);
@@ -79,27 +80,34 @@ extern void endgrent(void);
#endif
#ifdef USESHADOW
+# if defined(SVR4)
+# include <shadow.h>
+# else
extern struct spwd *getspnam(GETSPNAM_ARGS);
extern void endspent(void);
+# endif
#endif
-#if defined(CSRG_BASED)
-#include <pwd.h>
-#include <unistd.h>
+#if defined(CSRG_BASED) || defined(__GLIBC__)
+# include <pwd.h>
+# include <unistd.h>
#else
extern struct passwd *getpwnam(GETPWNAM_ARGS);
-#ifdef linux
+# ifdef linux
extern void endpwent(void);
-#endif
+# endif
extern char *crypt(CRYPT_ARGS);
#endif
+
#ifdef USE_PAM
-pam_handle_t **thepamhp()
+pam_handle_t **
+thepamhp(void)
{
static pam_handle_t *pamh = NULL;
return &pamh;
}
-pam_handle_t *thepamh()
+pam_handle_t *
+thepamh(void)
{
pam_handle_t **pamhp;
@@ -136,12 +144,12 @@ static struct dlfuncs dlfuncs = {
endgrent,
#ifdef USESHADOW
getspnam,
-#ifndef QNX4
+# ifndef QNX4
endspent,
-#endif /* QNX4 doesn't use endspent */
+# endif /* QNX4 doesn't use endspent */
#endif
getpwnam,
-#ifdef linux
+#if defined(linux) || defined(__GLIBC__)
endpwent,
#endif
crypt,
@@ -189,7 +197,7 @@ waitAbort (int n)
}
#if defined(_POSIX_SOURCE) || defined(SYSV) || defined(SVR4)
-#define killpg(pgrp, sig) kill(-(pgrp), sig)
+# define killpg(pgrp, sig) kill(-(pgrp), sig)
#endif
static void
@@ -226,8 +234,7 @@ AbortClient (int pid)
void
SessionPingFailed (struct display *d)
{
- if (clientPid > 1)
- {
+ if (clientPid > 1) {
AbortClient (clientPid);
source (verify.systemEnviron, d->reset);
}
@@ -246,7 +253,7 @@ SessionPingFailed (struct display *d)
static int
IOErrorHandler (Display *dpy)
{
- LogError("fatal IO error %d (%s)\n", errno, _SysErrorMsg(errno));
+ LogError ("fatal IO error %d (%s)\n", errno, _SysErrorMsg(errno));
exit(RESERVER_DISPLAY);
/*NOTREACHED*/
return 0;
@@ -255,7 +262,7 @@ IOErrorHandler (Display *dpy)
static int
ErrorHandler(Display *dpy, XErrorEvent *event)
{
- LogError("X error\n");
+ LogError ("X error\n");
if (XmuPrintDefaultErrorMessage (dpy, event, stderr) == 0) return 0;
exit(UNMANAGE_DISPLAY);
/*NOTREACHED*/
@@ -266,7 +273,7 @@ ManageSession (struct display *d)
{
static int pid = 0;
Display *dpy;
- greet_user_rtn greet_stat;
+ greet_user_rtn greet_stat;
static GreetUserProc greet_user_proc = NULL;
#ifndef GREET_USER_STATIC
void *greet_lib_handle;
@@ -288,13 +295,12 @@ ManageSession (struct display *d)
#ifdef GREET_USER_STATIC
greet_user_proc = GreetUser;
#else
- Debug("ManageSession: loading greeter library %s\n", greeterLib);
+ Debug ("ManageSession: loading greeter library %s\n", greeterLib);
greet_lib_handle = dlopen(greeterLib, RTLD_NOW);
if (greet_lib_handle != NULL)
greet_user_proc = (GreetUserProc)dlsym(greet_lib_handle, "GreetUser");
- if (greet_user_proc == NULL)
- {
- LogError("%s while loading %s\n", dlerror(), greeterLib);
+ if (greet_user_proc == NULL) {
+ LogError ("%s while loading %s\n", dlerror(), greeterLib);
exit(UNMANAGE_DISPLAY);
}
#endif
@@ -306,8 +312,7 @@ ManageSession (struct display *d)
greet.version = 1;
greet_stat = (*greet_user_proc)(d, &dpy, &verify, &greet, &dlfuncs);
- if (greet_stat == Greet_Success)
- {
+ if (greet_stat == Greet_Success) {
clientPid = 0;
if (!Setjmp (abortSession)) {
(void) Signal (SIGTERM, catchTerm);
@@ -322,29 +327,23 @@ ManageSession (struct display *d)
/* Save memory; close library */
dlclose(greet_lib_handle);
#endif
-
+
/*
* Wait for session to end,
*/
for (;;) {
- if (d->pingInterval)
- {
- if (!Setjmp (pingTime))
- {
+ if (d->pingInterval) {
+ if (!Setjmp (pingTime)) {
(void) Signal (SIGALRM, catchAlrm);
(void) alarm (d->pingInterval * 60);
pid = wait ((waitType *) 0);
(void) alarm (0);
- }
- else
- {
+ } else {
(void) alarm (0);
if (!PingServer (d, (Display *) NULL))
SessionPingFailed (d);
}
- }
- else
- {
+ } else {
pid = wait ((waitType *) 0);
}
if (pid == clientPid)
@@ -391,8 +390,7 @@ SetupDisplay (struct display *d)
{
char **env = 0;
- if (d->setup && d->setup[0])
- {
+ if (d->setup && d->setup[0]) {
env = systemEnv (d, (char *) 0, (char *) 0);
(void) source (env, d->setup);
freeEnv (env);
@@ -436,8 +434,7 @@ SecureDisplay (struct display *d, Display *dpy)
Debug ("Before XGrabServer %s\n", d->name);
XGrabServer (dpy);
if (XGrabKeyboard (dpy, DefaultRootWindow (dpy), True, GrabModeAsync,
- GrabModeAsync, CurrentTime) != GrabSuccess)
- {
+ GrabModeAsync, CurrentTime) != GrabSuccess) {
(void) alarm (0);
(void) Signal (SIGALRM, SIG_DFL);
LogError ("WARNING: keyboard on display %s could not be secured\n",
@@ -448,8 +445,7 @@ SecureDisplay (struct display *d, Display *dpy)
(void) alarm (0);
(void) Signal (SIGALRM, SIG_DFL);
pseudoReset (dpy);
- if (!d->grabServer)
- {
+ if (!d->grabServer) {
XUngrabServer (dpy);
XSync (dpy, 0);
}
@@ -460,8 +456,7 @@ void
UnsecureDisplay (struct display *d, Display *dpy)
{
Debug ("Unsecure display %s\n", d->name);
- if (d->grabServer)
- {
+ if (d->grabServer) {
XUngrabServer (dpy);
XSync (dpy, 0);
}
@@ -487,8 +482,7 @@ SessionExit (struct display *d, int status, int removeAuth)
kill (d->serverPid, d->resetSignal);
else
ResetServer (d);
- if (removeAuth)
- {
+ if (removeAuth) {
setgid (verify.gid);
setuid (verify.uid);
RemoveUserAuthorization (d, &verify);
@@ -500,7 +494,7 @@ SessionExit (struct display *d, int status, int removeAuth)
code = Krb5DisplayCCache(d->name, &ccache);
if (code)
- LogError("%s while getting Krb5 ccache to destroy\n",
+ LogError ("%s while getting Krb5 ccache to destroy\n",
error_message(code));
else {
code = krb5_cc_destroy(ccache);
@@ -508,7 +502,7 @@ SessionExit (struct display *d, int status, int removeAuth)
if (code == KRB5_FCC_NOFILE) {
Debug ("No Kerberos ccache file found to destroy\n");
} else
- LogError("%s while destroying Krb5 credentials cache\n",
+ LogError ("%s while destroying Krb5 credentials cache\n",
error_message(code));
} else
Debug ("Kerberos ccache destroyed\n");
@@ -535,8 +529,9 @@ StartClient (
#ifdef HAS_SETUSERCONTEXT
struct passwd* pwd;
#endif
-#ifdef USE_PAM
- pam_handle_t *pamh = thepamh();
+#ifdef USE_PAM
+ pam_handle_t *pamh = thepamh ();
+ int pam_error;
#endif
if (verify->argv) {
@@ -552,7 +547,7 @@ StartClient (
}
#ifdef USE_PAM
if (pamh) pam_open_session(pamh, 0);
-#endif
+#endif
switch (pid = fork ()) {
case 0:
CleanUpChild ();
@@ -577,34 +572,35 @@ StartClient (
#ifndef AIXV3
#ifndef HAS_SETUSERCONTEXT
- if (setgid(verify->gid) < 0)
- {
- LogError("setgid %d (user \"%s\") failed, errno=%d\n",
+ if (setgid(verify->gid) < 0) {
+ LogError ("setgid %d (user \"%s\") failed, errno=%d\n",
verify->gid, name, errno);
return (0);
}
#if defined(BSD) && (BSD >= 199103)
- if (setlogin(name) < 0)
- {
- LogError("setlogin for \"%s\" failed, errno=%d", name, errno);
+ if (setlogin(name) < 0) {
+ LogError ("setlogin for \"%s\" failed, errno=%d", name, errno);
return(0);
}
#endif
#ifndef QNX4
- if (initgroups(name, verify->gid) < 0)
- {
- LogError("initgroups for \"%s\" failed, errno=%d\n", name, errno);
+ if (initgroups(name, verify->gid) < 0) {
+ LogError ("initgroups for \"%s\" failed, errno=%d\n", name, errno);
return (0);
}
#endif /* QNX4 doesn't support multi-groups, no initgroups() */
#ifdef USE_PAM
- if (thepamh()) {
- pam_setcred(thepamh(), PAM_ESTABLISH_CRED);
+ if (pamh) {
+ pam_error = pam_setcred (pamh, PAM_ESTABLISH_CRED);
+ if (pam_error != PAM_SUCCESS) {
+ LogError ("pam_setcred for \"%s\" failed: %s\n",
+ name, pam_strerror(pamh, pam_error));
+ return(0);
+ }
}
#endif
- if (setuid(verify->uid) < 0)
- {
- LogError("setuid %d (user \"%s\") failed, errno=%d\n",
+ if (setuid(verify->uid) < 0) {
+ LogError ("setuid %d (user \"%s\") failed, errno=%d\n",
verify->uid, name, errno);
return (0);
}
@@ -614,19 +610,15 @@ StartClient (
* environment variables, resource limits, and umask.
*/
pwd = getpwnam(name);
- if (pwd)
- {
- if (setusercontext(NULL, pwd, pwd->pw_uid, LOGIN_SETALL) < 0)
- {
- LogError("setusercontext for \"%s\" failed, errno=%d\n", name,
+ if (pwd) {
+ if (setusercontext(NULL, pwd, pwd->pw_uid, LOGIN_SETALL) < 0) {
+ LogError ("setusercontext for \"%s\" failed, errno=%d\n", name,
errno);
return (0);
}
endpwent();
- }
- else
- {
- LogError("getpwnam for \"%s\" failed, errno=%d\n", name, errno);
+ } else {
+ LogError ("getpwnam for \"%s\" failed, errno=%d\n", name, errno);
return (0);
}
#endif /* HAS_SETUSERCONTEXT */
@@ -635,9 +627,8 @@ StartClient (
* Set the user's credentials: uid, gid, groups,
* audit classes, user limits, and umask.
*/
- if (setpcred(name, NULL) == -1)
- {
- LogError("setpcred for \"%s\" failed, errno=%d\n", name, errno);
+ if (setpcred(name, NULL) == -1) {
+ LogError ("setpcred for \"%s\" failed, errno=%d\n", name, errno);
return (0);
}
#endif /* AIXV3 */
@@ -652,6 +643,7 @@ StartClient (
char netname[MAXNETNAMELEN+1], secretkey[HEXKEYBYTES+1];
int nameret, keyret;
int len;
+ struct key_netstarg netst;
int key_set_ok = 0;
nameret = getnetname (netname);
@@ -662,34 +654,34 @@ StartClient (
keyret = getsecretkey(netname,secretkey,passwd);
Debug ("getsecretkey returns %d, key length %d\n",
keyret, strlen (secretkey));
+ memcpy(&(netst.st_priv_key), secretkey, HEXKEYBYTES);
+ netst.st_netname = strdup(netname);
+ memset(netst.st_pub_key, 0, HEXKEYBYTES);
+ if (key_setnet(&netst) < 0) {
+ Debug ("Could not set secret key.\n");
+ }
+ free(netst.st_netname);
/* is there a key, and do we have the right password? */
- if (keyret == 1)
- {
- if (*secretkey)
- {
+ if (keyret == 1) {
+ if (*secretkey) {
keyret = key_setsecret(secretkey);
Debug ("key_setsecret returns %d\n", keyret);
if (keyret == -1)
LogError ("failed to set NIS secret key\n");
else
key_set_ok = 1;
- }
- else
- {
+ } else {
/* found a key, but couldn't interpret it */
LogError ("password incorrect for NIS principal \"%s\"\n",
nameret ? netname : name);
}
}
- if (!key_set_ok)
- {
+ if (!key_set_ok) {
/* remove SUN-DES-1 from authorizations list */
int i, j;
- for (i = 0; i < d->authNum; i++)
- {
+ for (i = 0; i < d->authNum; i++) {
if (d->authorizations[i]->name_length == 9 &&
- memcmp(d->authorizations[i]->name, "SUN-DES-1", 9) == 0)
- {
+ memcmp(d->authorizations[i]->name, "SUN-DES-1", 9) == 0) {
for (j = i+1; j < d->authNum; j++)
d->authorizations[j-1] = d->authorizations[j];
d->authNum--;
@@ -714,11 +706,9 @@ StartClient (
setEnv(verify->userEnviron,
"KRB5CCNAME", Krb5CCacheName(d->name));
} else {
- for (i = 0; i < d->authNum; i++)
- {
+ for (i = 0; i < d->authNum; i++) {
if (d->authorizations[i]->name_length == 14 &&
- memcmp(d->authorizations[i]->name, "MIT-KERBEROS-5", 14) == 0)
- {
+ memcmp(d->authorizations[i]->name, "MIT-KERBEROS-5", 14) == 0) {
/* remove Kerberos from authorizations list */
for (j = i+1; j < d->authNum; j++)
d->authorizations[j-1] = d->authorizations[j];
@@ -773,8 +763,7 @@ source (char **environ, char *file)
if (file && file[0]) {
Debug ("source %s\n", file);
args = parseArgs ((char **) 0, file);
- if (!args)
- {
+ if (!args) {
args = args_safe;
args[0] = file;
args[1] = NULL;
@@ -841,8 +830,7 @@ execute (char **argv, char **environ)
f = fopen (argv[0], "r");
if (!f)
return;
- if (fgets (program, sizeof (program) - 1, f) == NULL)
- {
+ if (fgets (program, sizeof (program) - 1, f) == NULL) {
fclose (f);
return;
}
@@ -894,8 +882,7 @@ defaultEnv (void)
char **env, **exp, *value;
env = 0;
- for (exp = exportList; exp && *exp; ++exp)
- {
+ for (exp = exportList; exp && *exp; ++exp) {
value = getenv (*exp);
if (value)
env = setEnv (env, *exp, value);
@@ -907,13 +894,12 @@ char **
systemEnv (struct display *d, char *user, char *home)
{
char **env;
-
+
env = defaultEnv ();
env = setEnv (env, "DISPLAY", d->name);
if (home)
env = setEnv (env, "HOME", home);
- if (user)
- {
+ if (user) {
env = setEnv (env, "USER", user);
env = setEnv (env, "LOGNAME", user);
}
diff --git a/socket.c b/socket.c
index 83dddf6..b472bfb 100644
--- a/socket.c
+++ b/socket.c
@@ -2,6 +2,7 @@
/*
Copyright 1988, 1998 The Open Group
+Copyright 2002 Sun Microsystems, Inc. All rights reserved.
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@@ -15,18 +16,18 @@ in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
-Except as contained in this notice, the name of The Open Group shall
+Except as contained in this notice, the name of a copyright holder shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
-from The Open Group.
+from the copyright holder.
*/
-/* $XFree86: xc/programs/xdm/socket.c,v 3.10 2001/12/14 20:01:24 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/socket.c,v 3.13 2003/07/18 15:39:52 tsi Exp $ */
/*
* xdm - display manager daemon
@@ -52,9 +53,8 @@ from The Open Group.
#endif
#endif
#include <netdb.h>
+#include <arpa/inet.h>
-
-extern int xdmcpFd;
extern int chooserFd;
extern FD_TYPE WellKnownSocketsMask;
@@ -63,39 +63,14 @@ extern int WellKnownSocketsMax;
void
CreateWellKnownSockets (void)
{
- struct sockaddr_in sock_addr;
- char *name;
-
- if (request_port == 0)
- return;
- Debug ("creating socket %d\n", request_port);
- xdmcpFd = socket (AF_INET, SOCK_DGRAM, 0);
- if (xdmcpFd == -1) {
- LogError ("XDMCP socket creation failed, errno %d\n", errno);
- return;
- }
- name = localHostname ();
+ char *name = localHostname ();
registerHostname (name, strlen (name));
- RegisterCloseOnFork (xdmcpFd);
- /* zero out the entire structure; this avoids 4.4 incompatibilities */
- bzero ((char *) &sock_addr, sizeof (sock_addr));
-#ifdef BSD44SOCKETS
- sock_addr.sin_len = sizeof(sock_addr);
-#endif
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_port = htons ((short) request_port);
- sock_addr.sin_addr.s_addr = htonl (INADDR_ANY);
- if (bind (xdmcpFd, (struct sockaddr *)&sock_addr, sizeof (sock_addr)) == -1)
- {
- LogError ("error %d binding socket address %d\n", errno, request_port);
- close (xdmcpFd);
- xdmcpFd = -1;
- return;
- }
- WellKnownSocketsMax = xdmcpFd;
- FD_SET (xdmcpFd, &WellKnownSocketsMask);
+#if defined(IPv6) && defined(AF_INET6)
+ chooserFd = socket (AF_INET6, SOCK_STREAM, 0);
+#else
chooserFd = socket (AF_INET, SOCK_STREAM, 0);
+#endif
Debug ("Created chooser socket %d\n", chooserFd);
if (chooserFd == -1)
{
@@ -113,17 +88,425 @@ GetChooserAddr (
char *addr,
int *lenp)
{
+#if defined(IPv6) && defined(AF_INET6)
+ struct sockaddr_storage in_addr;
+#else
struct sockaddr_in in_addr;
+#endif
int len;
+ int retval = 0;
len = sizeof in_addr;
+ if (chooserFd < 0)
+ return -1; /* TODO check other listening sockets */
if (getsockname (chooserFd, (struct sockaddr *)&in_addr, (void *)&len) < 0)
return -1;
- Debug ("Chooser socket port: %d\n", ntohs(in_addr.sin_port));
- memmove( addr, (char *) &in_addr, len);
+#if defined(IPv6) && defined(AF_INET6)
+ if (((struct sockaddr *)&in_addr)->sa_family == AF_INET6)
+ Debug ("Chooser socket port: %d (IPv6)\n",
+ ntohs(((struct sockaddr_in6 *) &in_addr)->sin6_port));
+ else
+#endif
+ Debug ("Chooser socket port: %d\n",
+ ntohs(((struct sockaddr_in *) &in_addr)->sin_port));
+ if (*lenp < len)
+ retval = -2;
+ else
+ memmove( addr, (char *) &in_addr, len);
*lenp = len;
- return 0;
+ return retval;
+}
+
+static int
+CreateListeningSocket (struct sockaddr *sock_addr, int salen)
+{
+ int fd;
+ const char *addrstring = "unknown";
+#if defined(IPv6) && defined(AF_INET6)
+ char addrbuf[INET6_ADDRSTRLEN];
+#endif
+
+ if (request_port == 0)
+ return -1;
+
+ if (debugLevel > 0) {
+#if defined(IPv6) && defined(AF_INET6)
+ void *ipaddr;
+ if (sock_addr->sa_family == AF_INET6) {
+ ipaddr = & ((struct sockaddr_in6 *) sock_addr)->sin6_addr;
+ } else {
+ ipaddr = & ((struct sockaddr_in *) sock_addr)->sin_addr;
+ }
+ addrstring =
+ inet_ntop(sock_addr->sa_family, ipaddr, addrbuf, sizeof(addrbuf));
+
+#else
+ addrstring = inet_ntoa(((struct sockaddr_in *) sock_addr)->sin_addr);
+#endif
+
+ Debug ("creating socket to listen on port %d of address %s\n",
+ request_port,addrstring);
+ }
+
+ fd = socket (sock_addr->sa_family, SOCK_DGRAM, 0);
+
+ if (fd == -1) {
+ LogError ("XDMCP socket creation failed, errno %d\n", errno);
+ return fd;
+ }
+ RegisterCloseOnFork (fd);
+
+ if (bind (fd, sock_addr, salen) == -1)
+ {
+ LogError ("error %d binding socket address %d\n", errno, request_port);
+ close (fd);
+ fd = -1;
+ return fd;
+ }
+ if (fd > WellKnownSocketsMax)
+ WellKnownSocketsMax = fd;
+ FD_SET (fd, &WellKnownSocketsMask);
+ return fd;
+}
+
+struct socklist {
+ struct socklist * next;
+ struct socklist * mcastgroups;
+ struct sockaddr * addr;
+ int salen;
+ int addrlen;
+ int fd;
+ int ref; /* referenced bit - see UpdateListenSockets */
+};
+
+static struct socklist *listensocks;
+
+static void
+DestroyListeningSocket (struct socklist *s)
+{
+ if (s->fd >= 0) {
+ FD_CLR (s->fd, &WellKnownSocketsMask);
+ close(s->fd);
+ s->fd = -1;
+ }
+ if (s->addr) {
+ free(s->addr);
+ s->addr = NULL;
+ }
+ if (s->mcastgroups) {
+ struct socklist *g, *n;
+
+ for (g = s->mcastgroups; g != NULL; g = n) {
+ n = g->next;
+ if (g->addr)
+ free(g->addr);
+ free(g);
+ }
+ s->mcastgroups = NULL;
+ }
+}
+
+static struct socklist*
+FindInList(struct socklist *list, ARRAY8Ptr addr)
+{
+ struct socklist *s;
+
+ for (s = list; s != NULL; s = s->next) {
+ if (s->addrlen == addr->length) {
+ char *addrdata;
+
+ switch (s->addr->sa_family) {
+ case AF_INET:
+ addrdata = (char *)
+ &(((struct sockaddr_in *)s->addr)->sin_addr.s_addr);
+ break;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ addrdata = (char *)
+ &(((struct sockaddr_in6 *)s->addr)->sin6_addr.s6_addr);
+ break;
+#endif
+ default:
+ /* Unrecognized address family */
+ continue;
+ }
+ if (memcmp(addrdata, addr->data, addr->length) == 0) {
+ return s;
+ }
+ }
+ }
+ return NULL;
+}
+
+static struct socklist *
+CreateSocklistEntry(ARRAY8Ptr addr)
+{
+ struct socklist *s = malloc (sizeof(struct socklist));
+ if (s == NULL)
+ LogOutOfMem("CreateSocklistEntry");
+
+ bzero(s, sizeof(struct socklist));
+
+ if (addr->length == 4) /* IPv4 */
+ {
+ struct sockaddr_in *sin;
+ sin = malloc (sizeof(struct sockaddr_in));
+ if (sin == NULL)
+ LogOutOfMem("CreateSocklistEntry");
+ s->addr = (struct sockaddr *) sin;
+
+ bzero (sin, sizeof (struct sockaddr_in));
+#ifdef BSD44SOCKETS
+ sin->sin_len = sizeof(struct sockaddr_in);
+#endif
+ s->salen = sizeof(struct sockaddr_in);
+ s->addrlen = sizeof(struct in_addr);
+ sin->sin_family = AF_INET;
+ sin->sin_port = htons ((short) request_port);
+ memcpy(&sin->sin_addr, addr->data, addr->length);
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ else if (addr->length == 16) /* IPv6 */
+ {
+ struct sockaddr_in6 *sin6;
+ sin6 = malloc (sizeof(struct sockaddr_in6));
+ if (sin6 == NULL)
+ LogOutOfMem("CreateSocklistEntry");
+ s->addr = (struct sockaddr *) sin6;
+
+ bzero (sin6, sizeof (struct sockaddr_in6));
+#ifdef SIN6_LEN
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ s->salen = sizeof(struct sockaddr_in6);
+ s->addrlen = sizeof(struct in6_addr);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = htons ((short) request_port);
+ memcpy(&sin6->sin6_addr, addr->data, addr->length);
+ }
+#endif
+ else {
+ /* Unknown address type */
+ free(s);
+ s = NULL;
+ }
+ return s;
+}
+
+static void
+UpdateListener(ARRAY8Ptr addr, void **closure)
+{
+ struct socklist *s;
+ ARRAY8 tmpaddr;
+
+ *closure = NULL;
+
+ if (addr == NULL || addr->length == 0) {
+#if defined(IPv6) && defined(AF_INET6)
+ struct in6_addr in6 = in6addr_any;
+ tmpaddr.length = sizeof(in6);
+ tmpaddr.data = (CARD8Ptr) &in6;
+#else
+ struct in_addr in;
+ in.s_addr = htonl (INADDR_ANY);
+ tmpaddr.length = sizeof(in);
+ tmpaddr.data = (CARD8Ptr) &in;
+#endif
+ addr = &tmpaddr;
+ }
+
+ s = FindInList(listensocks, addr);
+
+ if (s) {
+ *closure = (void *) s;
+ s->ref = 1;
+ return;
+ }
+
+ s = CreateSocklistEntry(addr);
+
+ if (s == NULL)
+ return;
+
+ s->fd = CreateListeningSocket(s->addr, s->salen);
+ if (s->fd < 0) {
+ free(s->addr);
+ free(s);
+ return;
+ }
+ s->ref = 1;
+ s->next = listensocks;
+ listensocks = s;
+ *closure = (void *) s;
+}
+
+#define JOIN_MCAST_GROUP 0
+#define LEAVE_MCAST_GROUP 1
+
+static void
+ChangeMcastMembership(struct socklist *s, struct socklist *g, int op)
+{
+ int sockopt;
+
+ switch (s->addr->sa_family)
+ {
+ case AF_INET:
+ {
+ struct ip_mreq mreq;
+ memcpy(&mreq.imr_multiaddr,
+ &((struct sockaddr_in *) g->addr)->sin_addr,
+ sizeof(struct in_addr));
+ memcpy(&mreq.imr_interface,
+ &((struct sockaddr_in *) s->addr)->sin_addr,
+ sizeof(struct in_addr));
+ if (op == JOIN_MCAST_GROUP) {
+ sockopt = IP_ADD_MEMBERSHIP;
+ } else {
+ sockopt = IP_DROP_MEMBERSHIP;
+ }
+ if (setsockopt(s->fd, IPPROTO_IP, sockopt,
+ &mreq, sizeof(mreq)) < 0) {
+ LogError ("XDMCP socket multicast %s to %s failed, errno %d\n",
+ (op == JOIN_MCAST_GROUP) ? "join" : "drop",
+ inet_ntoa(((struct sockaddr_in *) g->addr)->sin_addr),
+ errno);
+ return;
+ } else if (debugLevel > 0) {
+ Debug ("XDMCP socket multicast %s to %s succeeded\n",
+ (op == JOIN_MCAST_GROUP) ? "join" : "drop",
+ inet_ntoa(((struct sockaddr_in *) g->addr)->sin_addr));
+ }
+ }
+#if defined(IPv6) && defined(AF_INET6)
+#ifndef IPV6_JOIN_GROUP
+#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
+#endif
+#ifndef IPV6_LEAVE_GROUP
+#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
+#endif
+ case AF_INET6:
+ {
+ struct ipv6_mreq mreq6;
+ memcpy(&mreq6.ipv6mr_multiaddr,
+ &((struct sockaddr_in6 *) g->addr)->sin6_addr,
+ sizeof(struct in6_addr));
+ mreq6.ipv6mr_interface = 0; /* TODO: fix this */
+ if (op == JOIN_MCAST_GROUP) {
+ sockopt = IPV6_JOIN_GROUP;
+ } else {
+ sockopt = IPV6_LEAVE_GROUP;
+ }
+ if (setsockopt(s->fd, IPPROTO_IPV6, sockopt,
+ &mreq6, sizeof(mreq6)) < 0) {
+ int saveerr = errno;
+ char addrbuf[INET6_ADDRSTRLEN];
+
+ inet_ntop(s->addr->sa_family,
+ &((struct sockaddr_in6 *) g->addr)->sin6_addr,
+ addrbuf, sizeof(addrbuf));
+
+ LogError ("XDMCP socket multicast %s to %s failed, errno %d\n",
+ (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf,
+ saveerr);
+ return;
+ } else if (debugLevel > 0) {
+ char addrbuf[INET6_ADDRSTRLEN];
+
+ inet_ntop(s->addr->sa_family,
+ &((struct sockaddr_in6 *) g->addr)->sin6_addr,
+ addrbuf, sizeof(addrbuf));
+
+ Debug ("XDMCP socket multicast %s to %s succeeded\n",
+ (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf);
+ }
+ }
+#endif
+ }
+}
+
+static void
+UpdateMcastGroup(ARRAY8Ptr addr, void **closure)
+{
+ struct socklist *s = (struct socklist *) *closure;
+ struct socklist *g;
+
+ g = FindInList(s->mcastgroups, addr);
+
+ if (g) { /* Already in the group, mark & continue */
+ g->ref = 1;
+ return;
+ }
+
+ /* Need to join the group */
+ g = CreateSocklistEntry(addr);
+ if (g == NULL)
+ return;
+
+ ChangeMcastMembership(s, g, JOIN_MCAST_GROUP);
+}
+
+/* Open or close listening sockets to match the current settings read in
+ from the access database. */
+void UpdateListenSockets (void)
+{
+ struct socklist *s, *g, **ls, **lg, *ns, *ng;
+ void *tmpPtr = NULL;
+
+ /* Clear Ref bits - any not marked by UpdateCallback will be closed */
+ for (s = listensocks; s != NULL; s = s->next) {
+ s->ref = 0;
+ for (g = s->mcastgroups; g != NULL ; g = g->next) {
+ g->ref = 0;
+ }
+ }
+ ForEachListenAddr(UpdateListener, UpdateMcastGroup, &tmpPtr);
+ for (s = listensocks, ls = &listensocks; s != NULL; s = ns) {
+ ns = s->next;
+ if (s->ref == 0) {
+ DestroyListeningSocket(s);
+ *ls = s->next;
+ free(s);
+ } else {
+ ls = &(s->next);
+ for (lg = &s->mcastgroups, g = *lg; g != NULL ; g = ng) {
+ ng = g->next;
+ if (g->ref == 0) {
+ ChangeMcastMembership(s,g,LEAVE_MCAST_GROUP);
+ *lg = g->next;
+ free(g);
+ } else {
+ lg = &(g->next);
+ }
+ }
+ }
+ }
+}
+
+/* Close all additional listening sockets beyond the basic chooserFd and
+ remove them from the WellKnownSocketsMask. */
+void CloseListenSockets (void)
+{
+ struct socklist *s, *n;
+
+ for (s = listensocks; s != NULL; s = n) {
+ n = s->next;
+ DestroyListeningSocket(s);
+ free(s);
+ }
+ listensocks = NULL;
+}
+
+/* For each listening socket identified in readmask, process the incoming
+ XDMCP request */
+void ProcessListenSockets (fd_set *readmask)
+{
+ struct socklist *s;
+
+ for (s = listensocks; s != NULL; s = s->next) {
+ if (FD_ISSET(s->fd, readmask))
+ ProcessRequestSocket(s->fd);
+ }
}
#endif /* !STREAMSCONN */
diff --git a/streams.c b/streams.c
index de6b41a..720b4cc 100644
--- a/streams.c
+++ b/streams.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/streams.c,v 3.6 2001/12/14 20:01:24 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/streams.c,v 3.8 2003/10/27 21:39:08 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -53,7 +53,7 @@ extern FD_TYPE WellKnownSocketsMask;
extern int WellKnownSocketsMax;
void
-CreateWellKnownSockets ()
+CreateWellKnownSockets (void)
{
struct t_bind bind_addr;
struct netconfig *nconf;
@@ -127,9 +127,9 @@ CreateWellKnownSockets ()
FD_SET (chooserFd, &WellKnownSocketsMask);
}
-GetChooserAddr (addr, lenp)
- char *addr; /* return */
- int *lenp; /* size of addr, returned as amt used */
+int
+GetChooserAddr (char *addr, /* return */
+ int *lenp) /* size of addr, returned as amt used */
{
struct netbuf nbuf;
int retval;
@@ -146,5 +146,24 @@ GetChooserAddr (addr, lenp)
return retval;
}
+/* TODO: Implement support for controlling which interfaces are listened on
+ and for listening to multicast addresses. See the sockets equivalent in
+ sockets.c for details. */
+
+void UpdateListenSockets (void)
+{
+ return;
+}
+
+void CloseListenSockets (void)
+{
+ return;
+}
+
+void ProcessListenSockets (fd_set *readmask)
+{
+ return;
+}
+
#endif /* STREAMSCONN */
#endif /* XDMCP */
diff --git a/xdm.man.cpp b/xdm.man.cpp
index 07fd53f..9ad586e 100644
--- a/xdm.man.cpp
+++ b/xdm.man.cpp
@@ -1,15 +1,15 @@
.\" $Xorg: xdm.man,v 1.4 2001/02/09 02:05:41 xorgcvs Exp $
.\" Copyright 1988, 1994, 1998 The Open Group
-.\"
+.\"
.\" Permission to use, copy, modify, distribute, and sell this software and its
.\" documentation for any purpose is hereby granted without fee, provided that
.\" the above copyright notice appear in all copies and that both that
.\" copyright notice and this permission notice appear in supporting
.\" documentation.
-.\"
+.\"
.\" The above copyright notice and this permission notice shall be included
.\" in all copies or substantial portions of the Software.
-.\"
+.\"
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -17,14 +17,14 @@
.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
.\" OTHER DEALINGS IN THE SOFTWARE.
-.\"
+.\"
.\" Except as contained in this notice, the name of The Open Group shall
.\" not be used in advertising or otherwise to promote the sale, use or
.\" other dealings in this Software without prior written authorization
.\" from The Open Group.
-.\"
-.\" $XFree86: xc/programs/xdm/xdm.man,v 3.22 2002/10/12 16:06:47 herrb Exp $
-.\"
+.\"
+.\" $XFree86: xc/programs/xdm/xdm.man,v 3.26 2003/10/24 20:38:15 tsi Exp $
+.\"
.TH XDM 1 __xorgversion__
.SH NAME
xdm \- X Display Manager with support for XDMCP, host chooser
@@ -92,6 +92,13 @@ by
.I chooser
or X terminals themselves.
.PP
+.I Xdm
+can be configured to ignore BroadcastQuery messages from selected hosts.
+This is useful when you don't want the host to appear in menus produced
+by
+.I chooser
+or X terminals themselves.
+.PP
Because
.I xdm
provides the first interface that users will see, it is designed to be
@@ -144,7 +151,7 @@ When the \fIXsession\fP script exits, the session is over.
At the end of the session, the \fIXreset\fP script is run to clean up,
the X server is reset, and the cycle starts over.
.PP
-The file \fI__projectroot__/lib/X11/xdm/xdm-errors\fP will contain error
+The file \fI __projectroot__/lib/X11/xdm/xdm-errors\fP will contain error
messages from
.I xdm
and anything output to stderr by \fIXsetup, Xstartup, Xsession\fP
@@ -247,7 +254,7 @@ dots to separate resource name parts,
.I xdm
substitutes underscores for both dots and colons when generating the resource
name.
-For example, \fBDisplayManager.expo_x_org_0.startup\fP is the name of the
+For example, \fBDisplayManager.expo_x_org_0.startup\fP is the name of the
resource which defines the startup shell file for the ``expo.x.org:0'' display.
.\"
.IP "\fBDisplayManager.servers\fP"
@@ -305,7 +312,7 @@ uses the \fIlockf\fP library call, while on BSD it uses \fIflock.\fP
This names a directory under which
.I xdm
stores authorization files while initializing the session. The
-default value is \fI__projectroot__/lib/X11/xdm.\fP
+default value is \fI __projectroot__/lib/X11/xdm.\fP
Can be overridden for specific displays by
DisplayManager.\fIDISPLAY\fP.authFile.
.IP \fBDisplayManager.autoRescan\fP
@@ -349,10 +356,31 @@ to pass on to the \fIXsetup\fP,
A file to checksum to generate the seed of authorization keys.
This should be a file that changes frequently.
The default is \fI/dev/mem\fP.
+#ifdef DEV_RANDOM
+.IP \fBDisplayManager.randomDevice\fP
+A file to read 8 bytes from to generate the seed of authorization keys.
+The default is \fI DEV_RANDOM \fP. If this file cannot be read, or if a
+read blocks for more than 5 seconds, xdm falls back to using a checksum
+of \fBDisplayManager.randomFile\fP to generate the seed.
+#endif
+#if !defined(ARC4_RANDOM)
+.IP \fBDisplayManager.prngdSocket\fP
+.IP \fBDisplayManager.prngPort\fP
+A UNIX domain socket name or a TCP socket port number on local host on
+which a Pseudo-Random Number Generator Daemon, like EGD
+(http://egd.sourceforge.net) is listening, in order to generate the
+autorization keys. Either a non null port or a valid socket name must
+be specified. The default is to use the Unix-domain socket
+\fI/tmp/entropy\fP.
+.PP
+On systems that don't have such a daemon, a fall-back entropy
+gathering system, based on various log file contents hashed by the MD5
+algorithm is used instead.
+#endif
.IP \fBDisplayManager.greeterLib\fP
On systems that support a dynamically-loadable greeter library, the
name of the library. The default is
-\fI__projectroot__/lib/X11/xdm/libXdmGreet.so\fP.
+\fI __projectroot__/lib/X11/xdm/libXdmGreet.so\fP.
.IP \fBDisplayManager.choiceTimeout\fP
Number of seconds to wait for display to respond after user has
selected a host from the chooser. If the display sends an XDMCP
@@ -384,17 +412,17 @@ section
which describes the various
resources that are appropriate to place in this file.
There is no default value for this resource, but
-\fI__projectroot__/lib/X11/xdm/Xresources\fP
+\fI __projectroot__/lib/X11/xdm/Xresources\fP
is the conventional name.
.IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.chooser\fP"
Specifies the program run to offer a host menu for Indirect queries
redirected to the special host name CHOOSER.
-\fI__projectroot__/lib/X11/xdm/chooser\fP is the default.
+\fI __projectroot__/lib/X11/xdm/chooser\fP is the default.
See the sections \fBXDMCP Access Control\fP and \fBChooser\fP.
.IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.xrdb\fP"
Specifies the program used to load the resources. By default,
.I xdm
-uses \fI__projectroot__/bin/xrdb\fP.
+uses \fI __projectroot__/bin/xrdb\fP.
.IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.cpp\fP"
This specifies the name of the C preprocessor which is used by \fIxrdb\fP.
.IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.setup\fP"
@@ -412,7 +440,7 @@ file used here is \fIXstartup\fP.
See the section \fBStartup Program.\fP
.IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.session\fP"
This specifies the session to be executed (not running as root).
-By default, \fI__projectroot__/bin/xterm\fP is
+By default, \fI __projectroot__/bin/xterm\fP is
run. The conventional name is \fIXsession\fP.
See the section
.B "Session Program."
@@ -498,7 +526,7 @@ If the default session fails to execute,
will fall back to this program. This program is executed with no
arguments, but executes using the same environment variables as
the session would have had (see the section \fBSession Program\fP).
-By default, \fI__projectroot__/bin/xterm\fP is used.
+By default, \fI __projectroot__/bin/xterm\fP is used.
.IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.grabServer\fP"
.IP "\fBDisplayManager.\fP\fIDISPLAY\fP\fB.grabTimeout\fP"
To improve security,
@@ -577,7 +605,7 @@ variable XAUTHORITY at the created file. It uses \fI/tmp\fP by default.
First, the
.I xdm
configuration file should be set up.
-Make a directory (usually \fI__projectroot__/lib/X11/xdm\fP) to contain all
+Make a directory (usually \fI __projectroot__/lib/X11/xdm\fP) to contain all
of the relevant files.
.LP
Here is a reasonable configuration file, which could be
@@ -632,6 +660,11 @@ it can be followed by the optional ``NOBROADCAST'' keyword.
This can be used to prevent an xdm server from appearing on
menus based on Broadcast queries.
.PP
+To only respond to Direct queries for a host or pattern,
+it can be followed by the optional ``NOBROADCAST'' keyword.
+This can be used to prevent an xdm server from appearing on
+menus based on Broadcast queries.
+.PP
An Indirect entry also contains a host name or pattern,
but follows it with a list of
host names or macros to which indirect queries should be sent.
@@ -686,6 +719,23 @@ extract.lcs.mit.edu xenon.lcs.mit.edu #force extract to contact xenon
!xtra.lcs.mit.edu dummy #disallow indirect access
*.lcs.mit.edu %HOSTS #all others get to choose
.fi
+.PP
+If compiled with IPv6 support, multicast address groups may also be included
+in the list of addresses indirect queries are set to. Multicast addresses
+may be followed by an optional / character and hop count. If no hop count is
+specified, the multicast hop count defaults to 1, keeping the packet on the
+local network. For IPv4 multicasting, the hop count is used as the TTL.
+.PP
+Examples:
+.LP
+.ta 2.1i 4.5i
+.nf
+rincewind.sample.net ff02::1 #IPv6 Multicast to ff02::1
+\& #with a hop count of 1
+ponder.sample.net CHOOSER 239.192.1.1/16 #Offer a menu of hosts
+\& #who respond to IPv4 Multicast
+\& # to 239.192.1.1 with a TTL of 16
+.fi
.SH CHOOSER
.PP
For X terminals that do not offer a host menu for use with Broadcast
@@ -725,6 +775,37 @@ and sends another \fBIndirect\fP XDMCP request.
\fBDisplayManager.choiceTimeout\fP seconds) and forwards the request
to the chosen host, which starts a session on that display.
.\"
+.SH LISTEN
+The following configuration directive is also defined for the Xaccess
+configuration file:
+.IP "\fBLISTEN\fP \fIinterface\fP \fI[list of multicast group addresses]\fP"
+\fIinterface\fP may be a hostname or IP addresss representing a
+network interface on this machine, or the wildcard * to represent all
+available network interfaces.
+.PP
+If one or more LISTEN lines are specified, xdm only listens for XDMCP
+connections on the specified interfaces. If multicast group addresses
+are listed on a listen line, xdm joins the multicast groups on the
+given interface.
+.PP
+If no LISTEN lines are given, the original behavior of listening on
+all interfaces is preserved for backwards compatibility.
+Additionally, if no LISTEN is specified, xdm joins the default XDMCP
+IPv6 multicast group, when compiled with IPv6 support.
+.PP
+To disable listening for XDMCP connections altogther, a line of LISTEN
+with no addresses may be specified, or the previously supported method
+of setting DisplayManager.requestPort to 0 may be used.
+.PP
+Examples:
+.ta 2i 4i
+.nf
+LISTEN * ff02::1 # Listen on all interfaces and to the
+\& # ff02::1 IPv6 multicast group.
+LISTEN 10.11.12.13 # Listen only on this interface, as long
+\& # as no other listen directives appear in
+\& # file.
+.fi
.SH "LOCAL SERVER SPECIFICATION"
.PP
The resource \fBDisplayManager.servers\fP gives a server specification
@@ -781,7 +862,7 @@ it at its authorization data.
For XDMCP servers, \fIxdm\fP passes the
authorization data to the server via the \fBAccept\fP XDMCP request.
.SH RESOURCES FILE
-The \fIXresources\fP file is
+The \fIXresources\fP file is
loaded onto the display as a resource database using
.I xrdb.
As the authentication
@@ -830,6 +911,15 @@ the following environment variables are passed:
SHELL the value of \fBDisplayManager.\fP\fIDISPLAY\fP\fB.systemShell\fP
XAUTHORITY may be set to an authority file
.fi
+.IP "\fBxlogin.Login.allowRootLogin\fP"
+If set to ``false'', don't allow root (and any other user with uid = 0) to
+log in directly.
+The default is ``true''.
+.IP "\fBxlogin.Login.allowNullPasswd\fP"
+If set to ``true'', allow an otherwise failing password match to succeed
+if the account does not require a password at all.
+The default is ``false'', so only users that have passwords assigned can
+log in.
.PP
Note that since \fIxdm\fP grabs the keyboard, any other windows will not be
able to receive keyboard input. They will be able to interact with
@@ -985,7 +1075,7 @@ before doing this.
.PP
On some systems (OpenBSD) the user's shell must be listed in
.I /etc/shells
-to allow login through xdm. The normal password and account expiration
+to allow login through xdm. The normal password and account expiration
dates are enforced too.
.SH "STARTUP PROGRAM"
.PP
@@ -1025,7 +1115,7 @@ cycle.
.PP
The sample \fIXstartup\fP file shown here prevents login while the
file \fI/etc/nologin\fP
-exists.
+exists.
Thus this is not a complete example, but
simply a demonstration of the available functionality.
.PP
@@ -1100,7 +1190,7 @@ be executable so we don't have to guess what shell it wants to use.
\& #
\& # This is the program that is run as the client
\& # for the display manager.
-
+
case $# in
1)
case $1 in
@@ -1109,10 +1199,10 @@ be executable so we don't have to guess what shell it wants to use.
;;
esac
esac
-
+
startup=$HOME/.xsession
resources=$HOME/.Xresources
-
+
if [ \-f "$startup" ]; then
exec "$startup"
else
@@ -1230,7 +1320,7 @@ line:
.nf
.ta .5i
- xdm \-server ":0 SUN-3/60CG4 local __projectroot__/bin/X :0"
+ xdm \-server \(lq:0 SUN-3/60CG4 local __projectroot__/bin/X :0\(rq
.fi
.PP
diff --git a/xdmauth.c b/xdmauth.c
index 7be4d3d..a42fcfb 100644
--- a/xdmauth.c
+++ b/xdmauth.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/xdmauth.c,v 1.5 2001/12/14 20:01:25 dawes Exp $ */
+/* $XFree86: xc/programs/xdm/xdmauth.c,v 1.7 2003/10/27 21:39:02 herrb Exp $ */
/*
* xdm - display manager daemon
* Author: Keith Packard, MIT X Consortium
@@ -45,11 +45,8 @@ from The Open Group.
static char auth_name[256];
static int auth_name_len;
-void
-XdmPrintDataHex (s, a, l)
- char *s;
- char *a;
- int l;
+static void
+XdmPrintDataHex (char *s, char *a, int l)
{
int i;
@@ -59,30 +56,16 @@ XdmPrintDataHex (s, a, l)
Debug ("\n");
}
-#ifdef notdef /* not used */
-void
-XdmPrintKey (s, k)
- char *s;
- XdmAuthKeyRec *k;
-{
- XdmPrintDataHex (s, (char *) k->data, 8);
-}
-#endif
-
#ifdef XDMCP
-void
-XdmPrintArray8Hex (s, a)
- char *s;
- ARRAY8Ptr a;
+static void
+XdmPrintArray8Hex (char *s, ARRAY8Ptr a)
{
XdmPrintDataHex (s, (char *) a->data, a->length);
}
#endif
void
-XdmInitAuth (name_len, name)
- unsigned short name_len;
- char *name;
+XdmInitAuth (unsigned short name_len, char *name)
{
if (name_len > 256)
name_len = 256;
@@ -99,11 +82,8 @@ XdmInitAuth (name_len, name)
* between xdm and the server (16 bytes total)
*/
-Xauth *
-XdmGetAuthHelper (namelen, name, includeRho)
- unsigned short namelen;
- char *name;
- int includeRho;
+static Xauth *
+XdmGetAuthHelper (unsigned short namelen, char *name, int includeRho)
{
Xauth *new;
new = (Xauth *) malloc (sizeof (Xauth));
@@ -135,7 +115,13 @@ XdmGetAuthHelper (namelen, name, includeRho)
}
memmove( (char *)new->name, name, namelen);
new->name_length = namelen;
- GenerateAuthData ((char *)new->data, new->data_length);
+ if (!GenerateAuthData ((char *)new->data, new->data_length))
+ {
+ free ((char *) new->name);
+ free ((char *) new->data);
+ free ((char *) new);
+ return (Xauth *) 0;
+ }
/*
* set the first byte of the session key to zero as it
* is a DES key and only uses 56 bits
@@ -146,9 +132,7 @@ XdmGetAuthHelper (namelen, name, includeRho)
}
Xauth *
-XdmGetAuth (namelen, name)
- unsigned short namelen;
- char *name;
+XdmGetAuth (unsigned short namelen, char *name)
{
return XdmGetAuthHelper (namelen, name, TRUE);
}
@@ -156,10 +140,8 @@ XdmGetAuth (namelen, name)
#ifdef XDMCP
void
-XdmGetXdmcpAuth (pdpy,authorizationNameLen, authorizationName)
- struct protoDisplay *pdpy;
- unsigned short authorizationNameLen;
- char *authorizationName;
+XdmGetXdmcpAuth (struct protoDisplay *pdpy,
+ unsigned short authorizationNameLen, char *authorizationName)
{
Xauth *fileauth, *xdmcpauth;
@@ -210,8 +192,7 @@ XdmGetXdmcpAuth (pdpy,authorizationNameLen, authorizationName)
'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
static int
-HexToBinary (key)
- char *key;
+HexToBinary(char *key)
{
char *out, *in;
int top, bottom;
@@ -240,10 +221,8 @@ HexToBinary (key)
* routine accepts either plain ascii strings for keys, or hex-encoded numbers
*/
-int
-XdmGetKey (pdpy, displayID)
- struct protoDisplay *pdpy;
- ARRAY8Ptr displayID;
+static int
+XdmGetKey(struct protoDisplay *pdpy, ARRAY8Ptr displayID)
{
FILE *keys;
char line[1024], id[1024], key[1024];
@@ -283,9 +262,8 @@ XdmGetKey (pdpy, displayID)
/*ARGSUSED*/
int
-XdmCheckAuthentication (pdpy, displayID, authenticationName, authenticationData)
- struct protoDisplay *pdpy;
- ARRAY8Ptr displayID, authenticationName, authenticationData;
+XdmCheckAuthentication(struct protoDisplay *pdpy, ARRAY8Ptr displayID,
+ ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData)
{
XdmAuthKeyPtr incoming;
diff --git a/xdmcp.c b/xdmcp.c
index 726902f..dcd28d1 100644
--- a/xdmcp.c
+++ b/xdmcp.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/xdm/xdmcp.c,v 3.21 2002/12/10 22:37:17 tsi Exp $ */
+/* $XFree86: xc/programs/xdm/xdmcp.c,v 3.24 2003/11/16 15:50:38 herrb Exp $ */
/*
* xdm - display manager daemon
@@ -55,14 +55,10 @@ from The Open Group.
#include <un.h>
#endif
#endif
-#if defined(__SVR4) && defined(__sun)
- /*
- * make sure we get the resolver's version of gethostbyname
- * otherwise we may not get all the addresses!
- */
-#define gethostbyname res_gethostbyname
-#endif
#include <netdb.h>
+#if defined(IPv6) && defined(AF_INET6)
+#include <arpa/inet.h>
+#endif
#include <time.h>
#define Time_t time_t
@@ -72,28 +68,32 @@ from The Open Group.
/*
* misc externs
*/
-extern int Rescan, ChildReady;
-extern int sourceAddress;
+extern volatile int Rescan;
+extern int sourceAddress, ChildReady;
/*
* Forward reference
*/
-static void broadcast_respond (struct sockaddr *from, int fromlen, int length);
-static void forward_respond (struct sockaddr *from, int fromlen, int length);
-static void manage (struct sockaddr *from, int fromlen, int length);
-static void query_respond (struct sockaddr *from, int fromlen, int length);
-static void request_respond (struct sockaddr *from, int fromlen, int length);
-static void send_accept (struct sockaddr *to, int tolen, CARD32 sessionID, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData);
-static void send_alive (struct sockaddr *from, int fromlen, int length);
-static void send_decline (struct sockaddr *to, int tolen, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr status);
-static void send_failed (struct sockaddr *from, int fromlen, char *name, CARD32 sessionID, char *reason);
-static void send_refuse (struct sockaddr *from, int fromlen, CARD32 sessionID);
-static void send_unwilling (struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status);
-static void send_willing (struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status);
-
-
+static void broadcast_respond (struct sockaddr *from, int fromlen, int length, int fd);
+static void forward_respond (struct sockaddr *from, int fromlen, int length, int fd);
+static void manage (struct sockaddr *from, int fromlen, int length, int fd);
+static void query_respond (struct sockaddr *from, int fromlen, int length, int fd);
+static void request_respond (struct sockaddr *from, int fromlen, int length, int fd);
+static void send_accept (struct sockaddr *to, int tolen, CARD32 sessionID, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData, int fd);
+static void send_alive (struct sockaddr *from, int fromlen, int length, int fd);
+static void send_decline (struct sockaddr *to, int tolen, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr status, int fd);
+static void send_failed (struct sockaddr *from, int fromlen, char *name, CARD32 sessionID, char *reason, int fd);
+static void send_refuse (struct sockaddr *from, int fromlen, CARD32 sessionID, int fd);
+static void send_unwilling (struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd);
+static void send_willing (struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd);
+
+#ifdef STREAMSCONN
int xdmcpFd = -1;
+#endif
int chooserFd = -1;
+#if defined(IPv6) && defined(AF_INET6)
+int chooserFd6 = -1;
+#endif
FD_TYPE WellKnownSocketsMask;
int WellKnownSocketsMax;
@@ -103,22 +103,55 @@ int WellKnownSocketsMax;
void
DestroyWellKnownSockets (void)
{
+#ifdef STREAMSCONN
if (xdmcpFd != -1)
{
close (xdmcpFd);
+ FD_CLR(xdmcpFd, &WellKnownSocketsMask);
xdmcpFd = -1;
}
+#endif
if (chooserFd != -1)
{
close (chooserFd);
+ FD_CLR(chooserFd, &WellKnownSocketsMask);
chooserFd = -1;
}
+#if defined(IPv6) && defined(AF_INET6)
+ if (chooserFd6 != -1)
+ {
+ close (chooserFd6);
+ FD_CLR(chooserFd6, &WellKnownSocketsMask);
+ chooserFd6 = -1;
+ }
+#endif
+ CloseListenSockets();
+}
+
+static int
+FD_ANYSET(fd_set *fds)
+{
+ int i;
+ char *mask = (char *) fds;
+
+ for (i = 0 ; i < sizeof(fds); i++) {
+ if (mask[i])
+ return TRUE;
+ }
+ return FALSE;
}
int
AnyWellKnownSockets (void)
{
- return xdmcpFd != -1 || chooserFd != -1;
+ return
+#ifdef STREAMS_CONN
+ xdmcpFd != -1 ||
+#endif
+#if defined(IPv6) && defined(AF_INET6)
+ chooserFd6 != -1 ||
+#endif
+ chooserFd != -1 || FD_ANYSET(&WellKnownSocketsMask);
}
static XdmcpBuffer buffer;
@@ -133,6 +166,9 @@ sendForward (
#ifdef AF_INET
struct sockaddr_in in_addr;
#endif
+#if defined(IPv6) && defined(AF_INET6)
+ struct sockaddr_in6 in6_addr;
+#endif
#ifdef AF_DECnet
#endif
struct sockaddr *addr;
@@ -155,13 +191,28 @@ sendForward (
addrlen = sizeof (struct sockaddr_in);
break;
#endif
+#if defined(IPv6) && defined(AF_INET6)
+ case FamilyInternet6:
+ addr = (struct sockaddr *) &in6_addr;
+ bzero ((char *) &in6_addr, sizeof (in6_addr));
+#ifdef SIN6_LEN
+ in6_addr.sin6_len = sizeof(in6_addr);
+#endif
+ in6_addr.sin6_family = AF_INET6;
+ in6_addr.sin6_port = htons ((short) XDM_UDP_PORT);
+ if (address->length != 16)
+ return;
+ memmove( (char *) &in6_addr.sin6_addr, address->data, address->length);
+ addrlen = sizeof (struct sockaddr_in6);
+ break;
+#endif
#ifdef AF_DECnet
case FamilyDECnet:
#endif
default:
return;
}
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) addr, addrlen);
+ XdmcpFlush (*((int *) closure), &buffer, (XdmcpNetaddr) addr, addrlen);
return;
}
@@ -193,7 +244,8 @@ all_query_respond (
struct sockaddr *from,
int fromlen,
ARRAYofARRAY8Ptr authenticationNames,
- xdmOpCode type)
+ xdmOpCode type,
+ int fd)
{
ARRAY8Ptr authenticationName;
ARRAY8 status;
@@ -217,10 +269,10 @@ all_query_respond (
authenticationName = ChooseAuthentication (authenticationNames);
if (Willing (&addr, connectionType, authenticationName, &status, type))
- send_willing (from, fromlen, authenticationName, &status);
+ send_willing (from, fromlen, authenticationName, &status, fd);
else
if (type == QUERY)
- send_unwilling (from, fromlen, authenticationName, &status);
+ send_unwilling (from, fromlen, authenticationName, &status, fd);
XdmcpDisposeARRAY8 (&status);
}
@@ -228,7 +280,8 @@ static void
indirect_respond (
struct sockaddr *from,
int fromlen,
- int length)
+ int length,
+ int fd)
{
ARRAYofARRAY8 queryAuthenticationNames;
ARRAY8 clientAddress;
@@ -264,13 +317,13 @@ indirect_respond (
XdmcpWriteARRAY8 (&buffer, &clientPort);
XdmcpWriteARRAYofARRAY8 (&buffer, &queryAuthenticationNames);
- localHostAsWell = ForEachMatchingIndirectHost (&clientAddress, connectionType, sendForward, (char *) 0);
+ localHostAsWell = ForEachMatchingIndirectHost (&clientAddress, connectionType, sendForward, (char *) &fd);
XdmcpDisposeARRAY8 (&clientAddress);
XdmcpDisposeARRAY8 (&clientPort);
if (localHostAsWell)
all_query_respond (from, fromlen, &queryAuthenticationNames,
- INDIRECT_QUERY);
+ INDIRECT_QUERY, fd);
}
else
{
@@ -279,16 +332,20 @@ indirect_respond (
XdmcpDisposeARRAYofARRAY8 (&queryAuthenticationNames);
}
-static void
-ProcessRequestSocket (void)
+void
+ProcessRequestSocket (int fd)
{
XdmcpHeader header;
+#if defined(IPv6) && defined(AF_INET6)
+ struct sockaddr_storage addr;
+#else
struct sockaddr addr;
+#endif
int addrlen = sizeof addr;
Debug ("ProcessRequestSocket\n");
bzero ((char *) &addr, sizeof (addr));
- if (!XdmcpFill (xdmcpFd, &buffer, (XdmcpNetaddr) &addr, &addrlen)) {
+ if (!XdmcpFill (fd, &buffer, (XdmcpNetaddr) &addr, &addrlen)) {
Debug ("XdmcpFill failed\n");
return;
}
@@ -305,25 +362,25 @@ ProcessRequestSocket (void)
switch (header.opcode)
{
case BROADCAST_QUERY:
- broadcast_respond (&addr, addrlen, header.length);
+ broadcast_respond ((struct sockaddr *) &addr, addrlen, header.length, fd);
break;
case QUERY:
- query_respond (&addr, addrlen, header.length);
+ query_respond ((struct sockaddr *) &addr, addrlen, header.length, fd);
break;
case INDIRECT_QUERY:
- indirect_respond (&addr, addrlen, header.length);
+ indirect_respond ((struct sockaddr *) &addr, addrlen, header.length, fd);
break;
case FORWARD_QUERY:
- forward_respond (&addr, addrlen, header.length);
+ forward_respond ((struct sockaddr *) &addr, addrlen, header.length, fd);
break;
case REQUEST:
- request_respond (&addr, addrlen, header.length);
+ request_respond ((struct sockaddr *) &addr, addrlen, header.length, fd);
break;
case MANAGE:
- manage (&addr, addrlen, header.length);
+ manage ((struct sockaddr *) &addr, addrlen, header.length, fd);
break;
case KEEPALIVE:
- send_alive (&addr, addrlen, header.length);
+ send_alive ((struct sockaddr *) &addr, addrlen, header.length, fd);
break;
}
}
@@ -342,15 +399,33 @@ WaitForSomething (void)
nready, Rescan, ChildReady);
if (nready > 0)
{
+#ifdef STREAMSCONN
if (xdmcpFd >= 0 && FD_ISSET (xdmcpFd, &reads))
ProcessRequestSocket ();
+#endif
if (chooserFd >= 0 && FD_ISSET (chooserFd, &reads))
+ {
#ifdef ISC
if (!ChildReady) {
WaitForSomething ();
} else
#endif
ProcessChooserSocket (chooserFd);
+ FD_CLR(chooserFd, &reads);
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ if (chooserFd6 >= 0 && FD_ISSET (chooserFd6, &reads))
+ {
+#ifdef ISC
+ if (!ChildReady) {
+ WaitForSomething ();
+ } else
+#endif
+ ProcessChooserSocket (chooserFd6);
+ FD_CLR(chooserFd6, &reads);
+ }
+#endif
+ ProcessListenSockets(&reads);
}
if (ChildReady)
{
@@ -384,7 +459,8 @@ direct_query_respond (
struct sockaddr *from,
int fromlen,
int length,
- xdmOpCode type)
+ xdmOpCode type,
+ int fd)
{
ARRAYofARRAY8 queryAuthenticationNames;
int expectedLen;
@@ -396,7 +472,7 @@ direct_query_respond (
for (i = 0; i < (int)queryAuthenticationNames.length; i++)
expectedLen += 2 + queryAuthenticationNames.data[i].length;
if (length == expectedLen)
- all_query_respond (from, fromlen, &queryAuthenticationNames, type);
+ all_query_respond (from, fromlen, &queryAuthenticationNames, type, fd);
XdmcpDisposeARRAYofARRAY8 (&queryAuthenticationNames);
}
@@ -404,19 +480,21 @@ static void
query_respond (
struct sockaddr *from,
int fromlen,
- int length)
+ int length,
+ int fd)
{
Debug ("Query respond %d\n", length);
- direct_query_respond (from, fromlen, length, QUERY);
+ direct_query_respond (from, fromlen, length, QUERY, fd);
}
static void
broadcast_respond (
struct sockaddr *from,
int fromlen,
- int length)
+ int length,
+ int fd)
{
- direct_query_respond (from, fromlen, length, BROADCAST_QUERY);
+ direct_query_respond (from, fromlen, length, BROADCAST_QUERY, fd);
}
/* computes an X display name */
@@ -431,6 +509,113 @@ NetworkAddressToName(
switch (connectionType)
{
case FamilyInternet:
+#if defined(IPv6) && defined(AF_INET6)
+ case FamilyInternet6:
+ {
+ CARD8 *data;
+ struct hostent *hostent;
+ char *hostname = NULL;
+ char *name;
+ char *localhost;
+ int multiHomed = 0;
+ struct addrinfo hints, *ai = NULL, *nai;
+ int type;
+
+ if (connectionType == FamilyInternet6)
+ type = AF_INET6;
+ else
+ type = AF_INET;
+
+ data = connectionAddress->data;
+ hostent = gethostbyaddr ((char *)data,
+ connectionAddress->length, type);
+ if (hostent) {
+ if (sourceAddress) {
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ if (getaddrinfo(hostent->h_name, NULL, &hints, &ai) == 0) {
+ hostname = ai->ai_canonname;
+ for (nai = ai->ai_next; nai!=NULL; nai=nai->ai_next) {
+ if ((ai->ai_protocol == nai->ai_protocol) &&
+ (ai->ai_addrlen == nai->ai_addrlen) &&
+ (memcmp(ai->ai_addr,nai->ai_addr,
+ ai->ai_addrlen) != 0) ) {
+ multiHomed = 1;
+ }
+ }
+ }
+ } else {
+ hostname = hostent->h_name;
+ }
+ }
+
+ localhost = localHostname ();
+
+ /*
+ * protect against bogus host names
+ */
+ if (hostname && hostname[0] && (hostname[0] != '.')
+ && !multiHomed)
+ {
+ if (!strcmp (localhost, hostname))
+ {
+ if (!getString (name, 10))
+ return 0;
+ sprintf (name, ":%d", displayNumber);
+ }
+ else
+ {
+ if (removeDomainname)
+ {
+ char *localDot, *remoteDot;
+
+ /* check for a common domain name. This
+ * could reduce names by recognising common
+ * super-domain names as well, but I don't think
+ * this is as useful, and will confuse more
+ * people
+ */
+ if ((localDot = strchr(localhost, '.')) &&
+ (remoteDot = strchr(hostname, '.')))
+ {
+ /* smash the name in place; it won't
+ * be needed later.
+ */
+ if (!strcmp (localDot+1, remoteDot+1))
+ *remoteDot = '\0';
+ }
+ }
+
+ if (!getString (name, strlen (hostname) + 10))
+ return 0;
+ sprintf (name, "%s:%d", hostname, displayNumber);
+ }
+ }
+ else
+ {
+ if (!getString (name, INET6_ADDRSTRLEN + 10))
+ return 0;
+ if (multiHomed) {
+ if (connectionType == FamilyInternet) {
+ data = (CARD8 *)
+ &((struct sockaddr_in *)originalAddress)->
+ sin_addr;
+ } else {
+ data = (CARD8 *)
+ &((struct sockaddr_in6 *)originalAddress)->sin6_addr;
+ }
+ }
+ if (inet_ntop(type, data, name, INET6_ADDRSTRLEN) == NULL) {
+ free(name);
+ return 0;
+ }
+ sprintf(name + strlen(name), ":%d", displayNumber);
+ }
+ if (ai)
+ freeaddrinfo(ai);
+ return name;
+ }
+#else /* IPv6 */
{
CARD8 *data;
struct hostent *hostent;
@@ -502,6 +687,7 @@ NetworkAddressToName(
}
return name;
}
+#endif /* IPv6 */
#ifdef DNET
case FamilyDECnet:
return NULL;
@@ -516,7 +702,8 @@ static void
forward_respond (
struct sockaddr *from,
int fromlen,
- int length)
+ int length,
+ int fd)
{
ARRAY8 clientAddress;
ARRAY8 clientPort;
@@ -576,7 +763,31 @@ forward_respond (
client = (struct sockaddr *) &in_addr;
clientlen = sizeof (in_addr);
all_query_respond (client, clientlen, &authenticationNames,
- FORWARD_QUERY);
+ FORWARD_QUERY, fd);
+ }
+ break;
+#endif
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ {
+ struct sockaddr_in6 in6_addr;
+
+ if (clientAddress.length != 16 ||
+ clientPort.length != 2)
+ {
+ goto badAddress;
+ }
+ bzero ((char *) &in6_addr, sizeof (in6_addr));
+#ifdef SIN6_LEN
+ in6_addr.sin6_len = sizeof(in6_addr);
+#endif
+ in6_addr.sin6_family = AF_INET6;
+ memmove(&in6_addr,clientAddress.data,clientAddress.length);
+ memmove((char *) &in6_addr.sin6_port, clientPort.data, 2);
+ client = (struct sockaddr *) &in6_addr;
+ clientlen = sizeof (in6_addr);
+ all_query_respond (client, clientlen, &authenticationNames,
+ FORWARD_QUERY, fd);
}
break;
#endif
@@ -599,7 +810,7 @@ forward_respond (
clientlen = sizeof (un_addr);
#endif
all_query_respond (client, clientlen, &authenticationNames,
- FORWARD_QUERY);
+ FORWARD_QUERY, fd);
}
break;
#endif
@@ -629,7 +840,8 @@ send_willing (
struct sockaddr *from,
int fromlen,
ARRAY8Ptr authenticationName,
- ARRAY8Ptr status)
+ ARRAY8Ptr status,
+ int fd)
{
XdmcpHeader header;
@@ -647,7 +859,7 @@ send_willing (
XdmcpWriteARRAY8 (&buffer, authenticationName);
XdmcpWriteARRAY8 (&buffer, &Hostname);
XdmcpWriteARRAY8 (&buffer, status);
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) from, fromlen);
+ XdmcpFlush (fd, &buffer, (XdmcpNetaddr) from, fromlen);
}
static void
@@ -655,7 +867,8 @@ send_unwilling (
struct sockaddr *from,
int fromlen,
ARRAY8Ptr authenticationName,
- ARRAY8Ptr status)
+ ARRAY8Ptr status,
+ int fd)
{
XdmcpHeader header;
@@ -671,7 +884,7 @@ send_unwilling (
XdmcpWriteHeader (&buffer, &header);
XdmcpWriteARRAY8 (&buffer, &Hostname);
XdmcpWriteARRAY8 (&buffer, status);
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) from, fromlen);
+ XdmcpFlush (fd, &buffer, (XdmcpNetaddr) from, fromlen);
}
static unsigned long globalSessionID;
@@ -696,7 +909,8 @@ static void
request_respond (
struct sockaddr *from,
int fromlen,
- int length)
+ int length,
+ int fd)
{
CARD16 displayNumber;
ARRAY16 connectionTypes;
@@ -821,14 +1035,14 @@ request_respond (
&authenticationName,
&authenticationData,
&authorizationName,
- &authorizationData);
+ &authorizationData, fd);
}
else
{
decline: ;
send_decline (from, fromlen, &authenticationName,
&authenticationData,
- reason);
+ reason, fd);
if (pdpy)
DisposeProtoDisplay (pdpy);
}
@@ -850,7 +1064,8 @@ send_accept (
ARRAY8Ptr authenticationName,
ARRAY8Ptr authenticationData,
ARRAY8Ptr authorizationName,
- ARRAY8Ptr authorizationData)
+ ARRAY8Ptr authorizationData,
+ int fd)
{
XdmcpHeader header;
@@ -868,7 +1083,7 @@ send_accept (
XdmcpWriteARRAY8 (&buffer, authenticationData);
XdmcpWriteARRAY8 (&buffer, authorizationName);
XdmcpWriteARRAY8 (&buffer, authorizationData);
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) to, tolen);
+ XdmcpFlush (fd, &buffer, (XdmcpNetaddr) to, tolen);
}
static void
@@ -877,7 +1092,8 @@ send_decline (
int tolen,
ARRAY8Ptr authenticationName,
ARRAY8Ptr authenticationData,
- ARRAY8Ptr status)
+ ARRAY8Ptr status,
+ int fd)
{
XdmcpHeader header;
@@ -892,14 +1108,15 @@ send_decline (
XdmcpWriteARRAY8 (&buffer, status);
XdmcpWriteARRAY8 (&buffer, authenticationName);
XdmcpWriteARRAY8 (&buffer, authenticationData);
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) to, tolen);
+ XdmcpFlush (fd, &buffer, (XdmcpNetaddr) to, tolen);
}
static void
manage (
struct sockaddr *from,
int fromlen,
- int length)
+ int length,
+ int fd)
{
CARD32 sessionID;
CARD16 displayNumber;
@@ -949,7 +1166,7 @@ manage (
Debug ("Session ID %ld refused\n", (long) sessionID);
if (pdpy)
Debug ("Existing Session ID %ld\n", (long) pdpy->sessionID);
- send_refuse (from, fromlen, sessionID);
+ send_refuse (from, fromlen, sessionID, fd);
}
else
{
@@ -960,7 +1177,8 @@ manage (
Debug ("Computed display name: %s\n", name);
if (!name)
{
- send_failed (from, fromlen, "(no name)", sessionID, "out of memory");
+ send_failed (from, fromlen, "(no name)", sessionID,
+ "out of memory", fd);
goto abort;
}
d = FindDisplayByName (name);
@@ -972,7 +1190,8 @@ manage (
class = malloc (displayClass.length + 1);
if (!class)
{
- send_failed (from, fromlen, name, sessionID, "out of memory");
+ send_failed (from, fromlen, name, sessionID,
+ "out of memory", fd);
goto abort;
}
if (displayClass.length)
@@ -988,7 +1207,8 @@ manage (
from_save = (XdmcpNetaddr) malloc (fromlen);
if (!from_save)
{
- send_failed (from, fromlen, name, sessionID, "out of memory");
+ send_failed (from, fromlen, name, sessionID,
+ "out of memory", fd);
goto abort;
}
memmove( from_save, from, fromlen);
@@ -996,7 +1216,8 @@ manage (
if (!d)
{
free ((char *) from_save);
- send_failed (from, fromlen, name, sessionID, "out of memory");
+ send_failed (from, fromlen, name, sessionID,
+ "out of memory", fd);
goto abort;
}
d->displayType.location = Foreign;
@@ -1008,6 +1229,7 @@ manage (
d->displayNumber = pdpy->displayNumber;
ClientAddress (from, &clientAddress, &clientPort, &connectionType);
d->useChooser = 0;
+ d->xdmcpFd = fd;
if (IsIndirectClient (&clientAddress, connectionType))
{
Debug ("IsIndirectClient\n");
@@ -1028,7 +1250,8 @@ manage (
{
free ((char *) from_save);
free ((char *) d);
- send_failed (from, fromlen, name, sessionID, "out of memory");
+ send_failed (from, fromlen, name, sessionID,
+ "out of memory", fd);
goto abort;
}
d->authorizations[0] = pdpy->fileAuthorization;
@@ -1052,7 +1275,8 @@ SendFailed (
char *reason)
{
Debug ("Display start failed, sending Failed\n");
- send_failed ((struct sockaddr *)(d->from), d->fromlen, d->name, d->sessionID, reason);
+ send_failed ((struct sockaddr *)(d->from), d->fromlen, d->name,
+ d->sessionID, reason, d->xdmcpFd);
}
static void
@@ -1061,7 +1285,8 @@ send_failed (
int fromlen,
char *name,
CARD32 sessionID,
- char *reason)
+ char *reason,
+ int fd)
{
static char buf[256];
XdmcpHeader header;
@@ -1078,14 +1303,15 @@ send_failed (
XdmcpWriteHeader (&buffer, &header);
XdmcpWriteCARD32 (&buffer, sessionID);
XdmcpWriteARRAY8 (&buffer, &status);
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) from, fromlen);
+ XdmcpFlush (fd, &buffer, (XdmcpNetaddr) from, fromlen);
}
static void
send_refuse (
struct sockaddr *from,
int fromlen,
- CARD32 sessionID)
+ CARD32 sessionID,
+ int fd)
{
XdmcpHeader header;
@@ -1095,14 +1321,15 @@ send_refuse (
header.length = 4;
XdmcpWriteHeader (&buffer, &header);
XdmcpWriteCARD32 (&buffer, sessionID);
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) from, fromlen);
+ XdmcpFlush (fd, &buffer, (XdmcpNetaddr) from, fromlen);
}
static void
send_alive (
struct sockaddr *from,
int fromlen,
- int length)
+ int length,
+ int fd)
{
CARD32 sessionID;
CARD16 displayNumber;
@@ -1136,7 +1363,7 @@ send_alive (
XdmcpWriteHeader (&buffer, &header);
XdmcpWriteCARD8 (&buffer, sendRunning);
XdmcpWriteCARD32 (&buffer, sendSessionID);
- XdmcpFlush (xdmcpFd, &buffer, (XdmcpNetaddr) from, fromlen);
+ XdmcpFlush (fd, &buffer, (XdmcpNetaddr) from, fromlen);
}
}
}
@@ -1151,16 +1378,55 @@ NetworkAddressToHostname (
switch (connectionType)
{
case FamilyInternet:
+#if defined(IPv6) && defined(AF_INET6)
+ case FamilyInternet6:
+#endif
{
struct hostent *hostent = NULL;
+#if defined(IPv6) && defined(AF_INET6)
+ char dotted[INET6_ADDRSTRLEN];
+#else
char dotted[20];
+#endif
char *local_name = "";
+ int af_type;
+
+#if defined(IPv6) && defined(AF_INET6)
+ if (connectionType == FamilyInternet6)
+ af_type = AF_INET6;
+ else
+#endif
+ af_type = AF_INET;
hostent = gethostbyaddr ((char *)connectionAddress->data,
- connectionAddress->length, AF_INET);
+ connectionAddress->length, af_type);
if (hostent) {
/* check for DNS spoofing */
+#if defined(IPv6) && defined(AF_INET6)
+ struct addrinfo *ai = NULL, *nai;
+ if (getaddrinfo(hostent->h_name, NULL, NULL, &ai) == 0) {
+ for (nai = ai; nai != NULL; nai = nai->ai_next) {
+ if ((af_type == nai->ai_family) &&
+ (connectionAddress->length == nai->ai_addrlen) &&
+ (memcmp(connectionAddress->data,nai->ai_addr,
+ nai->ai_addrlen) != 0) ) {
+ break;
+ }
+ }
+ if (ai == NULL) {
+ inet_ntop(af_type, connectionAddress->data,
+ dotted, sizeof(dotted));
+
+ LogError("Possible DNS spoof attempt %s->%s.", dotted,
+ hostent->h_name);
+ hostent = NULL;
+ }
+ freeaddrinfo(ai);
+ } else {
+ hostent = NULL;
+ }
+#else
char *s = strdup(hostent->h_name); /* fscking non-reentrancy of getXXX() */
if ((hostent = gethostbyname(s))) {
if (memcmp((char*)connectionAddress->data, hostent->h_addr,
@@ -1172,15 +1438,21 @@ NetworkAddressToHostname (
}
}
free(s);
+#endif
}
if (!hostent) {
/* can't get name, so use emergency fallback */
+#if defined(IPv6) && defined(AF_INET6)
+ inet_ntop(af_type, connectionAddress->data,
+ dotted, sizeof(dotted));
+#else
sprintf(dotted, "%d.%d.%d.%d",
connectionAddress->data[0],
connectionAddress->data[1],
connectionAddress->data[2],
connectionAddress->data[3]);
+#endif
local_name = dotted;
LogError ("Cannot convert Internet address %s to host name\n",
dotted);
@@ -1198,7 +1470,7 @@ NetworkAddressToHostname (
break;
}
return name;
- }
+}
#if 0
static int