/* This just gets a cookie of MIT-MAGIC-COOKIE-1 type */ char * mdmcomm_get_a_cookie (gboolean binary) { FILE *fp; char *number; char *cookie = NULL; Xauth *xau; VE_IGNORE_EINTR (fp = fopen (XauFileName (), "r")); if (fp == NULL) { return NULL; } number = get_dispnum (); cookie = NULL; while ((xau = XauReadAuth (fp)) != NULL) { /* Just find the FIRST magic cookie, that's what mdm uses */ if (xau->number_length != strlen (number) || strncmp (xau->number, number, xau->number_length) != 0 || /* mdm sends MIT-MAGIC-COOKIE-1 cookies of length 16, * so just do those */ xau->data_length != 16 || xau->name_length != strlen ("MIT-MAGIC-COOKIE-1") || strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) != 0) { XauDisposeAuth (xau); continue; } if (binary) { cookie = g_new0 (char, 16); memcpy (cookie, xau->data, 16); } else { int i; GString *str; str = g_string_new (NULL); for (i = 0; i < xau->data_length; i++) { g_string_append_printf (str, "%02x", (guint)(guchar)xau->data[i]); } cookie = g_string_free (str, FALSE); } XauDisposeAuth (xau); break; }
static Xauth* find_auth_cookie (FILE *f) { Xauth *ret = NULL; char local_hostname[MaxHostNameLen]; char *display_str = getenv("DISPLAY"); char d[MaxHostNameLen + 4]; char *colon; struct addrinfo *ai; struct addrinfo hints; int disp; int error; if(display_str == NULL) display_str = ":0"; strlcpy(d, display_str, sizeof(d)); display_str = d; colon = strchr (display_str, ':'); if (colon == NULL) disp = 0; else { *colon = '\0'; disp = atoi (colon + 1); } if (strcmp (display_str, "") == 0 || strncmp (display_str, "unix", 4) == 0 || strncmp (display_str, "localhost", 9) == 0) { gethostname (local_hostname, sizeof(local_hostname)); display_str = local_hostname; } memset (&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; error = getaddrinfo (display_str, NULL, &hints, &ai); if (error) ai = NULL; for (; (ret = XauReadAuth (f)) != NULL; XauDisposeAuth(ret)) { if (match_local_auth (ret, ai, display_str, disp) == 0) { if (ai != NULL) freeaddrinfo (ai); return ret; } } if (ai != NULL) freeaddrinfo (ai); return NULL; }
int LoadAuthorization (void) { FILE *f; Xauth *auth; int i; int count = 0; #if !defined(WIN32) && !defined(__UNIXOS2__) char *buf; #endif ShouldLoadAuth = FALSE; if (!authorization_file) return 0; #if !defined(WIN32) && !defined(__UNIXOS2__) buf = xalloc (strlen(authorization_file) + 5); if (!buf) return -1; sprintf (buf, "cat %s", authorization_file); f = Popen (buf, "r"); xfree (buf); #else f = fopen (authorization_file, "r"); #endif if (!f) return -1; while ((auth = XauReadAuth (f)) != 0) { for (i = 0; i < NUM_AUTHORIZATION; i++) { if (protocols[i].name_length == auth->name_length && memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 && protocols[i].Add) { ++count; (*protocols[i].Add) (auth->data_length, auth->data, FakeClientID(0)); } } XauDisposeAuth (auth); } #if !defined(WIN32) && !defined(__UNIXOS2__) if (Pclose (f) != 0) return -1; #else fclose (f); #endif return count; }
void DM::GDMAuthenticate() { FILE *fp; const char *dpy, *dnum, *dne; int dnl; Xauth *xau; dpy = DisplayString(QPaintDevice::x11AppDisplay()); if(!dpy) { dpy = ::getenv("DISPLAY"); if(!dpy) return; } dnum = strchr(dpy, ':') + 1; dne = strchr(dpy, '.'); dnl = dne ? dne - dnum : strlen(dnum); /* XXX should do locking */ if(!(fp = fopen(XauFileName(), "r"))) return; while((xau = XauReadAuth(fp))) { if(xau->family == FamilyLocal && xau->number_length == dnl && !memcmp(xau->number, dnum, dnl) && xau->data_length == 16 && xau->name_length == 18 && !memcmp(xau->name, "MIT-MAGIC-COOKIE-1", 18)) { QString cmd("AUTH_LOCAL "); for(int i = 0; i < 16; i++) cmd += QString::number((uchar)xau->data[i], 16).rightJustify(2, '0'); cmd += "\n"; if(exec(cmd.latin1())) { XauDisposeAuth(xau); break; } } XauDisposeAuth(xau); } fclose(fp); }
static int LoadAuthorization(void) { FILE *f; Xauth *auth; int i; int count = 0; ShouldLoadAuth = FALSE; if (!authorization_file) return 0; errno = 0; f = Fopen(authorization_file, "r"); if (!f) { LogMessageVerb(X_ERROR, 0, "Failed to open authorization file \"%s\": %s\n", authorization_file, errno != 0 ? strerror(errno) : "Unknown error"); return -1; } while ((auth = XauReadAuth(f)) != 0) { for (i = 0; i < NUM_AUTHORIZATION; i++) { if (protocols[i].name_length == auth->name_length && memcmp(protocols[i].name, auth->name, (int) auth->name_length) == 0 && protocols[i].Add) { ++count; (*protocols[i].Add) (auth->data_length, auth->data, FakeClientID(0)); } } XauDisposeAuth(auth); } Fclose(f); return count; }
Xauth * XauGetBestAuthByAddr ( #if NeedWidePrototypes unsigned int family, unsigned int address_length, #else unsigned short family, unsigned short address_length, #endif _Xconst char* address, #if NeedWidePrototypes unsigned int number_length, #else unsigned short number_length, #endif _Xconst char* number, int types_length, char** types, _Xconst int* type_lengths) { FILE *auth_file; char *auth_name; Xauth *entry; Xauth *best; int best_type; int type; #ifdef hpux char *fully_qual_address; unsigned short fully_qual_address_length; #endif auth_name = XauFileName (); if (!auth_name) return NULL; if (access (auth_name, R_OK) != 0) /* checks REAL id */ return NULL; auth_file = fopen (auth_name, "rb"); if (!auth_file) return NULL; #ifdef hpux if (family == FamilyLocal) { #ifdef XTHREADS_NEEDS_BYNAMEPARAMS _Xgethostbynameparams hparams; #endif struct hostent *hostp; /* make sure we try fully-qualified hostname */ if ((hostp = _XGethostbyname(address,hparams)) != NULL) { fully_qual_address = hostp->h_name; fully_qual_address_length = strlen(fully_qual_address); } else { fully_qual_address = NULL; fully_qual_address_length = 0; } } #endif /* hpux */ best = NULL; best_type = types_length; for (;;) { entry = XauReadAuth (auth_file); if (!entry) break; /* * Match when: * either family or entry->family are FamilyWild or * family and entry->family are the same and * address and entry->address are the same * and * either number or entry->number are empty or * number and entry->number are the same * and * either name or entry->name are empty or * name and entry->name are the same */ if ((family == FamilyWild || entry->family == FamilyWild || (entry->family == family && ((address_length == entry->address_length && binaryEqual (entry->address, address, (int)address_length)) #ifdef hpux || (family == FamilyLocal && fully_qual_address_length == entry->address_length && binaryEqual (entry->address, fully_qual_address, (int) fully_qual_address_length)) #endif ))) && (number_length == 0 || entry->number_length == 0 || (number_length == entry->number_length && binaryEqual (entry->number, number, (int)number_length)))) { if (best_type == 0) { best = entry; break; } for (type = 0; type < best_type; type++) if (type_lengths[type] == entry->name_length && !(strncmp (types[type], entry->name, entry->name_length))) { break; } if (type < best_type) { if (best) XauDisposeAuth (best); best = entry; best_type = type; if (type == 0) break; continue; } } XauDisposeAuth (entry); } (void) fclose (auth_file); return best; }
Xauth * XauGetAuthByAddr ( #if NeedWidePrototypes unsigned int family, unsigned int address_length, #else unsigned short family, unsigned short address_length, #endif _Xconst char* address, #if NeedWidePrototypes unsigned int number_length, #else unsigned short number_length, #endif _Xconst char* number, #if NeedWidePrototypes unsigned int name_length, #else unsigned short name_length, #endif _Xconst char* name) { FILE *auth_file; char *auth_name; Xauth *entry; auth_name = XauFileName (); if (!auth_name) return NULL; if (access (auth_name, R_OK) != 0) /* checks REAL id */ return NULL; auth_file = fopen (auth_name, "rb"); if (!auth_file) return NULL; for (;;) { entry = XauReadAuth (auth_file); if (!entry) break; /* * Match when: * either family or entry->family are FamilyWild or * family and entry->family are the same and * address and entry->address are the same * and * either number or entry->number are empty or * number and entry->number are the same * and * either name or entry->name are empty or * name and entry->name are the same */ if ((family == FamilyWild || entry->family == FamilyWild || (entry->family == family && address_length == entry->address_length && binaryEqual (entry->address, address, address_length))) && (number_length == 0 || entry->number_length == 0 || (number_length == entry->number_length && binaryEqual (entry->number, number, number_length))) && (name_length == 0 || entry->name_length == 0 || (entry->name_length == name_length && binaryEqual (entry->name, name, name_length)))) break; XauDisposeAuth (entry); } (void) fclose (auth_file); return entry; }
/******************************************************************** * * fork/exec a child pdm after setting up a message pipe. */ void mgr_launch_pdm( XpPdmServiceRec *rec ) { int i; struct sigaction svec; char buf[1024]; int original_umask; char *existing_name; FILE *existing_file; Xauth *entry; char *envstr; /* * Setup message pipe. */ if ( pipe(rec->message_pipe) == -1 ) { rec->pdm_exec_errorcode = g.pdm_start_error; sprintf( buf, PDMD_MSG_8, g.prog_name ); rec->pdm_exec_errormessage = xpstrdup( buf ); return; } rec->message_xtid = XtAppAddInput( g.context, rec->message_pipe[0], (XtPointer) XtInputReadMask, message_pipe_handler, (XtPointer) NULL ); /* * See if a cookie file is needed. */ if (rec->cookie_cnt) { /* * Create new .Xauthority file. */ original_umask = umask (0077); /* disallow non-owner access */ tmpnam( rec->auth_filename ); rec->auth_file = fopen( rec->auth_filename, "w" ); if (rec->auth_file) { /* * Copy existing .Xauthority entries. */ existing_name = XauFileName (); if (existing_name) { if (access (existing_name, R_OK) == 0) { /* checks REAL id */ existing_file = fopen (existing_name, "r"); if (existing_file) { for (;;) { entry = XauReadAuth (existing_file); if (!entry) break; XauWriteAuth( rec->auth_file, entry ); XauDisposeAuth (entry); } fclose (existing_file); } } } /* * Merge in cookies recently sent. */ for ( i = 0; i < rec->cookie_cnt; i++ ) { XauWriteAuth( rec->auth_file, rec->cookies[i] ); } fclose( rec->auth_file ); } original_umask = umask (original_umask); } rec->pid = fork(); if ( rec->pid < 0 ) { rec->pdm_exec_errorcode = g.pdm_start_error; sprintf( buf, PDMD_MSG_9, g.prog_name ); rec->pdm_exec_errormessage = xpstrdup( buf ); return; } else if ( rec->pid == 0) { /* * Child process. */ /* * Hook stderr back to parent via message pipe. */ dup2(rec->message_pipe[1], 2); close(rec->message_pipe[0]); /* * The child should have default behavior for all signals. */ sigemptyset(&svec.sa_mask); svec.sa_flags = 0; svec.sa_handler = SIG_DFL; (void) sigaction(SIGCHLD, &svec, (struct sigaction *) NULL); for (i=3; i < FOPEN_MAX; i++) { if ((i != rec->message_pipe[1]) && (rec->auth_file && (i != fileno(rec->auth_file)))) { (void) fcntl (i, F_SETFD, 1); } } /* * Set the new locale for the child. * * note: the locale hint will be of the form: * * name_spec[;registry_spec[;ver_spec[;encoding_spec]]] * * for now, just pull out the name_spec (e.g. 'C') * and use it. With a little work, a more complex * syntax could be understood and the appropriate * actions taken here rather than just wedging * name_spec into setlocale() and hoping. */ if ( !(rec->locale_hint) ) { /* * Leave current locale alone. */ } else if ( strcmp( rec->locale_hint, "" ) ) { /* * Leave current locale alone. Note that "" into * setlocale says to go with default vs leave it alone. */ } else { char *tptr1, *tptr2; tptr1 = xpstrdup( rec->locale_hint ); tptr2 = strchr( tptr1, ';' ); if (tptr2) *tptr2 = '\0'; setlocale( LC_ALL, tptr1 ); XFree( tptr1 ); } /* * Set XAUTHORITY env var if needed. */ if ((rec->cookie_cnt) && (rec->auth_filename) && (rec->auth_file)) { envstr = Xmalloc( strlen(rec->auth_filename) + 12 ); sprintf( envstr, "XAUTHORITY=%s", rec->auth_filename ); putenv( envstr ); } /* * Start the child for real. */ (void) execvp(rec->pdm_exec_argvs[0], rec->pdm_exec_argvs); (void) fprintf (stderr, PDMD_MSG_10, g.prog_name, rec->pdm_exec_argvs[0]); /* * tomg - need to deal with failed child start. */ exit(PDM_EXIT_ERROR); } else { /* * Parent process. */ /* * Close the write end of the pipe - only the child needs it. */ close(rec->message_pipe[1]); rec->message_pipe[1] = -1; } }
static gboolean gdm_authenticate_connection (GdmProtocolData *data) { #define GDM_MIT_MAGIC_COOKIE_LEN 16 const char *xau_path; FILE *f; Xauth *xau; char *display_number; gboolean retval; if (data->auth_cookie) { char *msg; char *response; msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", data->auth_cookie); response = gdm_send_protocol_msg (data, msg); g_free (msg); if (response && !strcmp (response, "OK")) { g_free (response); return TRUE; } else { g_free (response); g_free (data->auth_cookie); data->auth_cookie = NULL; } } if (!(xau_path = XauFileName ())) return FALSE; if (!(f = fopen (xau_path, "r"))) return FALSE; retval = FALSE; display_number = get_display_number (); while ((xau = XauReadAuth (f))) { char buffer[40]; /* 2*16 == 32, so 40 is enough */ char *msg; char *response; int i; if (xau->family != FamilyLocal || strncmp (xau->number, display_number, xau->number_length) || strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) || xau->data_length != GDM_MIT_MAGIC_COOKIE_LEN) { XauDisposeAuth (xau); continue; } for (i = 0; i < GDM_MIT_MAGIC_COOKIE_LEN; i++) g_snprintf (buffer + 2*i, 3, "%02x", (guint)(guchar)xau->data[i]); XauDisposeAuth (xau); msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer); response = gdm_send_protocol_msg (data, msg); g_free (msg); if (response && !strcmp (response, "OK")) { data->auth_cookie = g_strdup (buffer); g_free (response); retval = TRUE; break; } g_free (response); } g_free (display_number); fclose (f); return retval; #undef GDM_MIT_MAGIC_COOKIE_LEN }
/* If ADD-ENTRIES is true, merge our auth entries into the existing Xauthority file. If ADD-ENTRIES is false, remove our entries. */ static int write_auth_file (int add_entries) { char *home, newname[1024]; int fd, ret; FILE *new_fh, *old_fh; addr_list *addr; Xauth *auth; if (auth_file == NULL) return FALSE; home = getenv ("HOME"); if (home == NULL) { auth_file = NULL; return FALSE; } snprintf (newname, sizeof (newname), "%s/.XauthorityXXXXXX", home); mktemp (newname); if (XauLockAuth (auth_file, 1, 2, 10) != LOCK_SUCCESS) { /* FIXME: do something here? */ auth_file = NULL; return FALSE; } fd = open (newname, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd >= 0) { new_fh = fdopen (fd, "w"); if (new_fh != NULL) { if (add_entries) { for (addr = addresses; addr != NULL; addr = addr->next) { XauWriteAuth (new_fh, &addr->auth); } } old_fh = fopen (auth_file, "r"); if (old_fh != NULL) { while ((auth = XauReadAuth (old_fh)) != NULL) { if (!check_auth_item (auth)) XauWriteAuth (new_fh, auth); XauDisposeAuth (auth); } fclose (old_fh); } fclose (new_fh); unlink (auth_file); ret = rename (newname, auth_file); if (ret != 0) auth_file = NULL; XauUnlockAuth (auth_file); return ret == 0; } close (fd); } XauUnlockAuth (auth_file); auth_file = NULL; return FALSE; }
Xauth * XauGetBestAuthByAddr ( #if NeedWidePrototypes unsigned int family, unsigned int address_length, #else unsigned short family, unsigned short address_length, #endif _Xconst char* address, #if NeedWidePrototypes unsigned int number_length, #else unsigned short number_length, #endif _Xconst char* number, int types_length, char** types, _Xconst int* type_lengths) { FILE *auth_file; char *auth_name; Xauth *entry; Xauth *best; int best_type; int type; auth_name = XauFileName (); if (!auth_name) return 0; if (access (auth_name, R_OK) != 0) /* checks REAL id */ return 0; auth_file = fopen (auth_name, "rb"); if (!auth_file) return 0; best = 0; best_type = types_length; for (;;) { entry = XauReadAuth (auth_file); if (!entry) break; /* * Match when: * either family or entry->family are FamilyWild or * family and entry->family are the same and * address and entry->address are the same * and * either number or entry->number are empty or * number and entry->number are the same * and * either name or entry->name are empty or * name and entry->name are the same */ if ((family == FamilyWild || entry->family == FamilyWild || (entry->family == family && ((address_length == entry->address_length && binaryEqual (entry->address, address, (int)address_length)) ))) && (number_length == 0 || entry->number_length == 0 || (number_length == entry->number_length && binaryEqual (entry->number, number, (int)number_length)))) { if (best_type == 0) { best = entry; break; } for (type = 0; type < best_type; type++) if (type_lengths[type] == entry->name_length && !(strncmp (types[type], entry->name, entry->name_length))) { break; } if (type < best_type) { if (best) XauDisposeAuth (best); best = entry; best_type = type; if (type == 0) break; continue; } } XauDisposeAuth (entry); } (void) fclose (auth_file); return best; }