Display ----- Send indirect query -----> Manager Manager ----- Forward query to other machines -----> Other Managers Other ----- Send replies giving status -----> Display Managers (The display updates the host list. The user chooses a host.) Display ------ Request session -----> Other Manager (etc.)
Display ----- Send indirect query -----> Manager (The manager does not forward the query.) Manager ----- Send willing reply -----> Display (The display responds to the first willing reply.) Display ------ Request session -----> Manager Manager ------ Accept session -----> Display Display ------ Manage session -----> Manager Manager ------ X connection from the chooser -----> Display Manager ----- Forward query to other machines -----> Other Managers Other ----- Send replies giving status -----> Manager Managers (The manger updates the host list. The user chooses a host from the list. The chooser tells xdm which host has been chosen.) Manager ------ Closes X connection -----> Display (The display resets.) Display ----- Send indirect query -----> Manager (The manager ignores the query and its retransmissions up to 15 secs.) Manager ----- Forward query to other machine -----> Other Manager Other ----- Send reply giving status -----> Manager Manager Display ------ Request session -----> Other Manager (etc.)
In the XDMCP protocol, xdm does not need to know which machine a user has chosen because the choosing is done entirely in the X-server, and a manager will always respond to an indirect query by forwarding the query to other managers. In the implemented protocol, choosing the host is done on the machine running xdm, and the chooser (known as dtchooser by CDE users) has to communicate the user's choice of host back to xdm (dtlogin) so that when the X server resets and sends out an xdmcp indirect query, xdm can return an appropriate response. This communication is done using a tcp connection. The master xdm creates a listener during its initialisation, and the chooser processes connect to the master xdm when they wish to register a user's choice of host. The port that xdm is listening on is given on the chooser's command line.
/usr/dt/bin/dtchooser -xdmaddress 00020401c0a81243 -clientaddress c0a81244 ... / | \ Family Port IP addressBy using a tcp socket, xdm is unable to distinguish the chooser's connections from other connections. Since the the port is not bound to a local address, anyone on the Internet can exploit this weakness to choose which machine you are going to have a session on. The port number used is usually 1024 on Linux 2.0, and 1025 on Linux 2.1, so the exploit is quite easy. If you have a local account, you don't even have to guess the port number, since ps will tell you.
The chooser only makes the connection when the user has chosen a host, so it continues to operate correctly even if xdm was restarted while the chooser was running. Replacing the tcp connection with a pipe or socketpair would break that functionality. Instead, I have replaced the tcp socket with Unix-domain socket.
The socket is placed in a directory because many versions of Unix don't support permissions on sockets. The directory should be created using:
(umask 077 && mkdir /usr/lib/X11/xdm/socketdir)The following patch was made against XFree86-3.3.2 and should be applied using
cd <Xsourcedir>/xc/programs/xdm && patch -p1 </path/to/xdm-socket.patchxdm-socket.patch
This is the second version of the patch - the first version only worked on Linux 2.1 systems. You should verify that the patch is working correctly by restarting xdm, starting a display that makes an indirect query, checking that the command line has a pathname instead of an IP address, and selecting a host from the list.
You might also be interested in a patch to make generate better authorization keys: