Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2 
      3 Copyright 1988, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24 
     25 */
     26 
     27 #ifdef HAVE_CONFIG_H
     28 #include <config.h>
     29 #endif
     30 #include <X11/Xauth.h>
     31 #include <X11/Xos.h>
     32 #ifdef XTHREADS
     33 #include <X11/Xthreads.h>
     34 #endif
     35 
     36 #ifdef O_CLOEXEC
     37 #define FOPEN_CLOEXEC "e"
     38 #else
     39 #define FOPEN_CLOEXEC ""
     40 #endif
     41 
     42 #define binaryEqual(a, b, len) (memcmp(a, b, len) == 0)
     43 
     44 Xauth *
     45 XauGetBestAuthByAddr (
     46 #if NeedWidePrototypes
     47     unsigned int	family,
     48     unsigned int	address_length,
     49 #else
     50     unsigned short	family,
     51     unsigned short	address_length,
     52 #endif
     53     _Xconst char*	address,
     54 #if NeedWidePrototypes
     55     unsigned int	number_length,
     56 #else
     57     unsigned short	number_length,
     58 #endif
     59     _Xconst char*	number,
     60     int			types_length,
     61     char**		types,
     62     _Xconst int*	type_lengths)
     63 {
     64     FILE    *auth_file;
     65     char    *auth_name;
     66     Xauth   *entry;
     67     Xauth   *best;
     68     int	    best_type;
     69     int	    type;
     70 
     71     auth_name = XauFileName ();
     72     if (!auth_name)
     73 	return NULL;
     74     if (access (auth_name, R_OK) != 0)		/* checks REAL id */
     75 	return NULL;
     76     auth_file = fopen (auth_name, "rb" FOPEN_CLOEXEC);
     77     if (!auth_file)
     78 	return NULL;
     79 
     80     best = NULL;
     81     best_type = types_length;
     82     for (;;) {
     83 	entry = XauReadAuth (auth_file);
     84 	if (!entry)
     85 	    break;
     86 	/*
     87 	 * Match when:
     88 	 *   either family or entry->family are FamilyWild or
     89 	 *    family and entry->family are the same and
     90 	 *     address and entry->address are the same
     91 	 *  and
     92 	 *   either number or entry->number are empty or
     93 	 *    number and entry->number are the same
     94 	 *  and
     95 	 *   either name or entry->name are empty or
     96 	 *    name and entry->name are the same
     97 	 */
     98 
     99 	if ((family == FamilyWild || entry->family == FamilyWild ||
    100 	     (entry->family == family &&
    101 	     ((address_length == entry->address_length &&
    102 	      binaryEqual (entry->address, address, address_length))
    103 	    ))) &&
    104 	    (number_length == 0 || entry->number_length == 0 ||
    105 	     (number_length == entry->number_length &&
    106 	      binaryEqual (entry->number, number, number_length))))
    107 	{
    108 	    if (best_type == 0)
    109 	    {
    110 		best = entry;
    111 		break;
    112 	    }
    113 	    for (type = 0; type < best_type; type++)
    114 		if (type_lengths[type] == entry->name_length &&
    115 		    !(strncmp (types[type], entry->name, entry->name_length)))
    116 		{
    117 		    break;
    118 		}
    119 	    if (type < best_type)
    120 	    {
    121 		if (best)
    122 		    XauDisposeAuth (best);
    123 		best = entry;
    124 		best_type = type;
    125 		if (type == 0)
    126 		    break;
    127 		continue;
    128 	    }
    129 	}
    130 	XauDisposeAuth (entry);
    131     }
    132     (void) fclose (auth_file);
    133     return best;
    134 }
    135