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 381009a292Smrg#ifdef HAVE_ARC4RANDOM_BUF 391009a292Smrg#include <stdlib.h> /* for arc4random_buf() */ 40fb5e8d76Smrg#endif 41fb5e8d76Smrg 42a3129944Smrg#include <unistd.h> 43a3129944Smrg 44266e564dSmrgstatic int was_called_state; 45266e564dSmrg 46a3129944Smrg#ifndef HAVE_ARC4RANDOM_BUF 47266e564dSmrg 48a3129944Smrgstatic void 49a3129944Smrgemulate_getrandom_buf ( 50a3129944Smrg char *auth, 51c5629e66Smrg int len 52c5629e66Smrg) 53266e564dSmrg{ 54266e564dSmrg long ldata[2]; 55266e564dSmrg int seed; 56266e564dSmrg int value; 57266e564dSmrg int i; 589ef0b394Smrg 59266e564dSmrg#ifdef ITIMER_REAL 60266e564dSmrg { 61266e564dSmrg struct timeval now; 62266e564dSmrg X_GETTIMEOFDAY (&now); 63266e564dSmrg ldata[0] = now.tv_sec; 64266e564dSmrg ldata[1] = now.tv_usec; 65266e564dSmrg } 66a3129944Smrg#else /* ITIMER_REAL */ 67266e564dSmrg { 68266e564dSmrg long time (); 69266e564dSmrg ldata[0] = time ((long *) 0); 70266e564dSmrg ldata[1] = getpid (); 71266e564dSmrg } 72a3129944Smrg#endif /* ITIMER_REAL */ 73266e564dSmrg seed = (ldata[0]) + (ldata[1] << 16); 74266e564dSmrg srand (seed); 75266e564dSmrg for (i = 0; i < len; i++) 76266e564dSmrg { 77266e564dSmrg value = rand (); 78266e564dSmrg auth[i] = value & 0xff; 79266e564dSmrg } 80a3129944Smrg} 81a3129944Smrg 82a3129944Smrgstatic void 83a3129944Smrgarc4random_buf ( 84a3129944Smrg char *auth, 85a3129944Smrg int len 86a3129944Smrg) 87a3129944Smrg{ 88a3129944Smrg#if HAVE_GETENTROPY 89a3129944Smrg int ret; 90a3129944Smrg 91a3129944Smrg /* weak emulation of arc4random through the entropy libc */ 92a3129944Smrg ret = getentropy (auth, len); 93a3129944Smrg if (ret == 0) 94a3129944Smrg return; 95a3129944Smrg#endif /* HAVE_GETENTROPY */ 96a3129944Smrg 97a3129944Smrg emulate_getrandom_buf (auth, len); 98a3129944Smrg} 99a3129944Smrg 100a3129944Smrg#endif /* !defined(HAVE_ARC4RANDOM_BUF) */ 101a3129944Smrg 102a3129944Smrg/* 103a3129944Smrg * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by 104a3129944Smrg * the SI. It is not part of standard ICElib. 105a3129944Smrg */ 106a3129944Smrg 107a3129944Smrg 108a3129944Smrgchar * 109a3129944SmrgIceGenerateMagicCookie ( 110a3129944Smrg int len 111a3129944Smrg) 112a3129944Smrg{ 113a3129944Smrg char *auth; 114a3129944Smrg 115a3129944Smrg if ((auth = malloc (len + 1)) == NULL) 116a3129944Smrg return (NULL); 117a3129944Smrg 118a3129944Smrg arc4random_buf (auth, len); 119a3129944Smrg 120266e564dSmrg auth[len] = '\0'; 121266e564dSmrg return (auth); 122266e564dSmrg} 123266e564dSmrg 124266e564dSmrg 125a3129944Smrg 126266e564dSmrgIcePoAuthStatus 127c5629e66Smrg_IcePoMagicCookie1Proc ( 128c5629e66Smrg IceConn iceConn, 129c5629e66Smrg IcePointer *authStatePtr, 130c5629e66Smrg Bool cleanUp, 131c5629e66Smrg Bool swap, 132c5629e66Smrg int authDataLen, 133c5629e66Smrg IcePointer authData, 134c5629e66Smrg int *replyDataLenRet, 135c5629e66Smrg IcePointer *replyDataRet, 136c5629e66Smrg char **errorStringRet 137c5629e66Smrg) 138266e564dSmrg{ 139266e564dSmrg if (cleanUp) 140266e564dSmrg { 141266e564dSmrg /* 142266e564dSmrg * We didn't allocate any state. We're done. 143266e564dSmrg */ 144266e564dSmrg 145266e564dSmrg return (IcePoAuthDoneCleanup); 146266e564dSmrg } 147266e564dSmrg 148266e564dSmrg *errorStringRet = NULL; 149266e564dSmrg 150266e564dSmrg if (*authStatePtr == NULL) 151266e564dSmrg { 152266e564dSmrg /* 153266e564dSmrg * This is the first time we're being called. Search the 1541009a292Smrg * authentication data for the first occurrence of 155266e564dSmrg * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string. 156266e564dSmrg */ 157266e564dSmrg 158266e564dSmrg unsigned short length; 159266e564dSmrg char *data; 160266e564dSmrg 161266e564dSmrg _IceGetPoAuthData ("ICE", iceConn->connection_string, 162266e564dSmrg "MIT-MAGIC-COOKIE-1", &length, &data); 163266e564dSmrg 164266e564dSmrg if (!data) 165266e564dSmrg { 166266e564dSmrg const char *tempstr = 167266e564dSmrg "Could not find correct MIT-MAGIC-COOKIE-1 authentication"; 168266e564dSmrg 169266e564dSmrg *errorStringRet = strdup(tempstr); 170266e564dSmrg 171266e564dSmrg return (IcePoAuthFailed); 172266e564dSmrg } 173266e564dSmrg else 174266e564dSmrg { 175266e564dSmrg *authStatePtr = (IcePointer) &was_called_state; 176266e564dSmrg 177266e564dSmrg *replyDataLenRet = length; 178266e564dSmrg *replyDataRet = data; 179266e564dSmrg 180266e564dSmrg return (IcePoAuthHaveReply); 181266e564dSmrg } 182266e564dSmrg } 183266e564dSmrg else 184266e564dSmrg { 185266e564dSmrg /* 186266e564dSmrg * We should never get here for MIT-MAGIC-COOKIE-1 since it is 187266e564dSmrg * a single pass authentication method. 188266e564dSmrg */ 189266e564dSmrg 190266e564dSmrg const char *tempstr = 191266e564dSmrg "MIT-MAGIC-COOKIE-1 authentication internal error"; 192266e564dSmrg 193266e564dSmrg *errorStringRet = strdup(tempstr); 194266e564dSmrg 195266e564dSmrg return (IcePoAuthFailed); 196266e564dSmrg } 197266e564dSmrg} 198266e564dSmrg 199c5629e66SmrgIcePoAuthProc _IcePoAuthProcs[] = {_IcePoMagicCookie1Proc}; 200266e564dSmrg 201266e564dSmrg 202266e564dSmrgIcePaAuthStatus 203c5629e66Smrg_IcePaMagicCookie1Proc ( 204c5629e66Smrg IceConn iceConn, 205c5629e66Smrg IcePointer *authStatePtr, 206c5629e66Smrg Bool swap, 207c5629e66Smrg int authDataLen, 208c5629e66Smrg IcePointer authData, 209c5629e66Smrg int *replyDataLenRet, 210c5629e66Smrg IcePointer *replyDataRet, 211c5629e66Smrg char **errorStringRet 212c5629e66Smrg) 213266e564dSmrg{ 214266e564dSmrg *errorStringRet = NULL; 215266e564dSmrg *replyDataLenRet = 0; 216266e564dSmrg *replyDataRet = NULL; 217266e564dSmrg 218266e564dSmrg if (*authStatePtr == NULL) 219266e564dSmrg { 220266e564dSmrg /* 221266e564dSmrg * This is the first time we're being called. We don't have 222266e564dSmrg * any data to pass to the other client. 223266e564dSmrg */ 224266e564dSmrg 225266e564dSmrg *authStatePtr = (IcePointer) &was_called_state; 226266e564dSmrg 227266e564dSmrg return (IcePaAuthContinue); 228266e564dSmrg } 229266e564dSmrg else 230266e564dSmrg { 231266e564dSmrg /* 2321009a292Smrg * Search the authentication data for the first occurrence of 233266e564dSmrg * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string. 234266e564dSmrg */ 235266e564dSmrg 236266e564dSmrg unsigned short length; 237266e564dSmrg char *data; 238266e564dSmrg 239266e564dSmrg _IceGetPaAuthData ("ICE", iceConn->connection_string, 240266e564dSmrg "MIT-MAGIC-COOKIE-1", &length, &data); 241266e564dSmrg 242266e564dSmrg if (data) 243266e564dSmrg { 244266e564dSmrg IcePaAuthStatus stat; 245266e564dSmrg 246266e564dSmrg if (authDataLen == length && 247c5629e66Smrg memcmp (authData, data, authDataLen) == 0) 248266e564dSmrg { 249266e564dSmrg stat = IcePaAuthAccepted; 250266e564dSmrg } 251266e564dSmrg else 252266e564dSmrg { 253266e564dSmrg const char *tempstr 254266e564dSmrg = "MIT-MAGIC-COOKIE-1 authentication rejected"; 255266e564dSmrg 256266e564dSmrg *errorStringRet = strdup(tempstr); 257266e564dSmrg 258266e564dSmrg stat = IcePaAuthRejected; 259266e564dSmrg } 260266e564dSmrg 261266e564dSmrg free (data); 262266e564dSmrg return (stat); 263266e564dSmrg } 264266e564dSmrg else 265266e564dSmrg { 266266e564dSmrg /* 267266e564dSmrg * We should never get here because in the ConnectionReply 268266e564dSmrg * we should have passed all the valid methods. So we should 269266e564dSmrg * always find a valid entry. 270266e564dSmrg */ 271266e564dSmrg 272266e564dSmrg const char *tempstr = 273266e564dSmrg "MIT-MAGIC-COOKIE-1 authentication internal error"; 274266e564dSmrg 275266e564dSmrg *errorStringRet = strdup(tempstr); 276266e564dSmrg 277266e564dSmrg return (IcePaAuthFailed); 278266e564dSmrg } 279266e564dSmrg } 280266e564dSmrg} 281266e564dSmrg 282c5629e66SmrgIcePaAuthProc _IcePaAuthProcs[] = {_IcePaMagicCookie1Proc}; 283