1 /* $Xorg: auth.c,v 1.4 2001/02/09 02:05:59 xorgcvs Exp $ */ 2 /****************************************************************************** 3 4 Copyright 1993, 1998 The Open Group 5 6 Permission to use, copy, modify, distribute, and sell this software and its 7 documentation for any purpose is hereby granted without fee, provided that 8 the above copyright notice appear in all copies and that both that 9 copyright notice and this permission notice appear in supporting 10 documentation. 11 12 The above copyright notice and this permission notice shall be included in 13 all copies or substantial portions of the Software. 14 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 Except as contained in this notice, the name of The Open Group shall not be 23 used in advertising or otherwise to promote the sale, use or other dealings 24 in this Software without prior written authorization from The Open Group. 25 ******************************************************************************/ 26 /* $XFree86: xc/programs/xsm/auth.c,v 1.6 2001/01/17 23:46:28 dawes Exp $ */ 27 28 #include "xsm.h" 29 30 #include <X11/ICE/ICEutil.h> 31 #include "auth.h" 32 33 #ifdef HAVE_MKSTEMP 34 #include <unistd.h> 35 #endif 36 #include <sys/types.h> 37 #include <sys/stat.h> 38 39 static char *addAuthFile = NULL; 40 static char *remAuthFile = NULL; 41 42 43 44 /* 46 * Host Based Authentication Callback. This callback is invoked if 47 * the connecting client can't offer any authentication methods that 48 * we can accept. We can accept/reject based on the hostname. 49 */ 50 51 Bool 52 HostBasedAuthProc(char *hostname) 53 { 54 return (0); /* For now, we don't support host based authentication */ 55 } 56 57 58 59 /* 61 * We use temporary files which contain commands to add/remove entries from 62 * the .ICEauthority file. 63 */ 64 65 static void 66 write_iceauth(FILE *addfp, FILE *removefp, IceAuthDataEntry *entry) 67 { 68 fprintf (addfp, 69 "add %s \"\" %s %s ", 70 entry->protocol_name, 71 entry->network_id, 72 entry->auth_name); 73 fprintfhex (addfp, entry->auth_data_length, entry->auth_data); 74 fprintf (addfp, "\n"); 75 76 fprintf (removefp, 77 "remove protoname=%s protodata=\"\" netid=%s authname=%s\n", 78 entry->protocol_name, 79 entry->network_id, 80 entry->auth_name); 81 } 82 83 84 85 #ifndef HAVE_MKSTEMP 87 static char * 88 unique_filename(const char *path, const char *prefix) 89 #else 90 static char * 91 unique_filename(const char *path, const char *prefix, int *pFd) 92 #endif 93 { 94 #ifndef HAVE_MKSTEMP 95 #ifndef X_NOT_POSIX 96 return ((char *) tempnam (path, prefix)); 97 #else 98 char tempFile[PATH_MAX]; 99 char *tmp; 100 101 snprintf (tempFile, sizeof(tempFile), "%s/%sXXXXXX", path, prefix); 102 tmp = (char *) mktemp (tempFile); 103 if (tmp) 104 { 105 return strdup(tmp); 106 } 107 else 108 return (NULL); 109 #endif 110 #else 111 char tempFile[PATH_MAX]; 112 char *ptr; 113 114 snprintf (tempFile, sizeof(tempFile), "%s/%sXXXXXX", path, prefix); 115 ptr = strdup(tempFile); 116 if (ptr != NULL) 117 { 118 *pFd = mkstemp(ptr); 119 } 120 return ptr; 121 #endif 122 } 123 124 125 126 127 /* 129 * Provide authentication data to clients that wish to connect 130 */ 131 132 #define MAGIC_COOKIE_LEN 16 133 134 Status 135 SetAuthentication(int count, IceListenObj *listenObjs, 136 IceAuthDataEntry **authDataEntries) 137 { 138 FILE *addfp = NULL; 139 FILE *removefp = NULL; 140 const char *path; 141 mode_t original_umask; 142 char command[256]; 143 int i; 144 #ifdef HAVE_MKSTEMP 145 int fd; 146 #endif 147 148 original_umask = umask (0077); /* disallow non-owner access */ 149 150 path = getenv ("SM_SAVE_DIR"); 151 if (!path) 152 { 153 path = getenv ("HOME"); 154 if (!path) 155 path = "."; 156 } 157 #ifndef HAVE_MKSTEMP 158 if ((addAuthFile = unique_filename (path, ".xsm")) == NULL) 159 goto bad; 160 161 if (!(addfp = fopen (addAuthFile, "w"))) 162 goto bad; 163 fcntl(fileno(addfp), F_SETFD, FD_CLOEXEC); 164 165 if ((remAuthFile = unique_filename (path, ".xsm")) == NULL) 166 goto bad; 167 168 if (!(removefp = fopen (remAuthFile, "w"))) 169 goto bad; 170 fcntl(fileno(removefp), F_SETFD, FD_CLOEXEC); 171 #else 172 if ((addAuthFile = unique_filename (path, ".xsm", &fd)) == NULL) 173 goto bad; 174 175 if (!(addfp = fdopen(fd, "wb"))) 176 goto bad; 177 fcntl(fileno(addfp), F_SETFD, FD_CLOEXEC); 178 179 if ((remAuthFile = unique_filename (path, ".xsm", &fd)) == NULL) 180 goto bad; 181 182 if (!(removefp = fdopen(fd, "wb"))) 183 goto bad; 184 fcntl(fileno(removefp), F_SETFD, FD_CLOEXEC); 185 #endif 186 187 if ((*authDataEntries = (IceAuthDataEntry *) XtMalloc ( 188 count * 2 * sizeof (IceAuthDataEntry))) == NULL) 189 goto bad; 190 191 for (i = 0; i < count * 2; i += 2) 192 { 193 (*authDataEntries)[i].network_id = 194 IceGetListenConnectionString (listenObjs[i/2]); 195 (*authDataEntries)[i].protocol_name = "ICE"; 196 (*authDataEntries)[i].auth_name = "MIT-MAGIC-COOKIE-1"; 197 198 (*authDataEntries)[i].auth_data = 199 IceGenerateMagicCookie (MAGIC_COOKIE_LEN); 200 (*authDataEntries)[i].auth_data_length = MAGIC_COOKIE_LEN; 201 202 (*authDataEntries)[i+1].network_id = 203 IceGetListenConnectionString (listenObjs[i/2]); 204 (*authDataEntries)[i+1].protocol_name = "XSMP"; 205 (*authDataEntries)[i+1].auth_name = "MIT-MAGIC-COOKIE-1"; 206 207 (*authDataEntries)[i+1].auth_data = 208 IceGenerateMagicCookie (MAGIC_COOKIE_LEN); 209 (*authDataEntries)[i+1].auth_data_length = MAGIC_COOKIE_LEN; 210 211 write_iceauth (addfp, removefp, &(*authDataEntries)[i]); 212 write_iceauth (addfp, removefp, &(*authDataEntries)[i+1]); 213 214 IceSetPaAuthData (2, &(*authDataEntries)[i]); 215 216 IceSetHostBasedAuthProc (listenObjs[i/2], HostBasedAuthProc); 217 } 218 219 fclose (addfp); 220 fclose (removefp); 221 222 umask (original_umask); 223 224 snprintf (command, sizeof(command), "iceauth source %s", addAuthFile); 225 execute_system_command (command); 226 227 remove (addAuthFile); 228 229 return (1); 230 231 bad: 232 233 if (addfp) 234 fclose (addfp); 235 236 if (removefp) 237 fclose (removefp); 238 239 if (addAuthFile) 240 { 241 remove (addAuthFile); 242 free (addAuthFile); 243 } 244 if (remAuthFile) 245 { 246 remove (remAuthFile); 247 free (remAuthFile); 248 } 249 250 return (0); 251 } 252 253 254 255 /* 257 * Free up authentication data. 258 */ 259 260 void 261 FreeAuthenticationData(int count, IceAuthDataEntry *authDataEntries) 262 { 263 /* Each transport has entries for ICE and XSMP */ 264 265 char command[256]; 266 int i; 267 268 for (i = 0; i < count * 2; i++) 269 { 270 free (authDataEntries[i].network_id); 271 free (authDataEntries[i].auth_data); 272 } 273 274 XtFree ((char *) authDataEntries); 275 276 snprintf (command, sizeof(command), "iceauth source %s", remAuthFile); 277 execute_system_command (command); 278 279 remove (remAuthFile); 280 281 free (addAuthFile); 282 free (remAuthFile); 283 } 284