1266e564dSmrg/******************************************************************************
2266e564dSmrg
3266e564dSmrg
4266e564dSmrgCopyright 1993, 1998  The Open Group
5266e564dSmrg
6266e564dSmrgPermission to use, copy, modify, distribute, and sell this software and its
7266e564dSmrgdocumentation for any purpose is hereby granted without fee, provided that
8266e564dSmrgthe above copyright notice appear in all copies and that both that
9266e564dSmrgcopyright notice and this permission notice appear in supporting
10266e564dSmrgdocumentation.
11266e564dSmrg
12266e564dSmrgThe above copyright notice and this permission notice shall be included in
13266e564dSmrgall copies or substantial portions of the Software.
14266e564dSmrg
15266e564dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16266e564dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17266e564dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18266e564dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19266e564dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20266e564dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21266e564dSmrg
22266e564dSmrgExcept as contained in this notice, the name of The Open Group shall not be
23266e564dSmrgused in advertising or otherwise to promote the sale, use or other dealings
24266e564dSmrgin this Software without prior written authorization from The Open Group.
25266e564dSmrg
26266e564dSmrgAuthor: Ralph Mor, X Consortium
27266e564dSmrg******************************************************************************/
28266e564dSmrg
29266e564dSmrg#ifdef HAVE_CONFIG_H
30266e564dSmrg#include <config.h>
31266e564dSmrg#endif
32266e564dSmrg#include <X11/ICE/ICElib.h>
33266e564dSmrg#include "ICElibint.h"
34266e564dSmrg
35266e564dSmrgstatic Bool auth_valid (const char *auth_name, int num_auth_names,
369ef0b394Smrg			const char **auth_names, int *index_ret);
37266e564dSmrg
38a3129944Smrg
39266e564dSmrg/*
40266e564dSmrg * The functions in this file are not a standard part of ICElib.
41266e564dSmrg *
42266e564dSmrg * The sample implementation uses an .ICEauthority to manipulate
43266e564dSmrg * authentication data.
44266e564dSmrg *
45266e564dSmrg * For the client that initiates a Protocol Setup, we look in the
46266e564dSmrg * .ICEauthority file to get the data.
47266e564dSmrg *
48266e564dSmrg * For the client accepting the Protocol Setup, we get the data
49266e564dSmrg * from an in-memory database of authentication data (set by the
50266e564dSmrg * application calling IceSetPaAuthData).  We have to get the data
51266e564dSmrg * from memory because getting it directly from the .ICEauthority
52266e564dSmrg * file is not secure - someone can just modify the contents of the
53266e564dSmrg * .ICEauthority file behind our back.
54266e564dSmrg */
55266e564dSmrg
56266e564dSmrgvoid
57c5629e66Smrg_IceGetPoAuthData (
589ef0b394Smrg	const char	*protocolName,
599ef0b394Smrg	const char	*networkId,
609ef0b394Smrg	const char	*authName,
61c5629e66Smrg	unsigned short	*authDataLenRet,
62c5629e66Smrg	char		**authDataRet
63c5629e66Smrg)
64266e564dSmrg{
65266e564dSmrg    IceAuthFileEntry    *entry;
66266e564dSmrg
67266e564dSmrg    entry = IceGetAuthFileEntry (protocolName, networkId, authName);
68266e564dSmrg
69266e564dSmrg    if (entry)
70266e564dSmrg    {
71266e564dSmrg	*authDataLenRet = entry->auth_data_length;
72266e564dSmrg
73fb5e8d76Smrg	if ((*authDataRet = malloc (entry->auth_data_length)) != NULL)
74266e564dSmrg	    memcpy (*authDataRet, entry->auth_data, entry->auth_data_length);
75266e564dSmrg    }
76266e564dSmrg    else
77266e564dSmrg    {
78266e564dSmrg	*authDataLenRet = 0;
79266e564dSmrg	*authDataRet = NULL;
80266e564dSmrg    }
81266e564dSmrg
82266e564dSmrg    IceFreeAuthFileEntry (entry);
83266e564dSmrg}
84266e564dSmrg
85266e564dSmrg
86a3129944Smrg
87266e564dSmrgvoid
88c5629e66Smrg_IceGetPaAuthData (
899ef0b394Smrg	const char	*protocolName,
909ef0b394Smrg	const char	*networkId,
919ef0b394Smrg	const char	*authName,
92c5629e66Smrg	unsigned short	*authDataLenRet,
93c5629e66Smrg	char		**authDataRet
94c5629e66Smrg)
95266e564dSmrg{
96266e564dSmrg    IceAuthDataEntry	*entry = NULL;
97266e564dSmrg    int			found = 0;
98266e564dSmrg    int			i;
99266e564dSmrg
100266e564dSmrg    for (i = 0; i < _IcePaAuthDataEntryCount && !found; i++)
101266e564dSmrg    {
102266e564dSmrg	entry = &_IcePaAuthDataEntries[i];
103266e564dSmrg
104266e564dSmrg	found =
105266e564dSmrg	    strcmp (protocolName, entry->protocol_name) == 0 &&
106266e564dSmrg            strcmp (networkId, entry->network_id) == 0 &&
107266e564dSmrg            strcmp (authName, entry->auth_name) == 0;
108266e564dSmrg    }
109266e564dSmrg
110266e564dSmrg    if (found)
111266e564dSmrg    {
112266e564dSmrg	*authDataLenRet = entry->auth_data_length;
113266e564dSmrg
114fb5e8d76Smrg	if ((*authDataRet = malloc (entry->auth_data_length)) != NULL)
115266e564dSmrg	    memcpy (*authDataRet, entry->auth_data, entry->auth_data_length);
116266e564dSmrg    }
117266e564dSmrg    else
118266e564dSmrg    {
119266e564dSmrg	*authDataLenRet = 0;
120266e564dSmrg	*authDataRet = NULL;
121266e564dSmrg    }
122266e564dSmrg}
123266e564dSmrg
124266e564dSmrg
125a3129944Smrg
126266e564dSmrgvoid
127c5629e66Smrg_IceGetPoValidAuthIndices (
1289ef0b394Smrg	const char	*protocol_name,
1299ef0b394Smrg	const char	*network_id,
1309ef0b394Smrg	int		num_auth_names,
1319ef0b394Smrg	const char	**auth_names,
1329ef0b394Smrg	int		*num_indices_ret,
1339ef0b394Smrg	int		*indices_ret		/* in/out arg */
134c5629e66Smrg)
135266e564dSmrg{
136266e564dSmrg    FILE    		*auth_file;
137266e564dSmrg    char    		*filename;
138266e564dSmrg    IceAuthFileEntry    *entry;
139266e564dSmrg    int			index_ret, i;
140266e564dSmrg
141266e564dSmrg    *num_indices_ret = 0;
142266e564dSmrg
143266e564dSmrg    if (!(filename = IceAuthFileName ()))
144266e564dSmrg	return;
145266e564dSmrg
146266e564dSmrg    if (access (filename, R_OK) != 0)		/* checks REAL id */
147266e564dSmrg	return;
148266e564dSmrg
1493bf3b463Smrg    if (!(auth_file = fopen (filename, "rb" FOPEN_CLOEXEC)))
150266e564dSmrg	return;
151266e564dSmrg
152266e564dSmrg    for (;;)
153266e564dSmrg    {
154266e564dSmrg	if (!(entry = IceReadAuthFileEntry (auth_file)))
155266e564dSmrg	    break;
156266e564dSmrg
157266e564dSmrg	if (strcmp (protocol_name, entry->protocol_name) == 0 &&
158266e564dSmrg	    strcmp (network_id, entry->network_id) == 0 &&
159266e564dSmrg	    auth_valid (entry->auth_name, num_auth_names,
160266e564dSmrg	    auth_names, &index_ret))
161266e564dSmrg	{
162266e564dSmrg	    /*
163266e564dSmrg	     * Make sure we didn't store this index already.
164266e564dSmrg	     */
165266e564dSmrg
166266e564dSmrg	    for (i = 0; i < *num_indices_ret; i++)
167266e564dSmrg		if (index_ret == indices_ret[i])
168266e564dSmrg		    break;
169266e564dSmrg
170266e564dSmrg	    if (i >= *num_indices_ret)
171266e564dSmrg	    {
172266e564dSmrg		indices_ret[*num_indices_ret] = index_ret;
173266e564dSmrg		*num_indices_ret += 1;
174266e564dSmrg	    }
175266e564dSmrg	}
176266e564dSmrg
177266e564dSmrg	IceFreeAuthFileEntry (entry);
178266e564dSmrg    }
179266e564dSmrg
180266e564dSmrg    fclose (auth_file);
181266e564dSmrg}
182266e564dSmrg
183266e564dSmrg
184a3129944Smrg
185266e564dSmrgvoid
186c5629e66Smrg_IceGetPaValidAuthIndices (
1879ef0b394Smrg	const char	*protocol_name,
1889ef0b394Smrg	const char	*network_id,
1899ef0b394Smrg	int		num_auth_names,
1909ef0b394Smrg	const char	**auth_names,
1919ef0b394Smrg	int		*num_indices_ret,
1929ef0b394Smrg	int		*indices_ret		/* in/out arg */
193c5629e66Smrg)
194266e564dSmrg{
195266e564dSmrg    int			index_ret;
196266e564dSmrg    int			i, j;
197266e564dSmrg    IceAuthDataEntry	*entry;
198266e564dSmrg
199266e564dSmrg    *num_indices_ret = 0;
200266e564dSmrg
201266e564dSmrg    for (i = 0;	i < _IcePaAuthDataEntryCount; i++)
202266e564dSmrg    {
203266e564dSmrg	entry = &_IcePaAuthDataEntries[i];
204266e564dSmrg
205266e564dSmrg	if (strcmp (protocol_name, entry->protocol_name) == 0 &&
206266e564dSmrg            strcmp (network_id, entry->network_id) == 0 &&
207266e564dSmrg	    auth_valid (entry->auth_name, num_auth_names,
208266e564dSmrg	    auth_names, &index_ret))
209266e564dSmrg	{
210266e564dSmrg	    /*
211266e564dSmrg	     * Make sure we didn't store this index already.
212266e564dSmrg	     */
213266e564dSmrg
214266e564dSmrg	    for (j = 0; j < *num_indices_ret; j++)
215266e564dSmrg		if (index_ret == indices_ret[j])
216266e564dSmrg		    break;
217266e564dSmrg
218266e564dSmrg	    if (j >= *num_indices_ret)
219266e564dSmrg	    {
220266e564dSmrg		indices_ret[*num_indices_ret] = index_ret;
221266e564dSmrg		*num_indices_ret += 1;
222266e564dSmrg	    }
223266e564dSmrg	}
224266e564dSmrg    }
225266e564dSmrg}
226266e564dSmrg
227266e564dSmrg
228a3129944Smrg
229266e564dSmrg/*
230266e564dSmrg * local routines
231266e564dSmrg */
232266e564dSmrg
233266e564dSmrgstatic Bool
234266e564dSmrgauth_valid (const char *auth_name, int num_auth_names,
2359ef0b394Smrg	    const char **auth_names, int *index_ret)
236266e564dSmrg
237266e564dSmrg{
238266e564dSmrg    /*
239266e564dSmrg     * Check if auth_name is in auth_names.  Return index.
240266e564dSmrg     */
241266e564dSmrg
242266e564dSmrg    int i;
243266e564dSmrg
244266e564dSmrg    for (i = 0; i < num_auth_names; i++)
245266e564dSmrg	if (strcmp (auth_name, auth_names[i]) == 0)
246266e564dSmrg	{
247266e564dSmrg	    break;
248266e564dSmrg	}
2499ef0b394Smrg
250266e564dSmrg    if (i < num_auth_names)
251266e564dSmrg    {
252266e564dSmrg	*index_ret = i;
253266e564dSmrg	return (1);
254266e564dSmrg    }
255266e564dSmrg    else
256266e564dSmrg	return (0);
257266e564dSmrg}
258