/* * merge filename [filename ...] */ static int do_merge(char *inputfilename, int lineno, int argc, char **argv) { int i; int errors = 0; AuthList *head, *tail, *listhead, *listtail; int nentries, nnew, nrepl; Bool numeric = False; if (argc < 2) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } if (argv[0][0] == 'n') numeric = True; listhead = listtail = NULL; for (i = 1; i < argc; i++) { char *filename = argv[i]; FILE *fp; Bool used_stdin = False; fp = open_file (&filename, numeric ? "r" : "rb", &used_stdin, inputfilename, lineno, argv[0]); if (!fp) { errors++; continue; } head = tail = NULL; nentries = read_auth_entries (fp, numeric, &head, &tail); if (nentries == 0) { prefix (inputfilename, lineno); fprintf (stderr, "unable to read any entries from file \"%s\"\n", filename); errors++; } else { /* link it in */ add_to_list (listhead, listtail, head); } if (!used_stdin) (void) fclose (fp); } /* * if we have new entries, merge them in (freeing any duplicates) */ if (listhead) { nentries = merge_entries (&xauth_head, listhead, &nnew, &nrepl); if (verbose) printf ("%d entries read in: %d new, %d replacement%s\n", nentries, nnew, nrepl, nrepl != 1 ? "s" : ""); if (nentries > 0) xauth_modified = True; } return 0; }
/* * remove displayname */ static int do_remove(char *inputfilename, int lineno, int argc, char **argv) { int nremoved = 0; int errors; if (argc < 2) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } errors = iterdpy (inputfilename, lineno, 1, argc, argv, remove_entry, NULL, (char *) &nremoved); if (verbose) printf ("%d entries removed\n", nremoved); return errors; }
/* * extract filename displayname [displayname ...] */ static int do_extract(const char *inputfilename, int lineno, int argc, const char **argv) { int errors; struct _extract_data ed; if (argc < 3) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } ed.fp = NULL; ed.filename = argv[1]; ed.used_stdout = False; ed.numeric = (argv[0][0] == 'n'); ed.nwritten = 0; ed.cmd = argv[0]; errors = iterdpy (inputfilename, lineno, 2, argc, argv, extract_entry, NULL, (char *) &ed); if (!ed.fp) { fprintf (stderr, "No matches found, authority file \"%s\" not written\n", ed.filename); } else { if (verbose) { printf ("%d entries written to \"%s\"\n", ed.nwritten, ed.filename); } if (!ed.used_stdout) { (void) fclose (ed.fp); } } return errors; }
/* * info */ static int do_info(char *inputfilename, int lineno, int argc, char **argv) { int n; AuthList *l; if (argc != 1) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } for (l = xauth_head, n = 0; l; l = l->next, n++) ; printf ("Authority file: %s\n", xauth_filename ? xauth_filename : "(none)"); printf ("File new: %s\n", xauth_existed ? No : Yes); printf ("File locked: %s\n", xauth_locked ? No : Yes); printf ("Number of entries: %d\n", n); printf ("Changes honored: %s\n", xauth_allowed ? Yes : No); printf ("Changes made: %s\n", xauth_modified ? Yes : No); printf ("Current input: %s:%d\n", inputfilename, lineno); return 0; }
/* * source filename */ static int do_source(char *inputfilename, int lineno, int argc, char **argv) { char *script; char buf[BUFSIZ]; FILE *fp; Bool used_stdin = False; int len; int errors = 0, status; int sublineno = 0; char **subargv; int subargc; Bool prompt = False; /* only true if reading from tty */ if (argc != 2 || !argv[1]) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } script = argv[1]; fp = open_file (&script, "r", &used_stdin, inputfilename, lineno, argv[0]); if (!fp) { return 1; } if (verbose && used_stdin && isatty (fileno (fp))) prompt = True; while (!alldone) { buf[0] = '\0'; if (prompt) { printf ("xauth> "); fflush (stdout); } if (fgets (buf, sizeof buf, fp) == NULL) break; sublineno++; len = strlen (buf); if (len == 0 || buf[0] == '#') continue; if (buf[len-1] != '\n') { prefix (script, sublineno); fprintf (stderr, "line too long\n"); errors++; break; } buf[--len] = '\0'; /* remove new line */ subargv = split_into_words (buf, &subargc); if (subargv) { status = process_command (script, sublineno, subargc, subargv); free ((char *) subargv); errors += status; } else { prefix (script, sublineno); fprintf (stderr, "unable to break line into words\n"); errors++; } } if (!used_stdin) { (void) fclose (fp); } return errors; }
/* * add displayname protocolname hexkey */ static int do_add(char *inputfilename, int lineno, int argc, char **argv) { int n, nnew, nrepl; int len; char *dpyname; char *protoname; char *hexkey; char *key; Xauth *auth; AuthList *list; if (argc != 4 || !argv[1] || !argv[2] || !argv[3]) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } dpyname = argv[1]; protoname = argv[2]; hexkey = argv[3]; len = strlen(hexkey); if (hexkey[0] == '"' && hexkey[len-1] == '"') { key = malloc(len-1); strncpy(key, hexkey+1, len-2); len -= 2; } else if (!strcmp(protoname, SECURERPC) || !strcmp(protoname, K5AUTH)) { key = malloc(len+1); strcpy(key, hexkey); } else { len = cvthexkey (hexkey, &key); if (len < 0) { prefix (inputfilename, lineno); fprintf (stderr, "key contains odd number of or non-hex characters\n"); return 1; } } auth = (Xauth *) malloc (sizeof (Xauth)); if (!auth) { prefix (inputfilename, lineno); fprintf (stderr, "unable to allocate %ld bytes for Xauth structure\n", (unsigned long)sizeof (Xauth)); free (key); return 1; } if (!get_displayname_auth (dpyname, auth)) { prefix (inputfilename, lineno); baddisplayname (dpyname, argv[0]); free (auth); free (key); return 1; } /* * allow an abbreviation for common protocol names */ if (strcmp (protoname, DEFAULT_PROTOCOL_ABBREV) == 0) { protoname = DEFAULT_PROTOCOL; } auth->name_length = strlen (protoname); auth->name = copystring (protoname, auth->name_length); if (!auth->name) { prefix (inputfilename, lineno); fprintf (stderr, "unable to allocate %d character protocol name\n", auth->name_length); free (auth); free (key); return 1; } auth->data_length = len; auth->data = key; list = (AuthList *) malloc (sizeof (AuthList)); if (!list) { prefix (inputfilename, lineno); fprintf (stderr, "unable to allocate %ld bytes for auth list\n", (unsigned long)sizeof (AuthList)); free (auth); free (key); free (auth->name); return 1; } list->next = NULL; list->auth = auth; /* * merge it in; note that merge will deal with allocation */ n = merge_entries (&xauth_head, list, &nnew, &nrepl); if (n <= 0) { prefix (inputfilename, lineno); fprintf (stderr, "unable to merge in added record\n"); return 1; } xauth_modified = True; return 0; }
/* * generate */ static int do_generate(const char *inputfilename, int lineno, int argc, const char **argv) { const char *displayname; int major_version, minor_version; XSecurityAuthorization id_return; Xauth *auth_in, *auth_return; XSecurityAuthorizationAttributes attributes; unsigned long attrmask = 0; Display *dpy; int status; const char *args[4]; const char *protoname = "."; int i; int authdatalen = 0; const char *hexdata; char *authdata = NULL; char *hex; if (argc < 2 || !argv[1]) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } displayname = argv[1]; if (argc > 2) { protoname = argv[2]; } for (i = 3; i < argc; i++) { if (0 == strcmp(argv[i], "timeout")) { if (++i == argc) { prefix (inputfilename, lineno); badcommandline (argv[i-1]); return 1; } attributes.timeout = atoi(argv[i]); attrmask |= XSecurityTimeout; } else if (0 == strcmp(argv[i], "trusted")) { attributes.trust_level = XSecurityClientTrusted; attrmask |= XSecurityTrustLevel; } else if (0 == strcmp(argv[i], "untrusted")) { attributes.trust_level = XSecurityClientUntrusted; attrmask |= XSecurityTrustLevel; } else if (0 == strcmp(argv[i], "group")) { if (++i == argc) { prefix (inputfilename, lineno); badcommandline (argv[i-1]); return 1; } attributes.group = atoi(argv[i]); attrmask |= XSecurityGroup; } else if (0 == strcmp(argv[i], "data")) { if (++i == argc) { prefix (inputfilename, lineno); badcommandline (argv[i-1]); return 1; } hexdata = argv[i]; authdatalen = strlen(hexdata); if (hexdata[0] == '"' && hexdata[authdatalen-1] == '"') { authdata = malloc(authdatalen-1); strncpy(authdata, hexdata+1, authdatalen-2); authdatalen -= 2; } else { authdatalen = cvthexkey (hexdata, &authdata); if (authdatalen < 0) { prefix (inputfilename, lineno); fprintf (stderr, "data contains odd number of or non-hex characters\n"); return 1; } } } else { prefix (inputfilename, lineno); badcommandline (argv[i]); return 1; } } /* generate authorization using the Security extension */ dpy = XOpenDisplay (displayname); if (!dpy) { prefix (inputfilename, lineno); fprintf (stderr, "unable to open display \"%s\".\n", displayname); return 1; } status = XSecurityQueryExtension(dpy, &major_version, &minor_version); if (!status) { prefix (inputfilename, lineno); fprintf (stderr, "couldn't query Security extension on display \"%s\"\n", displayname); return 1; } /* fill in input Xauth struct */ auth_in = XSecurityAllocXauth(); if (strcmp (protoname, DEFAULT_PROTOCOL_ABBREV) == 0) { auth_in->name = copystring(DEFAULT_PROTOCOL, strlen(DEFAULT_PROTOCOL)); } else auth_in->name = copystring (protoname, strlen(protoname)); auth_in->name_length = strlen(auth_in->name); auth_in->data = authdata; auth_in->data_length = authdatalen; x_protocol_error = 0; XSetErrorHandler(catch_x_protocol_error); auth_return = XSecurityGenerateAuthorization(dpy, auth_in, attrmask, &attributes, &id_return); XSync(dpy, False); if (!auth_return || x_protocol_error) { prefix (inputfilename, lineno); fprintf (stderr, "couldn't generate authorization\n"); return 1; } if (verbose) printf("authorization id is %ld\n", id_return); /* create a fake input line to give to do_add */ hex = bintohex(auth_return->data_length, auth_return->data); args[0] = "add"; args[1] = displayname; args[2] = auth_in->name; args[3] = hex; status = do_add(inputfilename, lineno, 4, args); if (authdata) free(authdata); XSecurityFreeXauth(auth_in); XSecurityFreeXauth(auth_return); free(hex); XCloseDisplay(dpy); return status; }