iceauth.c revision fb5e8d76
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#include <X11/ICE/ICEutil.h>
35266e564dSmrg
36266e564dSmrg#include <time.h>
37266e564dSmrg#define Time_t time_t
38266e564dSmrg
39fb5e8d76Smrg#ifdef HAVE_LIBBSD
40fb5e8d76Smrg#include <bsd/stdlib.h>	/* for arc4random_buf() */
41fb5e8d76Smrg#endif
42fb5e8d76Smrg
43266e564dSmrgstatic int was_called_state;
44266e564dSmrg
45266e564dSmrg/*
46266e564dSmrg * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by
47266e564dSmrg * the SI.  It is not part of standard ICElib.
48266e564dSmrg */
49266e564dSmrg
50266e564dSmrg
51266e564dSmrgchar *
52c5629e66SmrgIceGenerateMagicCookie (
53c5629e66Smrg	int len
54c5629e66Smrg)
55266e564dSmrg{
56266e564dSmrg    char    *auth;
57fb5e8d76Smrg#ifndef HAVE_ARC4RANDOM_BUF
58266e564dSmrg    long    ldata[2];
59266e564dSmrg    int	    seed;
60266e564dSmrg    int	    value;
61266e564dSmrg    int	    i;
62fb5e8d76Smrg#endif
639ef0b394Smrg
64fb5e8d76Smrg    if ((auth = malloc (len + 1)) == NULL)
65266e564dSmrg	return (NULL);
66266e564dSmrg
67fb5e8d76Smrg#ifdef HAVE_ARC4RANDOM_BUF
68fb5e8d76Smrg    arc4random_buf(auth, len);
69fb5e8d76Smrg#else
70266e564dSmrg#ifdef ITIMER_REAL
71266e564dSmrg    {
72266e564dSmrg	struct timeval  now;
73266e564dSmrg	X_GETTIMEOFDAY (&now);
74266e564dSmrg	ldata[0] = now.tv_sec;
75266e564dSmrg	ldata[1] = now.tv_usec;
76266e564dSmrg    }
77266e564dSmrg#else
78266e564dSmrg    {
79266e564dSmrg	long    time ();
80266e564dSmrg	ldata[0] = time ((long *) 0);
81266e564dSmrg	ldata[1] = getpid ();
82266e564dSmrg    }
83266e564dSmrg#endif
84266e564dSmrg    seed = (ldata[0]) + (ldata[1] << 16);
85266e564dSmrg    srand (seed);
86266e564dSmrg    for (i = 0; i < len; i++)
87266e564dSmrg    {
88266e564dSmrg	value = rand ();
89266e564dSmrg	auth[i] = value & 0xff;
90266e564dSmrg    }
91fb5e8d76Smrg#endif
92266e564dSmrg    auth[len] = '\0';
93266e564dSmrg    return (auth);
94266e564dSmrg}
95266e564dSmrg
96266e564dSmrg
97266e564dSmrg
98266e564dSmrgIcePoAuthStatus
99c5629e66Smrg_IcePoMagicCookie1Proc (
100c5629e66Smrg	IceConn		iceConn,
101c5629e66Smrg	IcePointer	*authStatePtr,
102c5629e66Smrg	Bool 		cleanUp,
103c5629e66Smrg	Bool		swap,
104c5629e66Smrg	int     	authDataLen,
105c5629e66Smrg	IcePointer	authData,
106c5629e66Smrg	int 		*replyDataLenRet,
107c5629e66Smrg	IcePointer	*replyDataRet,
108c5629e66Smrg	char    	**errorStringRet
109c5629e66Smrg)
110266e564dSmrg{
111266e564dSmrg    if (cleanUp)
112266e564dSmrg    {
113266e564dSmrg	/*
114266e564dSmrg	 * We didn't allocate any state.  We're done.
115266e564dSmrg	 */
116266e564dSmrg
117266e564dSmrg	return (IcePoAuthDoneCleanup);
118266e564dSmrg    }
119266e564dSmrg
120266e564dSmrg    *errorStringRet = NULL;
121266e564dSmrg
122266e564dSmrg    if (*authStatePtr == NULL)
123266e564dSmrg    {
124266e564dSmrg	/*
125266e564dSmrg	 * This is the first time we're being called.  Search the
126266e564dSmrg	 * authentication data for the first occurence of
127266e564dSmrg	 * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string.
128266e564dSmrg	 */
129266e564dSmrg
130266e564dSmrg	unsigned short  length;
131266e564dSmrg	char		*data;
132266e564dSmrg
133266e564dSmrg	_IceGetPoAuthData ("ICE", iceConn->connection_string,
134266e564dSmrg	    "MIT-MAGIC-COOKIE-1", &length, &data);
135266e564dSmrg
136266e564dSmrg	if (!data)
137266e564dSmrg	{
138266e564dSmrg	    const char *tempstr =
139266e564dSmrg		"Could not find correct MIT-MAGIC-COOKIE-1 authentication";
140266e564dSmrg
141266e564dSmrg	    *errorStringRet = strdup(tempstr);
142266e564dSmrg
143266e564dSmrg	    return (IcePoAuthFailed);
144266e564dSmrg	}
145266e564dSmrg	else
146266e564dSmrg	{
147266e564dSmrg	    *authStatePtr = (IcePointer) &was_called_state;
148266e564dSmrg
149266e564dSmrg	    *replyDataLenRet = length;
150266e564dSmrg	    *replyDataRet = data;
151266e564dSmrg
152266e564dSmrg	    return (IcePoAuthHaveReply);
153266e564dSmrg	}
154266e564dSmrg    }
155266e564dSmrg    else
156266e564dSmrg    {
157266e564dSmrg	/*
158266e564dSmrg	 * We should never get here for MIT-MAGIC-COOKIE-1 since it is
159266e564dSmrg	 * a single pass authentication method.
160266e564dSmrg	 */
161266e564dSmrg
162266e564dSmrg	const char *tempstr =
163266e564dSmrg	    "MIT-MAGIC-COOKIE-1 authentication internal error";
164266e564dSmrg
165266e564dSmrg	*errorStringRet = strdup(tempstr);
166266e564dSmrg
167266e564dSmrg	return (IcePoAuthFailed);
168266e564dSmrg    }
169266e564dSmrg}
170266e564dSmrg
171c5629e66SmrgIcePoAuthProc	_IcePoAuthProcs[] = {_IcePoMagicCookie1Proc};
172266e564dSmrg
173266e564dSmrg
174266e564dSmrgIcePaAuthStatus
175c5629e66Smrg_IcePaMagicCookie1Proc (
176c5629e66Smrg	IceConn		iceConn,
177c5629e66Smrg	IcePointer	*authStatePtr,
178c5629e66Smrg	Bool		swap,
179c5629e66Smrg	int     	authDataLen,
180c5629e66Smrg	IcePointer	authData,
181c5629e66Smrg	int 		*replyDataLenRet,
182c5629e66Smrg	IcePointer	*replyDataRet,
183c5629e66Smrg	char    	**errorStringRet
184c5629e66Smrg)
185266e564dSmrg{
186266e564dSmrg    *errorStringRet = NULL;
187266e564dSmrg    *replyDataLenRet = 0;
188266e564dSmrg    *replyDataRet = NULL;
189266e564dSmrg
190266e564dSmrg    if (*authStatePtr == NULL)
191266e564dSmrg    {
192266e564dSmrg	/*
193266e564dSmrg	 * This is the first time we're being called.  We don't have
194266e564dSmrg	 * any data to pass to the other client.
195266e564dSmrg	 */
196266e564dSmrg
197266e564dSmrg	*authStatePtr = (IcePointer) &was_called_state;
198266e564dSmrg
199266e564dSmrg	return (IcePaAuthContinue);
200266e564dSmrg    }
201266e564dSmrg    else
202266e564dSmrg    {
203266e564dSmrg	/*
204266e564dSmrg	 * Search the authentication data for the first occurence of
205266e564dSmrg	 * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string.
206266e564dSmrg	 */
207266e564dSmrg
208266e564dSmrg	unsigned short  length;
209266e564dSmrg	char		*data;
210266e564dSmrg
211266e564dSmrg	_IceGetPaAuthData ("ICE", iceConn->connection_string,
212266e564dSmrg	    "MIT-MAGIC-COOKIE-1", &length, &data);
213266e564dSmrg
214266e564dSmrg	if (data)
215266e564dSmrg	{
216266e564dSmrg	    IcePaAuthStatus stat;
217266e564dSmrg
218266e564dSmrg	    if (authDataLen == length &&
219c5629e66Smrg	        memcmp (authData, data, authDataLen) == 0)
220266e564dSmrg	    {
221266e564dSmrg		stat = IcePaAuthAccepted;
222266e564dSmrg	    }
223266e564dSmrg	    else
224266e564dSmrg	    {
225266e564dSmrg		const char *tempstr
226266e564dSmrg		    = "MIT-MAGIC-COOKIE-1 authentication rejected";
227266e564dSmrg
228266e564dSmrg		*errorStringRet = strdup(tempstr);
229266e564dSmrg
230266e564dSmrg		stat = IcePaAuthRejected;
231266e564dSmrg	    }
232266e564dSmrg
233266e564dSmrg	    free (data);
234266e564dSmrg	    return (stat);
235266e564dSmrg	}
236266e564dSmrg	else
237266e564dSmrg	{
238266e564dSmrg	    /*
239266e564dSmrg	     * We should never get here because in the ConnectionReply
240266e564dSmrg	     * we should have passed all the valid methods.  So we should
241266e564dSmrg	     * always find a valid entry.
242266e564dSmrg	     */
243266e564dSmrg
244266e564dSmrg	    const char *tempstr =
245266e564dSmrg		"MIT-MAGIC-COOKIE-1 authentication internal error";
246266e564dSmrg
247266e564dSmrg	    *errorStringRet = strdup(tempstr);
248266e564dSmrg
249266e564dSmrg	    return (IcePaAuthFailed);
250266e564dSmrg	}
251266e564dSmrg    }
252266e564dSmrg}
253266e564dSmrg
254c5629e66SmrgIcePaAuthProc	_IcePaAuthProcs[] = {_IcePaMagicCookie1Proc};
255