AuGetBest.c revision 313a12fd
1/*
2
3Copyright 1988, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in 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#ifdef hpux
36#define X_INCLUDE_NETDB_H
37#define XOS_USE_NO_LOCKING
38#include <X11/Xos_r.h>
39#endif
40
41#define binaryEqual(a, b, len) (memcmp(a, b, len) == 0)
42
43Xauth *
44XauGetBestAuthByAddr (
45#if NeedWidePrototypes
46    unsigned int	family,
47    unsigned int	address_length,
48#else
49    unsigned short	family,
50    unsigned short	address_length,
51#endif
52    _Xconst char*	address,
53#if NeedWidePrototypes
54    unsigned int	number_length,
55#else
56    unsigned short	number_length,
57#endif
58    _Xconst char*	number,
59    int			types_length,
60    char**		types,
61    _Xconst int*	type_lengths)
62{
63    FILE    *auth_file;
64    char    *auth_name;
65    Xauth   *entry;
66    Xauth   *best;
67    int	    best_type;
68    int	    type;
69#ifdef hpux
70    char		*fully_qual_address;
71    unsigned short	fully_qual_address_length;
72#endif
73
74    auth_name = XauFileName ();
75    if (!auth_name)
76	return NULL;
77    if (access (auth_name, R_OK) != 0)		/* checks REAL id */
78	return NULL;
79    auth_file = fopen (auth_name, "rb");
80    if (!auth_file)
81	return NULL;
82
83#ifdef hpux
84    if (family == FamilyLocal) {
85#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
86	_Xgethostbynameparams hparams;
87#endif
88	struct hostent *hostp;
89
90	/* make sure we try fully-qualified hostname */
91	if ((hostp = _XGethostbyname(address,hparams)) != NULL) {
92	    fully_qual_address = hostp->h_name;
93	    fully_qual_address_length = strlen(fully_qual_address);
94	}
95	else
96	{
97	    fully_qual_address = NULL;
98	    fully_qual_address_length = 0;
99	}
100    }
101#endif /* hpux */
102
103    best = NULL;
104    best_type = types_length;
105    for (;;) {
106	entry = XauReadAuth (auth_file);
107	if (!entry)
108	    break;
109	/*
110	 * Match when:
111	 *   either family or entry->family are FamilyWild or
112	 *    family and entry->family are the same and
113	 *     address and entry->address are the same
114	 *  and
115	 *   either number or entry->number are empty or
116	 *    number and entry->number are the same
117	 *  and
118	 *   either name or entry->name are empty or
119	 *    name and entry->name are the same
120	 */
121
122	if ((family == FamilyWild || entry->family == FamilyWild ||
123	     (entry->family == family &&
124	     ((address_length == entry->address_length &&
125	      binaryEqual (entry->address, address, address_length))
126#ifdef hpux
127	     || (family == FamilyLocal &&
128		fully_qual_address_length == entry->address_length &&
129	     	binaryEqual (entry->address, fully_qual_address,
130		    fully_qual_address_length))
131#endif
132	    ))) &&
133	    (number_length == 0 || entry->number_length == 0 ||
134	     (number_length == entry->number_length &&
135	      binaryEqual (entry->number, number, number_length))))
136	{
137	    if (best_type == 0)
138	    {
139		best = entry;
140		break;
141	    }
142	    for (type = 0; type < best_type; type++)
143		if (type_lengths[type] == entry->name_length &&
144		    !(strncmp (types[type], entry->name, entry->name_length)))
145		{
146		    break;
147		}
148	    if (type < best_type)
149	    {
150		if (best)
151		    XauDisposeAuth (best);
152		best = entry;
153		best_type = type;
154		if (type == 0)
155		    break;
156		continue;
157	    }
158	}
159	XauDisposeAuth (entry);
160    }
161    (void) fclose (auth_file);
162    return best;
163}
164