iceauth.c revision fb5e8d76
1/******************************************************************************
2
3
4Copyright 1993, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26Author: Ralph Mor, X Consortium
27******************************************************************************/
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32#include <X11/ICE/ICElib.h>
33#include "ICElibint.h"
34#include <X11/ICE/ICEutil.h>
35
36#include <time.h>
37#define Time_t time_t
38
39#ifdef HAVE_LIBBSD
40#include <bsd/stdlib.h>	/* for arc4random_buf() */
41#endif
42
43static int was_called_state;
44
45/*
46 * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by
47 * the SI.  It is not part of standard ICElib.
48 */
49
50
51char *
52IceGenerateMagicCookie (
53	int len
54)
55{
56    char    *auth;
57#ifndef HAVE_ARC4RANDOM_BUF
58    long    ldata[2];
59    int	    seed;
60    int	    value;
61    int	    i;
62#endif
63
64    if ((auth = malloc (len + 1)) == NULL)
65	return (NULL);
66
67#ifdef HAVE_ARC4RANDOM_BUF
68    arc4random_buf(auth, len);
69#else
70#ifdef ITIMER_REAL
71    {
72	struct timeval  now;
73	X_GETTIMEOFDAY (&now);
74	ldata[0] = now.tv_sec;
75	ldata[1] = now.tv_usec;
76    }
77#else
78    {
79	long    time ();
80	ldata[0] = time ((long *) 0);
81	ldata[1] = getpid ();
82    }
83#endif
84    seed = (ldata[0]) + (ldata[1] << 16);
85    srand (seed);
86    for (i = 0; i < len; i++)
87    {
88	value = rand ();
89	auth[i] = value & 0xff;
90    }
91#endif
92    auth[len] = '\0';
93    return (auth);
94}
95
96
97
98IcePoAuthStatus
99_IcePoMagicCookie1Proc (
100	IceConn		iceConn,
101	IcePointer	*authStatePtr,
102	Bool 		cleanUp,
103	Bool		swap,
104	int     	authDataLen,
105	IcePointer	authData,
106	int 		*replyDataLenRet,
107	IcePointer	*replyDataRet,
108	char    	**errorStringRet
109)
110{
111    if (cleanUp)
112    {
113	/*
114	 * We didn't allocate any state.  We're done.
115	 */
116
117	return (IcePoAuthDoneCleanup);
118    }
119
120    *errorStringRet = NULL;
121
122    if (*authStatePtr == NULL)
123    {
124	/*
125	 * This is the first time we're being called.  Search the
126	 * authentication data for the first occurence of
127	 * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string.
128	 */
129
130	unsigned short  length;
131	char		*data;
132
133	_IceGetPoAuthData ("ICE", iceConn->connection_string,
134	    "MIT-MAGIC-COOKIE-1", &length, &data);
135
136	if (!data)
137	{
138	    const char *tempstr =
139		"Could not find correct MIT-MAGIC-COOKIE-1 authentication";
140
141	    *errorStringRet = strdup(tempstr);
142
143	    return (IcePoAuthFailed);
144	}
145	else
146	{
147	    *authStatePtr = (IcePointer) &was_called_state;
148
149	    *replyDataLenRet = length;
150	    *replyDataRet = data;
151
152	    return (IcePoAuthHaveReply);
153	}
154    }
155    else
156    {
157	/*
158	 * We should never get here for MIT-MAGIC-COOKIE-1 since it is
159	 * a single pass authentication method.
160	 */
161
162	const char *tempstr =
163	    "MIT-MAGIC-COOKIE-1 authentication internal error";
164
165	*errorStringRet = strdup(tempstr);
166
167	return (IcePoAuthFailed);
168    }
169}
170
171IcePoAuthProc	_IcePoAuthProcs[] = {_IcePoMagicCookie1Proc};
172
173
174IcePaAuthStatus
175_IcePaMagicCookie1Proc (
176	IceConn		iceConn,
177	IcePointer	*authStatePtr,
178	Bool		swap,
179	int     	authDataLen,
180	IcePointer	authData,
181	int 		*replyDataLenRet,
182	IcePointer	*replyDataRet,
183	char    	**errorStringRet
184)
185{
186    *errorStringRet = NULL;
187    *replyDataLenRet = 0;
188    *replyDataRet = NULL;
189
190    if (*authStatePtr == NULL)
191    {
192	/*
193	 * This is the first time we're being called.  We don't have
194	 * any data to pass to the other client.
195	 */
196
197	*authStatePtr = (IcePointer) &was_called_state;
198
199	return (IcePaAuthContinue);
200    }
201    else
202    {
203	/*
204	 * Search the authentication data for the first occurence of
205	 * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string.
206	 */
207
208	unsigned short  length;
209	char		*data;
210
211	_IceGetPaAuthData ("ICE", iceConn->connection_string,
212	    "MIT-MAGIC-COOKIE-1", &length, &data);
213
214	if (data)
215	{
216	    IcePaAuthStatus stat;
217
218	    if (authDataLen == length &&
219	        memcmp (authData, data, authDataLen) == 0)
220	    {
221		stat = IcePaAuthAccepted;
222	    }
223	    else
224	    {
225		const char *tempstr
226		    = "MIT-MAGIC-COOKIE-1 authentication rejected";
227
228		*errorStringRet = strdup(tempstr);
229
230		stat = IcePaAuthRejected;
231	    }
232
233	    free (data);
234	    return (stat);
235	}
236	else
237	{
238	    /*
239	     * We should never get here because in the ConnectionReply
240	     * we should have passed all the valid methods.  So we should
241	     * always find a valid entry.
242	     */
243
244	    const char *tempstr =
245		"MIT-MAGIC-COOKIE-1 authentication internal error";
246
247	    *errorStringRet = strdup(tempstr);
248
249	    return (IcePaAuthFailed);
250	}
251    }
252}
253
254IcePaAuthProc	_IcePaAuthProcs[] = {_IcePaMagicCookie1Proc};
255