*** tkUnixSend.c	2004/06/04 19:31:13	1.1
--- tkUnixSend.c	2004/06/04 20:46:42
***************
*** 12,23 ****
   * See the file "license.terms" for information on usage and redistribution
   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
   *
!  * RCS: @(#) $Id: tkUnixSend.c,v 1.1 2004/06/04 19:31:13 jmorzins Exp $
   */
  
  #include "tkPort.h"
  #include "tkInt.h"
  #include "tkUnixInt.h"
  
  /* 
   * The following structure is used to keep track of the interpreters
--- 12,33 ----
   * See the file "license.terms" for information on usage and redistribution
   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
   *
!  * RCS: @(#) $Id: tkUnixSend.c,v 1.3 2004/06/04 20:46:41 jmorzins Exp $
   */
  
  #include "tkPort.h"
  #include "tkInt.h"
  #include "tkUnixInt.h"
+ #if !defined(TK_NO_SECURITY) && !defined(TK_FULL_SECURITY)
+ #include <X11/Xauth.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/param.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ #include <arpa/inet.h>
+ #include <unistd.h>
+ #endif
  
  /* 
   * The following structure is used to keep track of the interpreters
***************
*** 694,699 ****
--- 704,710 ----
  #ifdef TK_NO_SECURITY
      return 1;
  #else
+ #ifdef TK_FULL_SECURITY
      XHostAddress *addrPtr;
      int numHosts, secure;
      Bool enabled;
***************
*** 707,712 ****
--- 718,808 ----
  	XFree((char *) addrPtr);
      }
      return secure;
+ #else
+ /*
+  * Code to cause wish to be a little more tolerant of the way that
+  * X11R6 reports xhost'ed hosts.  It's messy, and has warts in its
+  * logic, but it mostly works.  (If X is recompiled with Xauth enabled,
+  * this code may have to be looked at.)
+  */
+     XHostAddress *addrPtr;
+     int numHosts, secure;
+     Bool enabled;
+     char **p, hostName[MAXHOSTNAMELEN];
+     static struct hostent *hp;
+     struct in_addr myAddr[10], in;
+     int i, j, match;
+ 
+     secure = 1;
+     addrPtr = XListHosts(dispPtr->display, &numHosts, &enabled);
+     
+     if (enabled) {
+       if (gethostname(hostName, sizeof(hostName)) == 0) {
+ 	if ((hp = gethostbyname(hostName))) {
+ 	  for ((i=0, p=hp->h_addr_list); (*p != 0) && (i < 9); (i++, p++)) {
+ 	    memcpy(&(myAddr[i].s_addr), *p, sizeof(myAddr[i].s_addr));
+ 	  }
+ 	  if (i < 10) {
+ 	    myAddr[i].s_addr = 0;
+ 	  }
+ 	}
+ 	else			/* gethostbyname */
+ 	  secure = 0;
+       }
+       else			/* gethostname */
+ 	secure = 0;
+     }
+     else			/* enabled */
+       secure = 0;
+ 
+ 
+     if (secure) {
+       if (numHosts > 0) {	/* Check out the Xhosts one by one */
+ 	for (i = 0; i < numHosts; i++ ) {
+ 
+ 	  switch (addrPtr[i].family) {
+ 	  case FamilyInternet:
+ 	    if ((hp = gethostbyaddr(addrPtr[i].address,
+ 				   addrPtr[i].length, AF_INET))) {
+ 
+ /* Compare its addr to my addr, set match if we are the same addr. */
+ 	      match = 0;
+ 	      for (p = hp->h_addr_list; *p != 0; p++) {
+ 		memcpy(&in.s_addr, *p, sizeof(in.s_addr));
+ 	      
+ 		if (htonl(in.s_addr) == INADDR_LOOPBACK) /* 127.0.0.1 */
+ 		  match = 1;
+ 		for (j = 0; myAddr[j].s_addr != 0; j++) {
+ 		  if (in.s_addr == myAddr[j].s_addr)
+ 		    match = 1;
+ 		}
+ 	      }
+ 
+ 	      if (!match)
+ 		secure = 0;	/* No matching addr.  Different host. */
+ 	    }
+ 	    else		/* if(gethostbyaddr()) */
+ 	      secure = 0;
+ 	    break;
+ #if defined(FamilyLocalHost)
+ 	  case FamilyLocalHost:
+ 	    break;		/* still secure */
+ #endif
+ 	  default:
+ 	    secure = 0;		/* Unexpected, so claim insecure. */
+ 	  } /* switch(addrPtr[i].family) */
+ 
+ 	}
+ 
+       }	/* (numHosts!=0) */
+     } /* (secure!=0) */
+ 
+     if (addrPtr != NULL) {
+       XFree((char *) addrPtr);
+     }
+     return secure;
+ 
+ #endif /* TK_FULL_SECURITY */
  #endif /* TK_NO_SECURITY */
  }
  
