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