diff options
Diffstat (limited to 'nx-X11/lib/X11/ConnDis.c.X.original')
-rw-r--r-- | nx-X11/lib/X11/ConnDis.c.X.original | 1233 |
1 files changed, 0 insertions, 1233 deletions
diff --git a/nx-X11/lib/X11/ConnDis.c.X.original b/nx-X11/lib/X11/ConnDis.c.X.original deleted file mode 100644 index 30616d207..000000000 --- a/nx-X11/lib/X11/ConnDis.c.X.original +++ /dev/null @@ -1,1233 +0,0 @@ -/* $XdotOrg: xc/lib/X11/ConnDis.c,v 1.10 2005/07/03 07:00:55 daniels Exp $ */ -/* $Xorg: ConnDis.c,v 1.8 2001/02/09 02:03:31 xorgcvs Exp $ */ -/* - -Copyright 1989, 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. IN NO EVENT SHALL THE -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 -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/lib/X11/ConnDis.c,v 3.28 2003/12/02 23:33:17 herrb Exp $ */ - -/* - * This file contains operating system dependencies. - */ - -#define NEED_EVENTS - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xlibint.h> -#include <X11/Xtrans/Xtrans.h> -#include <X11/Xauth.h> -#include <X11/Xdmcp.h> -#include <stdio.h> -#include <ctype.h> - -#if !defined(WIN32) -#ifndef Lynx -#include <sys/socket.h> -#else -#include <socket.h> -#endif -#else -#include <X11/Xwindows.h> -#endif - -#ifndef X_CONNECTION_RETRIES /* number retries on ECONNREFUSED */ -#define X_CONNECTION_RETRIES 5 -#endif - -#ifdef LOCALCONN -#include <sys/utsname.h> -#endif - -#include "Xintconn.h" - -/* prototypes */ -static void GetAuthorization( - XtransConnInfo trans_conn, - int family, - char *saddr, - int saddrlen, - int idisplay, - char **auth_namep, - int *auth_namelenp, - char **auth_datap, - int *auth_datalenp); - -/* functions */ -static char *copystring (char *src, int len) -{ - char *dst = Xmalloc (len + 1); - - if (dst) { - strncpy (dst, src, len); - dst[len] = '\0'; - } - - return dst; -} - - -/* - * Attempts to connect to server, given display name. Returns file descriptor - * (network socket) or -1 if connection fails. Display names may be of the - * following format: - * - * [protocol/] [hostname] : [:] displaynumber [.screennumber] - * - * A string with exactly two colons seperating hostname from the display - * indicates a DECnet style name. Colons in the hostname may occur if an - * IPv6 numeric address is used as the hostname. An IPv6 numeric address - * may also end in a double colon, so three colons in a row indicates an - * IPv6 address ending in :: followed by :display. To make it easier for - * people to read, an IPv6 numeric address hostname may be surrounded by - * [ ] in a similar fashion to the IPv6 numeric address URL syntax defined - * by IETF RFC 2732. - * - * If no hostname and no protocol is specified, the string is interpreted - * as the most efficient local connection to a server on the same machine. - * This is usually: - * - * o shared memory - * o local stream - * o UNIX domain socket - * o TCP to local host - * - * This function will eventually call the X Transport Interface functions - * which expects the hostname in the format: - * - * [protocol/] [hostname] : [:] displaynumber - * - */ -XtransConnInfo -_X11TransConnectDisplay ( - char *display_name, - char **fullnamep, /* RETURN */ - int *dpynump, /* RETURN */ - int *screenp, /* RETURN */ - char **auth_namep, /* RETURN */ - int *auth_namelenp, /* RETURN */ - char **auth_datap, /* RETURN */ - int *auth_datalenp) /* RETURN */ -{ - int family; - int saddrlen; - Xtransaddr *saddr; - char *lastp, *lastc, *p; /* char pointers */ - char *pprotocol = NULL; /* start of protocol name */ - char *phostname = NULL; /* start of host of display */ - char *pdpynum = NULL; /* start of dpynum of display */ - char *pscrnum = NULL; /* start of screen of display */ - Bool dnet = False; /* if true, then DECnet format */ - int idisplay = 0; /* required display number */ - int iscreen = 0; /* optional screen number */ - /* int (*connfunc)(); */ /* method to create connection */ - int len, hostlen; /* length tmp variable */ - int retry; /* retry counter */ - char addrbuf[128]; /* final address passed to - X Transport Interface */ - char* address = addrbuf; - XtransConnInfo trans_conn = NULL; /* transport connection object */ - int connect_stat; -#ifdef LOCALCONN - struct utsname sys; -#endif -#ifdef TCPCONN - char *tcphostname = NULL; /* A place to save hostname pointer */ -#endif - - p = display_name; - - saddrlen = 0; /* set so that we can clear later */ - saddr = NULL; - - /* - * Step 0, find the protocol. This is delimited by the optional - * slash ('/'). - */ - for (lastp = p; *p && *p != ':' && *p != '/'; p++) ; - if (!*p) return NULL; /* must have a colon */ - - if (p != lastp && *p != ':') { /* protocol given? */ - pprotocol = copystring (lastp, p - lastp); - if (!pprotocol) goto bad; /* no memory */ - p++; /* skip the '/' */ - } else - p = display_name; /* reset the pointer in - case no protocol was given */ - - /* - * Step 1, find the hostname. This is delimited by either one colon, - * or two colons in the case of DECnet (DECnet Phase V allows a single - * colon in the hostname). (See note above regarding IPv6 numeric - * addresses with triple colons or [] brackets.) - */ - - lastp = p; - lastc = NULL; - for (; *p; p++) - if (*p == ':') - lastc = p; - - if (!lastc) return NULL; /* must have a colon */ - - if ((lastp != lastc) && (*(lastc - 1) == ':') -#if defined(IPv6) && defined(AF_INET6) - && ( ((lastc - 1) == lastp) || (*(lastc - 2) != ':')) -#endif - ) { - /* DECnet display specified */ - -#ifndef DNETCONN - goto bad; -#else - dnet = True; - /* override the protocol specified */ - if (pprotocol) - Xfree (pprotocol); - pprotocol = copystring ("dnet", 4); - hostlen = lastc - 1 - lastp; -#endif - } - else - hostlen = lastc - lastp; - - if (hostlen > 0) { /* hostname given? */ - phostname = copystring (lastp, hostlen); - if (!phostname) goto bad; /* no memory */ - } - - p = lastc; - -#ifdef LOCALCONN - /* check if phostname == localnodename AND protocol not specified */ - if (!pprotocol && phostname && uname(&sys) >= 0 && - !strncmp(phostname, sys.nodename, - (strlen(sys.nodename) < strlen(phostname) ? - strlen(phostname) : strlen(sys.nodename)))) - { -#ifdef TCPCONN - /* - * We'll first attempt to connect using the local transport. If - * this fails (which is the case if sshd X protocol forwarding is - * being used), retry using tcp and this hostname. - */ - tcphostname = copystring(phostname, strlen(phostname)); -#endif - Xfree (phostname); - phostname = copystring ("unix", 4); - } -#endif - - - /* - * Step 2, find the display number. This field is required and is - * delimited either by a nul or a period, depending on whether or not - * a screen number is present. - */ - - for (lastp = ++p; *p && isascii(*p) && isdigit(*p); p++) ; - if ((p == lastp) || /* required field */ - (*p != '\0' && *p != '.') || /* invalid non-digit terminator */ - !(pdpynum = copystring (lastp, p - lastp))) /* no memory */ - goto bad; - idisplay = atoi (pdpynum); - - - /* - * Step 3, find the screen number. This field is optional. It is - * present only if the display number was followed by a period (which - * we've already verified is the only non-nul character). - */ - - if (*p) { - for (lastp = ++p; *p && isascii(*p) && isdigit (*p); p++) ; - if (p != lastp) { - if (*p || /* non-digits */ - !(pscrnum = copystring (lastp, p - lastp))) /* no memory */ - goto bad; - iscreen = atoi (lastp); - } - } - - /* - * At this point, we know the following information: - * - * pprotocol protocol string or NULL - * phostname hostname string or NULL - * idisplay display number - * iscreen screen number - * dnet DECnet boolean - * - * We can now decide which transport to use based on the ConnectionFlags - * build parameter the hostname string. If phostname is NULL or equals - * the string "local", then choose the best transport. If phostname - * is "unix", then choose BSD UNIX domain sockets (if configured). - */ - -#if defined(TCPCONN) || defined(UNIXCONN) || defined(LOCALCONN) || defined(MNX_TCPCONN) || defined(OS2PIPECONN) - if (!pprotocol) { - if (!phostname) { -#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN) - pprotocol = copystring ("local", 5); -#if defined(TCPCONN) - tcphostname = copystring("localhost", 9); -#endif - } - else - { -#endif - pprotocol = copystring ("tcp", 3); - } - } -#endif - -#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN) - /* - * Now that the defaults have been established, see if we have any - * special names that we have to override: - * - * :N => if UNIXCONN then unix-domain-socket - * ::N => if UNIXCONN then unix-domain-socket - * unix:N => if UNIXCONN then unix-domain-socket - * - * Note that if UNIXCONN isn't defined, then we can use the default - * transport connection function set above. - */ - - if (!phostname) { -#ifdef apollo - ; /* Unix domain sockets are *really* bad on apollos */ -#else - if( pprotocol ) Xfree(pprotocol); - pprotocol = copystring ("local", 5); -#endif - } - else if (strcmp (phostname, "unix") == 0) { - if( pprotocol ) Xfree(pprotocol); - pprotocol = copystring ("local", 5); - } -#endif - -#if defined(TCPCONN) - connect: -#endif - /* - * This seems kind of backwards, but we need to put the protocol, - * host, and port back together to pass to _X11TransOpenCOTSClient(). - */ - - { - int olen = 3 + (pprotocol ? strlen(pprotocol) : 0) + - (phostname ? strlen(phostname) : 0) + - (pdpynum ? strlen(pdpynum) : 0); - if (olen > sizeof addrbuf) address = Xmalloc (olen); - } - if (!address) goto bad; - - sprintf(address,"%s/%s:%d", - pprotocol ? pprotocol : "", - phostname ? phostname : "", - idisplay ); - - /* - * Make the connection, also need to get the auth address info for - * the connection. Do retries in case server host has hit its - * backlog (which, unfortunately, isn't distinguishable from there not - * being a server listening at all, which is why we have to not retry - * too many times). - */ - for(retry=X_CONNECTION_RETRIES; retry>=0; retry-- ) - { - if ( (trans_conn = _X11TransOpenCOTSClient(address)) == NULL ) - { - break; - } - if ((connect_stat = _X11TransConnect(trans_conn,address)) < 0 ) - { - _X11TransClose(trans_conn); - trans_conn = NULL; - - if (connect_stat == TRANS_TRY_CONNECT_AGAIN) - { - sleep(1); - continue; - } - else - break; - } - - _X11TransGetPeerAddr(trans_conn, &family, &saddrlen, &saddr); - - /* - * The family is given in a socket format (ie AF_INET). This - * will convert it to the format used by the authorization and - * X protocol (ie FamilyInternet). - */ - - if( _X11TransConvertAddress(&family, &saddrlen, &saddr) < 0 ) - { - _X11TransClose(trans_conn); - trans_conn = NULL; - sleep(1); - if (saddr) - { - free ((char *) saddr); - saddr = NULL; - } - continue; - } - - break; - } - - if (address != addrbuf) Xfree (address); - address = addrbuf; - - if( trans_conn == NULL ) - goto bad; - - /* - * Set close-on-exec so that programs that fork() doesn't get confused. - */ - - _X11TransSetOption(trans_conn,TRANS_CLOSEONEXEC,1); - - /* - * Build the expanded display name: - * - * [host] : [:] dpy . scr \0 - */ - len = ((phostname ? strlen(phostname) : 0) + 1 + (dnet ? 1 : 0) + - strlen(pdpynum) + 1 + (pscrnum ? strlen(pscrnum) : 1) + 1); - *fullnamep = (char *) Xmalloc (len); - if (!*fullnamep) goto bad; - - sprintf (*fullnamep, "%s%s%d.%d", - (phostname ? phostname : ""), - (dnet ? "::" : ":"), - idisplay, iscreen); - - *dpynump = idisplay; - *screenp = iscreen; - if (pprotocol) Xfree (pprotocol); - if (phostname) Xfree (phostname); - if (pdpynum) Xfree (pdpynum); - if (pscrnum) Xfree (pscrnum); -#ifdef TCPCONN - if (tcphostname) Xfree (tcphostname); -#endif - - GetAuthorization(trans_conn, family, (char *) saddr, saddrlen, idisplay, - auth_namep, auth_namelenp, auth_datap, auth_datalenp); - return trans_conn; - - - /* - * error return; make sure everything is cleaned up. - */ - bad: - if (trans_conn) (void)_X11TransClose(trans_conn); - if (saddr) free ((char *) saddr); - if (pprotocol) Xfree (pprotocol); - if (phostname) Xfree (phostname); - if (address && address != addrbuf) { Xfree(address); address = addrbuf; } - -#if defined(TCPCONN) - if (tcphostname) { - pprotocol = copystring("tcp", 3); - phostname = tcphostname; - tcphostname = NULL; - goto connect; - } -#endif - - if (pdpynum) Xfree (pdpynum); - if (pscrnum) Xfree (pscrnum); - return NULL; - -} - -/* - * This is gross, but we need it for compatiblity. - * The test suite relies on the following interface. - * - */ - -int _XConnectDisplay ( - char *display_name, - char **fullnamep, /* RETURN */ - int *dpynump, /* RETURN */ - int *screenp, /* RETURN */ - char **auth_namep, /* RETURN */ - int *auth_namelenp, /* RETURN */ - char **auth_datap, /* RETURN */ - int *auth_datalenp) /* RETURN */ -{ - XtransConnInfo trans_conn; - - trans_conn = _X11TransConnectDisplay ( - display_name, fullnamep, dpynump, screenp, - auth_namep, auth_namelenp, auth_datap, auth_datalenp); - - if (trans_conn) - { - int fd = _X11TransGetConnectionNumber (trans_conn); - _X11TransFreeConnInfo (trans_conn); - return (fd); - } - else - return (-1); -} - - -/***************************************************************************** - * * - * Connection Utility Routines * - * * - *****************************************************************************/ - -/* - * Disconnect from server. - */ - -int _XDisconnectDisplay (trans_conn) - -XtransConnInfo trans_conn; - -{ - _X11TransDisconnect(trans_conn); - _X11TransClose(trans_conn); - return 0; -} - - - -Bool -_XSendClientPrefix (dpy, client, auth_proto, auth_string, prefix) - Display *dpy; - xConnClientPrefix *client; /* contains count for auth_* */ - char *auth_proto, *auth_string; /* NOT null-terminated */ - xConnSetupPrefix *prefix; /* prefix information */ -{ - int auth_length = client->nbytesAuthProto; - int auth_strlen = client->nbytesAuthString; - static char padbuf[3]; /* for padding to 4x bytes */ - int pad; - struct iovec iovarray[5], *iov = iovarray; - int niov = 0; - int len = 0; - -#define add_to_iov(b,l) \ - { iov->iov_base = (b); iov->iov_len = (l); iov++, niov++; len += (l); } - - add_to_iov ((caddr_t) client, SIZEOF(xConnClientPrefix)); - - /* - * write authorization protocol name and data - */ - if (auth_length > 0) { - add_to_iov (auth_proto, auth_length); - pad = -auth_length & 3; /* pad auth_length to a multiple of 4 */ - if (pad) add_to_iov (padbuf, pad); - } - if (auth_strlen > 0) { - add_to_iov (auth_string, auth_strlen); - pad = -auth_strlen & 3; /* pad auth_strlen to a multiple of 4 */ - if (pad) add_to_iov (padbuf, pad); - } - -#undef add_to_iov - - len -= _X11TransWritev (dpy->trans_conn, iovarray, niov); - - /* - * Set the connection non-blocking since we use select() to block. - */ - - _X11TransSetOption(dpy->trans_conn, TRANS_NONBLOCKING, 1); - - if (len != 0) - return -1; - -#ifdef K5AUTH - if (auth_length == 14 && - !strncmp(auth_proto, "MIT-KERBEROS-5", 14)) - { - return k5_clientauth(dpy, prefix); - } else -#endif - return 0; -} - - -#ifdef STREAMSCONN -#ifdef SVR4 -#include <tiuser.h> -#else -#undef HASXDMAUTH -#endif -#endif - -#ifdef SECURE_RPC -#include <rpc/rpc.h> -#ifdef ultrix -#include <time.h> -#include <rpc/auth_des.h> -#endif -#endif - -#ifdef HASXDMAUTH -#include <time.h> -#define Time_t time_t -#endif - -/* - * First, a routine for setting authorization data - */ -static int xauth_namelen = 0; -static char *xauth_name = NULL; /* NULL means use default mechanism */ -static int xauth_datalen = 0; -static char *xauth_data = NULL; /* NULL means get default data */ - -/* - * This is a list of the authorization names which Xlib currently supports. - * Xau will choose the file entry which matches the earliest entry in this - * array, allowing us to prioritize these in terms of the most secure first - */ - -static char *default_xauth_names[] = { -#ifdef K5AUTH - "MIT-KERBEROS-5", -#endif -#ifdef SECURE_RPC - "SUN-DES-1", -#endif -#ifdef HASXDMAUTH - "XDM-AUTHORIZATION-1", -#endif - "MIT-MAGIC-COOKIE-1" -}; - -static _Xconst int default_xauth_lengths[] = { -#ifdef K5AUTH - 14, /* strlen ("MIT-KERBEROS-5") */ -#endif -#ifdef SECURE_RPC - 9, /* strlen ("SUN-DES-1") */ -#endif -#ifdef HASXDMAUTH - 19, /* strlen ("XDM-AUTHORIZATION-1") */ -#endif - 18 /* strlen ("MIT-MAGIC-COOKIE-1") */ -}; - -#define NUM_DEFAULT_AUTH (sizeof (default_xauth_names) / sizeof (default_xauth_names[0])) - -static char **xauth_names = default_xauth_names; -static _Xconst int *xauth_lengths = default_xauth_lengths; - -static int xauth_names_length = NUM_DEFAULT_AUTH; - -void XSetAuthorization (name, namelen, data, datalen) - int namelen, datalen; /* lengths of name and data */ - char *name, *data; /* NULL or arbitrary array of bytes */ -{ - char *tmpname, *tmpdata; - - _XLockMutex(_Xglobal_lock); - if (xauth_name) Xfree (xauth_name); /* free any existing data */ - if (xauth_data) Xfree (xauth_data); - - xauth_name = xauth_data = NULL; /* mark it no longer valid */ - xauth_namelen = xauth_datalen = 0; - _XUnlockMutex(_Xglobal_lock); - - if (namelen < 0) namelen = 0; /* check for bogus inputs */ - if (datalen < 0) datalen = 0; /* maybe should return? */ - - if (namelen > 0) { /* try to allocate space */ - tmpname = Xmalloc ((unsigned) namelen); - if (!tmpname) return; - memcpy (tmpname, name, namelen); - } else { - tmpname = NULL; - } - - if (datalen > 0) { - tmpdata = Xmalloc ((unsigned) datalen); - if (!tmpdata) { - if (tmpname) (void) Xfree (tmpname); - return; - } - memcpy (tmpdata, data, datalen); - } else { - tmpdata = NULL; - } - - _XLockMutex(_Xglobal_lock); - xauth_name = tmpname; /* and store the suckers */ - xauth_namelen = namelen; - if (tmpname) - { - xauth_names = &xauth_name; - xauth_lengths = &xauth_namelen; - xauth_names_length = 1; - } - else - { - xauth_names = default_xauth_names; - xauth_lengths = default_xauth_lengths; - xauth_names_length = NUM_DEFAULT_AUTH; - } - xauth_data = tmpdata; - xauth_datalen = datalen; - _XUnlockMutex(_Xglobal_lock); - return; -} - -#ifdef SECURE_RPC -/* - * Create a credential that we can send to the X server. - */ -static int -auth_ezencode(servername, window, cred_out, len) - char *servername; - int window; - char *cred_out; - int *len; -{ - AUTH *a; - XDR xdr; - -#if defined(SVR4) && defined(sun) - a = authdes_seccreate(servername, window, NULL, NULL); -#else - a = (AUTH *)authdes_create(servername, window, NULL, NULL); -#endif - if (a == (AUTH *)NULL) { - perror("auth_create"); - return 0; - } - xdrmem_create(&xdr, cred_out, *len, XDR_ENCODE); - if (AUTH_MARSHALL(a, &xdr) == FALSE) { - perror("auth_marshall"); - AUTH_DESTROY(a); - return 0; - } - *len = xdr_getpos(&xdr); - AUTH_DESTROY(a); - return 1; -} -#endif - -#ifdef K5AUTH -#include <com_err.h> - -extern krb5_flags krb5_kdc_default_options; - -/* - * k5_clientauth - * - * Returns non-zero if the setup prefix has been read, - * so we can tell XOpenDisplay to not bother looking for it by - * itself. - */ -static int k5_clientauth(dpy, sprefix) - Display *dpy; - xConnSetupPrefix *sprefix; -{ - krb5_error_code retval; - xReq prefix; - char *buf; - CARD16 plen, tlen; - krb5_data kbuf; - krb5_ccache cc; - krb5_creds creds; - krb5_principal cprinc, sprinc; - krb5_ap_rep_enc_part *repl; - - krb5_init_ets(); - /* - * stage 0: get encoded principal and tgt from server - */ - _XRead(dpy, (char *)&prefix, sz_xReq); - if (prefix.reqType != 2 && prefix.reqType != 3) - /* not an auth packet... so deal */ - if (prefix.reqType == 0 || prefix.reqType == 1) - { - memcpy((char *)sprefix, (char *)&prefix, sz_xReq); - _XRead(dpy, (char *)sprefix + sz_xReq, - sz_xConnSetupPrefix - sz_xReq); /* ewww... gross */ - return 1; - } - else - { - fprintf(stderr, - "Xlib: Krb5 stage 0: got illegal connection setup success code %d\n", - prefix.reqType); - return -1; - } - if (prefix.data != 0) - { - fprintf(stderr, "Xlib: got out of sequence (%d) packet in Krb5 auth\n", - prefix.data); - return -1; - } - buf = (char *)malloc((prefix.length << 2) - sz_xReq); - if (buf == NULL) /* malloc failed. Run away! */ - { - fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); - return -1; - } - tlen = (prefix.length << 2) - sz_xReq; - _XRead(dpy, buf, tlen); - if (prefix.reqType == 2 && tlen < 6) - { - fprintf(stderr, "Xlib: Krb5 stage 0 reply from server too short\n"); - free(buf); - return -1; - } - if (prefix.reqType == 2) - { - plen = *(CARD16 *)buf; - kbuf.data = buf + 2; - kbuf.length = (plen > tlen) ? tlen : plen; - } - else - { - kbuf.data = buf; - kbuf.length = tlen; - } - if (XauKrb5Decode(kbuf, &sprinc)) - { - free(buf); - fprintf(stderr, "Xlib: XauKrb5Decode bombed\n"); - return -1; - } - if (prefix.reqType == 3) /* do some special stuff here */ - { - char *sname, *hostname = NULL; - - sname = (char *)malloc(krb5_princ_component(sprinc, 0)->length + 1); - if (sname == NULL) - { - free(buf); - krb5_free_principal(sprinc); - fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); - return -1; - } - memcpy(sname, krb5_princ_component(sprinc, 0)->data, - krb5_princ_component(sprinc, 0)->length); - sname[krb5_princ_component(sprinc, 0)->length] = '\0'; - krb5_free_principal(sprinc); - if (dpy->display_name[0] != ':') /* hunt for a hostname */ - { - char *t; - - if ((hostname = (char *)malloc(strlen(dpy->display_name))) - == NULL) - { - free(buf); - free(sname); - fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); - return -1; - } - strcpy(hostname, dpy->display_name); - t = strchr(hostname, ':'); - if (t == NULL) - { - free(buf); - free(sname); - free(hostname); - fprintf(stderr, - "Xlib: shouldn't get here! malformed display name."); - return -1; - } - if ((t - hostname + 1 < strlen(hostname)) && t[1] == ':') - t++; - *t = '\0'; /* truncate the dpy number out */ - } - retval = krb5_sname_to_principal(hostname, sname, - KRB5_NT_SRV_HST, &sprinc); - free(sname); - if (hostname) - free(hostname); - if (retval) - { - free(buf); - fprintf(stderr, "Xlib: krb5_sname_to_principal failed: %s\n", - error_message(retval)); - return -1; - } - } - if (retval = krb5_cc_default(&cc)) - { - free(buf); - krb5_free_principal(sprinc); - fprintf(stderr, "Xlib: krb5_cc_default failed: %s\n", - error_message(retval)); - return -1; - } - if (retval = krb5_cc_get_principal(cc, &cprinc)) - { - free(buf); - krb5_free_principal(sprinc); - fprintf(stderr, "Xlib: cannot get Kerberos principal from \"%s\": %s\n", - krb5_cc_default_name(), error_message(retval)); - return -1; - } - bzero((char *)&creds, sizeof(creds)); - creds.server = sprinc; - creds.client = cprinc; - if (prefix.reqType == 2) - { - creds.second_ticket.length = tlen - plen - 2; - creds.second_ticket.data = buf + 2 + plen; - retval = krb5_get_credentials(KRB5_GC_USER_USER | - krb5_kdc_default_options, - cc, &creds); - } - else - retval = krb5_get_credentials(krb5_kdc_default_options, - cc, &creds); - if (retval) - { - free(buf); - krb5_free_cred_contents(&creds); - fprintf(stderr, "Xlib: cannot get Kerberos credentials: %s\n", - error_message(retval)); - return -1; - } - /* - * now format the ap_req to send to the server - */ - if (prefix.reqType == 2) - retval = krb5_mk_req_extended(AP_OPTS_USE_SESSION_KEY | - AP_OPTS_MUTUAL_REQUIRED, NULL, - 0, 0, NULL, cc, - &creds, NULL, &kbuf); - else - retval = krb5_mk_req_extended(AP_OPTS_MUTUAL_REQUIRED, NULL, - 0, 0, NULL, cc, &creds, NULL, - &kbuf); - free(buf); - if (retval) /* Some manner of Kerberos lossage */ - { - krb5_free_cred_contents(&creds); - fprintf(stderr, "Xlib: krb5_mk_req_extended failed: %s\n", - error_message(retval)); - return -1; - } - prefix.reqType = 1; - prefix.data = 0; - prefix.length = (kbuf.length + sz_xReq + 3) >> 2; - /* - * stage 1: send ap_req to server - */ - _XSend(dpy, (char *)&prefix, sz_xReq); - _XSend(dpy, (char *)kbuf.data, kbuf.length); - free(kbuf.data); - /* - * stage 2: get ap_rep from server to mutually authenticate - */ - _XRead(dpy, (char *)&prefix, sz_xReq); - if (prefix.reqType != 2) - if (prefix.reqType == 0 || prefix.reqType == 1) - { - memcpy((char *)sprefix, (char *)&prefix, sz_xReq); - _XRead(dpy, (char *)sprefix + sz_xReq, - sz_xConnSetupPrefix - sz_xReq); - return 1; - } - else - { - fprintf(stderr, - "Xlib: Krb5 stage 2: got illegal connection setup success code %d\n", - prefix.reqType); - return -1; - } - if (prefix.data != 2) - return -1; - kbuf.length = (prefix.length << 2) - sz_xReq; - kbuf.data = (char *)malloc(kbuf.length); - if (kbuf.data == NULL) - { - fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); - return -1; - } - _XRead(dpy, (char *)kbuf.data, kbuf.length); - retval = krb5_rd_rep(&kbuf, &creds.keyblock, &repl); - if (retval) - { - free(kbuf.data); - fprintf(stderr, "Xlib: krb5_rd_rep failed: %s\n", - error_message(retval)); - return -1; - } - free(kbuf.data); - /* - * stage 3: send a short ack to the server and return - */ - prefix.reqType = 3; - prefix.data = 0; - prefix.length = sz_xReq >> 2; - _XSend(dpy, (char *)&prefix, sz_xReq); - return 0; -} -#endif /* K5AUTH */ - -static void -GetAuthorization( - XtransConnInfo trans_conn, - int family, - char *saddr, - int saddrlen, - int idisplay, - char **auth_namep, /* RETURN */ - int *auth_namelenp, /* RETURN */ - char **auth_datap, /* RETURN */ - int *auth_datalenp) /* RETURN */ -{ -#ifdef SECURE_RPC - char rpc_cred[MAX_AUTH_BYTES]; -#endif -#ifdef HASXDMAUTH - unsigned char xdmcp_data[192/8]; -#endif - char *auth_name; - int auth_namelen; - unsigned char *auth_data; - int auth_datalen; - Xauth *authptr = NULL; - -/* - * Look up the authorization protocol name and data if necessary. - */ - if (xauth_name && xauth_data) { - auth_namelen = xauth_namelen; - auth_name = xauth_name; - auth_datalen = xauth_datalen; - auth_data = (unsigned char *) xauth_data; - } else { - char dpynumbuf[40]; /* big enough to hold 2^64 and more */ - (void) sprintf (dpynumbuf, "%d", idisplay); - - authptr = XauGetBestAuthByAddr ((unsigned short) family, - (unsigned short) saddrlen, - saddr, - (unsigned short) strlen (dpynumbuf), - dpynumbuf, - xauth_names_length, - xauth_names, - xauth_lengths); - if (authptr) { - auth_namelen = authptr->name_length; - auth_name = (char *)authptr->name; - auth_datalen = authptr->data_length; - auth_data = (unsigned char *) authptr->data; - } else { - auth_namelen = 0; - auth_name = NULL; - auth_datalen = 0; - auth_data = NULL; - } - } -#ifdef HASXDMAUTH - /* - * build XDM-AUTHORIZATION-1 data - */ - if (auth_namelen == 19 && !strncmp (auth_name, "XDM-AUTHORIZATION-1", 19)) - { - int i, j; - Time_t now; - int family, addrlen; - Xtransaddr *addr = NULL; - - for (j = 0; j < 8; j++) - xdmcp_data[j] = auth_data[j]; - - _X11TransGetMyAddr(trans_conn, &family, &addrlen, &addr); - - switch( family ) - { -#ifdef AF_INET - case AF_INET: - { - /* - * addr will contain a sockaddr_in with all - * of the members already in network byte order. - */ - - for(i=4; i<8; i++) /* do sin_addr */ - xdmcp_data[j++] = ((char *)addr)[i]; - for(i=2; i<4; i++) /* do sin_port */ - xdmcp_data[j++] = ((char *)addr)[i]; - break; - } -#endif /* AF_INET */ -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - /* XXX This should probably never happen */ - { - unsigned char ipv4mappedprefix[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; - - /* In the case of v4 mapped addresses send the v4 - part of the address - addr is already in network byte order */ - if (memcmp(addr+8, ipv4mappedprefix, 12) == 0) { - for (i = 20 ; i < 24; i++) - xdmcp_data[j++] = ((char *)addr)[i]; - - /* Port number */ - for (i=2; i<4; i++) - xdmcp_data[j++] = ((char *)addr)[i]; - } else { - /* Fake data to keep the data aligned. Otherwise the - the server will bail about incorrect timing data */ - for (i = 0; i < 6; i++) { - xdmcp_data[j++] = 0; - } - } - break; - } -#endif /* AF_INET6 */ -#ifdef AF_UNIX - case AF_UNIX: - { - /* - * We don't use the sockaddr_un for this encoding. - * Instead, we create a sockaddr_in filled with - * a decreasing counter for the address, and the - * pid for the port. - */ - - static unsigned long unix_addr = 0xFFFFFFFF; - unsigned long the_addr; - unsigned short the_port; - unsigned long the_utime; - struct timeval tp; - - X_GETTIMEOFDAY(&tp); - _XLockMutex(_Xglobal_lock); - the_addr = unix_addr--; - _XUnlockMutex(_Xglobal_lock); - the_utime = (unsigned long) tp.tv_usec; - the_port = getpid (); - - xdmcp_data[j++] = (the_utime >> 24) & 0xFF; - xdmcp_data[j++] = (the_utime >> 16) & 0xFF; - xdmcp_data[j++] = ((the_utime >> 8) & 0xF0) - | ((the_addr >> 8) & 0x0F); - xdmcp_data[j++] = (the_addr >> 0) & 0xFF; - xdmcp_data[j++] = (the_port >> 8) & 0xFF; - xdmcp_data[j++] = (the_port >> 0) & 0xFF; - break; - } -#endif /* AF_UNIX */ -#ifdef AF_DECnet - case AF_DECnet: - /* - * What is the defined encoding for this? - */ - break; -#endif /* AF_DECnet */ - default: - /* - * Need to return some kind of errro status here. - * maybe a NULL auth?? - */ - break; - } /* switch */ - - if (addr) - free ((char *) addr); - - time (&now); - xdmcp_data[j++] = (now >> 24) & 0xFF; - xdmcp_data[j++] = (now >> 16) & 0xFF; - xdmcp_data[j++] = (now >> 8) & 0xFF; - xdmcp_data[j++] = (now >> 0) & 0xFF; - while (j < 192 / 8) - xdmcp_data[j++] = 0; - _XLockMutex(_Xglobal_lock); - /* this function might use static data, hence the lock around it */ - XdmcpWrap (xdmcp_data, auth_data + 8, - xdmcp_data, j); - _XUnlockMutex(_Xglobal_lock); - auth_data = xdmcp_data; - auth_datalen = j; - } -#endif /* HASXDMAUTH */ -#ifdef SECURE_RPC - /* - * The SUN-DES-1 authorization protocol uses the - * "secure RPC" mechanism in SunOS 4.0+. - */ - if (auth_namelen == 9 && !strncmp(auth_name, "SUN-DES-1", 9)) { - char servernetname[MAXNETNAMELEN + 1]; - - /* - * Copy over the server's netname from the authorization - * data field filled in by XauGetAuthByAddr(). - */ - if (auth_datalen > MAXNETNAMELEN) { - auth_datalen = 0; - auth_data = NULL; - } else { - memcpy(servernetname, auth_data, auth_datalen); - servernetname[auth_datalen] = '\0'; - - auth_datalen = sizeof (rpc_cred); - if (auth_ezencode(servernetname, 100, rpc_cred, - &auth_datalen)) - auth_data = (unsigned char *) rpc_cred; - else { - auth_datalen = 0; - auth_data = NULL; - } - } - } -#endif - if (saddr) free ((char *) saddr); - if ((*auth_namelenp = auth_namelen)) - { - if ((*auth_namep = Xmalloc(auth_namelen))) - memcpy(*auth_namep, auth_name, auth_namelen); - else - *auth_namelenp = 0; - } - else - *auth_namep = NULL; - if ((*auth_datalenp = auth_datalen)) - { - if ((*auth_datap = Xmalloc(auth_datalen))) - memcpy(*auth_datap, auth_data, auth_datalen); - else - *auth_datalenp = 0; - } - else - *auth_datap = NULL; - if (authptr) XauDisposeAuth (authptr); -} |