--- OLD/xc/programs/xauth/process.c Thu Jan 1 00:00:00 1970 +++ NEW/xc/programs/xauth/process.c Thu Jan 1 00:00:00 1970 @@ -453,18 +453,23 @@ return n; } -static Bool get_displayname_auth (displayname, auth) +static int get_displayname_auth (displayname, authv) char *displayname; - Xauth *auth; /* fill in */ + Xauth ***authv; /* fill in */ { int family; char *host = NULL, *rest = NULL; int dpynum, scrnum; char *cp; int len; - extern char *get_address_info(); + extern void **get_address_info(); + void **addrinfo; Xauth proto; int prelen = 0; + int n; + char dnbuf[40]; /* want to hold largest display num */ + int dnlen; + Xauth **rv; /* * check to see if the display name is of the form "host/unix:" @@ -472,47 +477,66 @@ */ cp = strchr(displayname, '/'); if (cp && strncmp (cp, "/unix:", 6) == 0) - prelen = (cp - displayname); + prelen = (cp - displayname); if (!parse_displayname (displayname + ((prelen > 0) ? prelen + 1 : 0), &family, &host, &dpynum, &scrnum, &rest)) { return False; } - proto.family = family; - proto.address = get_address_info (family, displayname, prelen, host, &len); - if (proto.address) { - char buf[40]; /* want to hold largest display num */ - - proto.address_length = len; - buf[0] = '\0'; - sprintf (buf, "%d", dpynum); - proto.number_length = strlen (buf); - if (proto.number_length <= 0) { - free (proto.address); - proto.address = NULL; - } else { - proto.number = copystring (buf, proto.number_length); - } - } - + addrinfo = get_address_info (family, displayname, prelen, host, &len); if (host) free (host); if (rest) free (rest); + if (! addrinfo) return 0; - if (proto.address) { - auth->family = proto.family; - auth->address = proto.address; - auth->address_length = proto.address_length; - auth->number = proto.number; - auth->number_length = proto.number_length; - auth->name = NULL; - auth->name_length = 0; - auth->data = NULL; - auth->data_length = 0; - return True; - } else { - return False; + for (n = 0; addrinfo[n]; n++) + ; + + rv = malloc (n * sizeof(*rv)); + if (! rv) { + for (n = 0; addrinfo[n]; n++) free (addrinfo[n]); + free (addrinfo); + return 0; } + + sprintf (&dnbuf[0], "%d", dpynum); + dnlen = strlen (&dnbuf[0]); + + for (n = 0; addrinfo[n]; n++) { + rv[n] = malloc (sizeof(**rv)); + if (rv[n] == 0) { + for (n--; n >= 0; n--) free (rv[n]); + free (rv); + for (n = 0; addrinfo[n]; n++) free (addrinfo[n]); + free (addrinfo); + return 0; + } + } + + for (n = 0; addrinfo[n]; n++) { + rv[n]->family = family; + rv[n]->address = addrinfo[n]; + rv[n]->address_length = len; + rv[n]->number = copystring (&dnbuf[0], dnlen); + if (! rv[n]->number) { + for (n--; n >= 0; n--) free (rv[n]->number); + for (n = 0; addrinfo[n]; n++) { + free (addrinfo[n]); + free (rv[n]); + } + free (addrinfo); + free (rv); + return 0; + } + rv[n]->number_length = dnlen; + rv[n]->name = 0; + rv[n]->name_length = 0; + rv[n]->data = 0; + rv[n]->data_length = 0; + } + + *authv = rv; + return n; } static int cvthexkey (hexstr, ptrp) /* turn hex key string into octets */ @@ -1020,14 +1044,14 @@ AuthList **firstp, *second; int *nnewp, *nreplp; { - AuthList *a, *b, *first, *tail; + AuthList *a, *b, *first, **tail; int n = 0, nnew = 0, nrepl = 0; if (!second) return 0; if (!*firstp) { /* if nothing to merge into */ *firstp = second; - for (tail = *firstp, n = 1; tail->next; n++, tail = tail->next) ; + for (a = *firstp, n = 0; a; n++, a = a->next) ; *nnewp = n; *nreplp = 0; return n; @@ -1035,50 +1059,39 @@ first = *firstp; /* - * find end of first list and stick second list on it + * find end of first list */ - for (tail = first; tail->next; tail = tail->next) ; - tail->next = second; + for (tail = &first; (a = *tail); tail = &a->next) ; /* - * run down list freeing duplicate entries; if an entry is okay, then - * bump the tail up to include it, otherwise, cut the entry out of - * the chain. + * run down list; for each entry, see if it's a duplicate. if so, + * replace and free; else append. */ - for (b = second; b; ) { - AuthList *next = b->next; /* in case we free it */ - - a = first; - for (;;) { - if (match_auth (a->auth, b->auth)) { /* found a duplicate */ - AuthList tmp; /* swap it in for old one */ - tmp = *a; - *a = *b; - *b = tmp; - a->next = b->next; - XauDisposeAuth (b->auth); - free ((char *) b); - b = NULL; - tail->next = next; + b = second; + while (b) { + AuthList *next = b->next; + for (a = first; a; a = a->next) { + if (match_auth (a->auth, b->auth)) { /* duplicate! */ + XauDisposeAuth (a->auth); + a->auth = b->auth; + free (b); nrepl++; - nnew--; break; } - if (a == tail) break; /* if have looked at left side */ - a = a->next; } - if (b) { /* if we didn't remove it */ - tail = b; /* bump end of first list */ + if (! a) { /* no dup found */ + b->next = 0; + *tail = b; + tail = &b->next; + nnew++; } b = next; n++; - nnew++; } *nnewp = nnew; *nreplp = nrepl; return n; - } @@ -1093,9 +1106,11 @@ char *data; { int i; + int j; int status; int errors = 0; - Xauth proto; + Xauth **authlist; + int authn; AuthList *l, *next; /* @@ -1103,8 +1118,8 @@ */ for (i = start; i < argc; i++) { char *displayname = argv[i]; - proto.address = proto.number = NULL; - if (!get_displayname_auth (displayname, &proto)) { + authn = get_displayname_auth (displayname, &authlist); + if (authn <= 0) { prefix (inputfilename, lineno); baddisplayname (displayname, argv[0]); errors++; @@ -1113,7 +1128,9 @@ status = 0; for (l = xauth_head; l; l = next) { next = l->next; - if (match_auth_dpy (&proto, l->auth)) { + for (j = 0; j < authn; j++) + if (match_auth_dpy (authlist[j], l->auth)) break; + if (j < authn) { if (yfunc) { status = (*yfunc) (inputfilename, lineno, l->auth, data); @@ -1127,8 +1144,12 @@ } } } - if (proto.address) free (proto.address); - if (proto.number) free (proto.number); + for (j = 0; j < authn; j++) { + if (authlist[j]->address) free (authlist[j]->address); + if (authlist[j]->number) free (authlist[j]->number); + free (authlist[j]); + } + free (authlist); if (status < 0) { errors -= status; /* since status is negative */ break; @@ -1416,13 +1437,17 @@ char **argv; { int n, nnew, nrepl; - int len; + int keylen; char *dpyname; char *protoname; char *hexkey; char *key; - Xauth *auth; + Xauth **auth; + int nauth; AuthList *list; + AuthList **listtail; + AuthList *al; + int i; if (argc != 4 || !argv[1] || !argv[2] || !argv[3]) { prefix (inputfilename, lineno); @@ -1434,18 +1459,19 @@ 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; + i = strlen(hexkey); + if (hexkey[0] == '"' && hexkey[i-1] == '"') { + keylen = i - 2; + key = malloc(keylen); + memcpy(key, hexkey+1, keylen); } else if (!strcmp(protoname, SECURERPC) || !strcmp(protoname, K5AUTH)) { - key = malloc(len+1); - strcpy(key, hexkey); + keylen = i; + key = malloc(keylen); + memcpy(key, hexkey, keylen); } else { - len = cvthexkey (hexkey, &key); - if (len < 0) { + keylen = cvthexkey (hexkey, &key); + if (keylen < 0) { prefix (inputfilename, lineno); fprintf (stderr, "key contains odd number of or non-hex characters\n"); @@ -1453,19 +1479,16 @@ } } - auth = (Xauth *) malloc (sizeof (Xauth)); - if (!auth) { + nauth = get_displayname_auth (dpyname, &auth); + if (nauth < 0) { prefix (inputfilename, lineno); - fprintf (stderr, "unable to allocate %d bytes for Xauth structure\n", - sizeof (Xauth)); + fprintf (stderr, "unable to allocate space for Xauth structures\n"); free (key); return 1; } - - if (!get_displayname_auth (dpyname, auth)) { + if (nauth == 0) { prefix (inputfilename, lineno); baddisplayname (dpyname, argv[0]); - free (auth); free (key); return 1; } @@ -1477,32 +1500,73 @@ 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; + for (i = 0; i < nauth; i++) { + auth[i]->name_length = strlen (protoname); + auth[i]->name = copystring (protoname, auth[i]->name_length); + if (!auth[i]->name) { + prefix (inputfilename, lineno); + fprintf (stderr, "unable to allocate %d-character protocol name\n", + auth[i]->name_length); + for (i = 0; i < nauth; i++) { + if (auth[i]->name) free (auth[i]->name); + if (auth[i]->data) free (auth[i]->data); + free (auth[i]); + } + free (auth); + free (key); + return 1; + } + /* + * It's a pain to have to duplicate the key data like this, + * but merge_entries may call XauDisposeAuth, which expects + * the key data to be individually freeable. + */ + auth[i]->data_length = keylen; + auth[i]->data = malloc (keylen); + if (!auth[i]->data) { + prefix (inputfilename, lineno); + fprintf (stderr, "unable to allocate %d-byte key buffer\n", + keylen); + for (i = 0; i < nauth; i++) { + if (auth[i]->name) free (auth[i]->name); + if (auth[i]->data) free (auth[i]->data); + free (auth[i]); + } + free (auth); + free (key); + return 1; + } + memcpy (auth[i]->data, key, keylen); } - auth->data_length = len; - auth->data = key; + free (key); - list = (AuthList *) malloc (sizeof (AuthList)); - if (!list) { - prefix (inputfilename, lineno); - fprintf (stderr, "unable to allocate %d bytes for auth list\n", - sizeof (AuthList)); - free (auth); - free (key); - free (auth->name); - return 1; + listtail = &list; + for (i = 0; i < nauth; i++) { + al = (AuthList *) malloc (sizeof (AuthList)); + if (!al) { + prefix (inputfilename, lineno); + fprintf (stderr, "unable to allocate %d bytes for auth list\n", + sizeof (AuthList)); + for (i = 0; i < nauth; i++) { + free (auth[i]->name); + free (auth[i]->data); + free (auth[i]); + } + free (auth); + *listtail = 0; + while (list) { + al = list; + list = al->next; + free(al); + } + return 1; + } + al->auth = auth[i]; + *listtail = al; + listtail = &al->next; } - - list->next = NULL; - list->auth = auth; + *listtail = 0; + free (auth); /* * merge it in; note that merge will deal with allocation @@ -1510,7 +1574,7 @@ n = merge_entries (&xauth_head, list, &nnew, &nrepl); if (n <= 0) { prefix (inputfilename, lineno); - fprintf (stderr, "unable to merge in added record\n"); + fprintf (stderr, "unable to merge in added record(s)\n"); return 1; }