2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * $TOG: process.c /main/1 1999/08/30 10:45:37 mgreess $
27 Copyright 1989, 1998 The Open Group
31 The above copyright notice and this permission notice shall be included in
32 all copies or substantial portions of the Software.
34 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
38 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 Except as contained in this notice, the name of The Open Group shall not be
42 used in advertising or otherwise to promote the sale, use or other dealings
43 in this Software without prior written authorization from The Open Group.
45 * Original Author of "xauth" : Jim Fulton, MIT X Consortium
46 * Modified into "ttauth" : Ralph Mor, X Consortium
47 * Modified into "ttauth" : Mitch Greess, Solutions Atlantic
57 #include <sys/types.h>
63 #include "api/c/api_auth.h"
64 #include "api/c/tt_c.h"
68 #define SECURERPC "SUN-DES-1"
69 #define K5AUTH "KERBEROS-V5-1"
71 #define TTAUTH_DEFAULT_RETRIES 10 /* number of competitors we expect */
72 #define TTAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */
73 #define TTAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */
75 #define add_to_list(h,t,e) {if (t) (t)->next = (e); else (h) = (e); (t) = (e);}
77 typedef struct _CommandTable { /* commands that are understood */
78 char *name; /* full name */
79 int minlen; /* unique prefix */
80 int maxlen; /* strlen(name) */
81 int (*processfunc)(); /* handler */
82 char *helptext; /* what to print for help */
85 struct _extract_data { /* for iterating */
86 FILE *fp; /* input source */
87 char *filename; /* name of input */
88 Bool used_stdout; /* whether or not need to close */
89 int nwritten; /* number of entries written */
90 char *cmd; /* for error messages */
93 struct _list_data { /* for iterating */
94 FILE *fp; /* output file */
101 static char *stdin_filename = "(stdin)"; /* for messages */
102 static char *stdout_filename = "(stdout)"; /* for messages */
103 static const char *Yes = "yes"; /* for messages */
104 static const char *No = "no"; /* for messages */
106 static int do_list(char *inputfilename, int lineno, int argc, char *argv[]);
107 static int do_merge(char *inputfilename, int lineno, int argc, char *argv[]);
108 static int do_extract(char *inputfilename, int lineno, int argc, char *argv[]);
109 static int do_add(char *inputfilename, int lineno, int argc, char *argv[]);
110 static int do_remove(char *inputfilename, int lineno, int argc, char *argv[]);
111 static int do_help(char *inputfilename, int lineno, int argc, char *argv[]);
112 static int do_source(char *inputfilename, int lineno, int argc, char *argv[]);
113 static int do_info(char *inputfilename, int lineno, int argc, char *argv[]);
114 static int do_exit(char *inputfilename, int lineno, int argc, char *argv[]);
115 static int do_quit(char *inputfilename, int lineno, int argc, char *argv[]);
116 static int do_questionmark(char *inputfilename, int lineno, int argc, char *argv[]);
118 static CommandTable command_table[] = { /* table of known commands */
119 { "add", 2, 3, do_add,
122 add protoname protodata netid authname authdata"
125 { "exit", 3, 4, do_exit,
127 exit save changes and exit program"
130 { "extract", 3, 7, do_extract,
132 extract extract entries into file\n\
133 extract filename <protoname=$> <protodata=$> <netid=$> <authname=$>"
136 { "help", 1, 4, do_help,
142 { "info", 1, 4, do_info,
144 info print information about entries"
147 { "list", 1, 4, do_list,
150 list <protoname=$> <protodata=$> <netid=$> <authname=$>"
153 { "merge", 1, 5, do_merge,
155 merge merge entries from files\n\
156 merge filename1 <filename2> <filename3> ..."
159 { "quit", 1, 4, do_quit,
161 quit abort changes and exit program" },
163 { "remove", 1, 6, do_remove,
165 remove remove entries\n\
166 remove <protoname=$> <protodata=$> <netid=$> <authname=$>"
169 { "source", 1, 6, do_source,
171 source read commands from file\n\
175 { "?", 1, 1, do_questionmark,
177 ? list available commands" },
179 { NULL, 0, 0, NULL, NULL },
182 #define COMMAND_NAMES_PADDED_WIDTH 10 /* wider than anything above */
185 static Bool okay_to_use_stdin = True; /* set to false after using */
187 static const char *hex_table[] = { /* for printing hex digits */
188 "00", "01", "02", "03", "04", "05", "06", "07",
189 "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
190 "10", "11", "12", "13", "14", "15", "16", "17",
191 "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
192 "20", "21", "22", "23", "24", "25", "26", "27",
193 "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
194 "30", "31", "32", "33", "34", "35", "36", "37",
195 "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
196 "40", "41", "42", "43", "44", "45", "46", "47",
197 "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
198 "50", "51", "52", "53", "54", "55", "56", "57",
199 "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
200 "60", "61", "62", "63", "64", "65", "66", "67",
201 "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
202 "70", "71", "72", "73", "74", "75", "76", "77",
203 "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
204 "80", "81", "82", "83", "84", "85", "86", "87",
205 "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
206 "90", "91", "92", "93", "94", "95", "96", "97",
207 "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
208 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
209 "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
210 "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
211 "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
212 "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7",
213 "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
214 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
215 "d8", "d9", "da", "db", "dc", "dd", "de", "df",
216 "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7",
217 "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
218 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
219 "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
222 static unsigned int hexvalues[256]; /* for parsing hex input */
224 static int original_umask = 0; /* for restoring */
228 * private utility procedures
232 copystring(const char *src)
237 if (!src) return NULL;
240 cp = malloc (len + 1);
247 binaryEqual(const char *a, const char *b, unsigned len)
256 prefix(const char *fn, int n)
258 fprintf (stderr, "%s: %s:%d: ", ProgramName, fn, n);
262 badcommandline(const char *cmd)
264 fprintf (stderr, "bad \"%s\" command line\n", cmd);
272 for ( ; *s && isascii(*s) && isspace(*s); s++)
279 skip_nonspace(char *s)
283 /* put quoting into loop if need be */
284 for ( ; *s && isascii(*s) && !isspace(*s); s++)
291 split_into_words(char *src, int *argcp)
299 #define WORDSTOALLOC 4 /* most lines are short */
300 argv = (char **) malloc (WORDSTOALLOC * sizeof (char *));
301 if (!argv) return NULL;
303 total = WORDSTOALLOC;
306 * split the line up into separate, nul-terminated tokens; the last
307 * "token" will point to the empty string so that it can be bashed into
312 jword = skip_space (src);
313 src = skip_nonspace (jword);
317 total += WORDSTOALLOC;
318 argv = (char **) realloc (argv, total * sizeof (char *));
319 if (!argv) return NULL;
322 if (savec) src++; /* if not last on line advance */
323 } while (jword != src);
325 argv[--cur] = NULL; /* smash empty token to end list */
332 open_file(char **filenamep, char *mode, Bool *usedstdp, char *srcfn, int srcln, char *cmd)
336 if (strcmp (*filenamep, "-") == 0) {
338 /* select std descriptor to use */
339 if (mode[0] == 'r') {
340 if (okay_to_use_stdin) {
341 okay_to_use_stdin = False;
342 *filenamep = stdin_filename;
345 prefix (srcfn, srcln);
346 fprintf (stderr, "%s: stdin already in use\n", cmd);
350 *filenamep = stdout_filename;
351 return stdout; /* always okay to use stdout */
355 fp = fopen (*filenamep, mode);
357 prefix (srcfn, srcln);
358 fprintf (stderr, "%s: unable to open file %s\n", cmd, *filenamep);
365 read_auth_entries(FILE *fp, _tt_AuthFileEntryList **headp,
366 _tt_AuthFileEntryList **tailp)
368 _tt_AuthFileEntry *entry;
369 _tt_AuthFileEntryList *head, *tail;
374 /* put all records into linked list */
375 while ((entry = tt_ReadAuthFileEntry (fp)) != NULL) {
376 _tt_AuthFileEntryList *l =
377 (_tt_AuthFileEntryList *) malloc (sizeof (_tt_AuthFileEntryList));
380 "%s: unable to alloc entry reading auth file\n",
386 if (tail) /* if not first time through append */
389 head = l; /* first time through, so assign */
398 /* turn hex key string into octets */
400 cvthexkey(char *hexstr, char **ptrp)
410 for (s = hexstr; *s; s++) {
411 if (!isascii(*s)) return -1;
412 if (isspace(*s)) continue;
413 if (!isxdigit(*s)) return -1;
417 /* if odd then there was an error */
418 if ((len & 1) == 1) return -1;
421 /* now we know that the input is good */
423 retval = malloc (len);
425 fprintf (stderr, "%s: unable to allocate %d bytes for hexkey\n",
430 for (us = (unsigned char *) retval, i = len; i > 0; hexstr++) {
432 if (isspace(c)) continue; /* already know it is ascii */
436 #define atoh(c) ((c) - (((c) >= '0' && (c) <= '9') ? '0' : ('a'-10)))
437 *us = (unsigned char)((atoh(savec) << 4) + atoh(c));
439 savec = 0; /* ready for next character */
451 dispatch_command(char *inputfilename, int lineno, int argc, char **argv,
452 CommandTable *tab, int *statusp)
457 /* scan table for command */
460 for (ct = tab; ct->name; ct++) {
461 /* look for unique prefix */
462 if (n >= ct->minlen && n <= ct->maxlen &&
463 strncmp (cmd, ct->name, n) == 0) {
464 *statusp = (*(ct->processfunc))(inputfilename, lineno, argc, argv);
474 static _tt_AuthFileEntryList *ttauth_head = NULL; /* list of auth entries */
475 static Bool ttauth_existed = False; /* if was present at initialize */
476 static Bool ttauth_modified = False; /* if added, removed, or merged */
477 static Bool ttauth_allowed = True; /* if allowed to write auth file */
478 static char *ttauth_filename = NULL;
479 static Bool dieing = False;
481 #ifdef SIGNALRETURNSINT
482 #define _signal_t int
484 #define _signal_t void
492 exit (auth_finalize ());
494 #ifdef SIGNALRETURNSINT
495 return -1; /* for picky compilers */
503 if (sig > 0) signal (sig, die); /* re-establish signal handler */
505 if (verbose && ttauth_modified) printf ("\r\n");
508 #ifdef SIGNALRETURNSINT
509 return -1; /* for picky compilers */
514 register_signals(void)
516 signal (SIGINT, catchsig);
517 signal (SIGTERM, catchsig);
519 signal (SIGHUP, catchsig);
526 * public procedures for parsing lines of input
530 auth_initialize(char *authfilename)
533 _tt_AuthFileEntryList *head, *tail;
539 bzero ((char *) hexvalues, sizeof hexvalues);
550 hexvalues['a'] = hexvalues['A'] = 0xa;
551 hexvalues['b'] = hexvalues['B'] = 0xb;
552 hexvalues['c'] = hexvalues['C'] = 0xc;
553 hexvalues['d'] = hexvalues['D'] = 0xd;
554 hexvalues['e'] = hexvalues['E'] = 0xe;
555 hexvalues['f'] = hexvalues['F'] = 0xf;
557 if (break_locks && verbose) {
558 printf ("Attempting to break locks on authority file %s\n",
563 if (break_locks) tt_UnlockAuthFile (authfilename);
565 n = tt_LockAuthFile (authfilename, TTAUTH_DEFAULT_RETRIES,
566 TTAUTH_DEFAULT_TIMEOUT,
567 (break_locks ? 0L : TTAUTH_DEFAULT_DEADTIME));
568 if (n != _tt_AuthLockSuccess) {
569 char *reason = "unknown error";
571 case _tt_AuthLockError:
574 case _tt_AuthLockTimeout:
578 fprintf (stderr, "%s: %s in locking authority file %s\n",
579 ProgramName, reason, authfilename);
584 /* these checks can only be done reliably after the file is locked */
585 exists = (access (authfilename, F_OK) == 0);
586 if (exists && access (authfilename, W_OK) != 0) {
588 "%s: %s not writable, changes will be ignored\n",
589 ProgramName, authfilename);
590 ttauth_allowed = False;
593 original_umask = umask (0077); /* disallow non-owner access */
595 authfp = fopen (authfilename, "rb");
597 int olderrno = errno;
599 /* if file there then error */
600 if (access (authfilename, F_OK) == 0) { /* then file does exist! */
603 } /* else ignore it */
605 "%s: creating new authority file %s\n",
606 ProgramName, authfilename);
608 ttauth_existed = True;
609 n = read_auth_entries (authfp, &head, &tail);
610 (void) fclose (authfp);
613 "%s: unable to read auth entries from file \"%s\"\n",
614 ProgramName, authfilename);
620 n = strlen (authfilename);
621 ttauth_filename = malloc (n + 1);
622 if (ttauth_filename) strcpy (ttauth_filename, authfilename);
623 ttauth_modified = False;
626 printf ("%s authority file %s\n",
627 ignore_locks ? "Ignoring locks on" : "Using", authfilename);
633 write_auth_file(char *tmp_nam)
636 _tt_AuthFileEntryList *list;
638 strcpy (tmp_nam, ttauth_filename);
639 strcat (tmp_nam, "-n"); /* for new */
640 (void) unlink (tmp_nam);
641 fp = fopen (tmp_nam, "wb"); /* umask is still set to 0077 */
643 fprintf (stderr, "%s: unable to open tmp file \"%s\"\n",
644 ProgramName, tmp_nam);
648 for (list = ttauth_head; list; list = list->next)
649 tt_WriteAuthFileEntry (fp, list->entry);
658 char temp_name[1024]; /* large filename size */
660 if (ttauth_modified) {
663 printf ("Aborting changes to authority file %s\n",
666 } else if (!ttauth_allowed) {
668 "%s: %s not writable, changes ignored\n",
669 ProgramName, ttauth_filename);
672 printf ("%s authority file %s\n",
673 ignore_locks ? "Ignoring locks and writing" :
674 "Writing", ttauth_filename);
677 if (write_auth_file (temp_name) == -1) {
679 "%s: unable to write authority file %s\n",
680 ProgramName, temp_name);
682 (void) unlink (ttauth_filename);
684 if (rename(temp_name, ttauth_filename) == -1)
686 if (link (temp_name, ttauth_filename) == -1)
690 "%s: unable to link authority file %s, use %s\n",
691 ProgramName, ttauth_filename, temp_name);
693 (void) unlink (temp_name);
700 tt_UnlockAuthFile (ttauth_filename);
702 (void) umask (original_umask);
707 process_command(char *inputfilename, int lineno, int argc, char **argv)
711 if (argc < 1 || !argv || !argv[0]) return 1;
713 if (dispatch_command (inputfilename, lineno, argc, argv,
714 command_table, &status))
717 prefix (inputfilename, lineno);
718 fprintf (stderr, "unknown command \"%s\"\n", argv[0]);
728 fprintfhex(FILE *fp, unsigned len, const char *cp)
730 const unsigned char *ucp = (const unsigned char *) cp;
732 for (; len > 0; len--, ucp++) {
733 const char *s = hex_table[*ucp];
742 dump_entry(char *inputfilename, int lineno, _tt_AuthFileEntry *auth, char *data)
744 struct _list_data *ld = (struct _list_data *) data;
747 fprintf (fp, "%s", auth->protocol_name);
749 if (auth->protocol_data_length > 0)
750 fprintfhex (fp, auth->protocol_data_length, auth->protocol_data);
752 fprintf (fp, "\"\"");
754 fprintf (fp, "%s", auth->network_id);
756 fprintf (fp, "%s", auth->auth_name);
759 if (auth->auth_data_length == 0)
760 fprintf (fp, "\"\"");
761 else if (!strcmp(auth->auth_name, SECURERPC) ||
762 !strcmp(auth->auth_name, K5AUTH))
763 fwrite (auth->auth_data, sizeof (char), auth->auth_data_length, fp);
765 fprintfhex (fp, auth->auth_data_length, auth->auth_data);
772 extract_entry(char *inputfilename, int lineno, _tt_AuthFileEntry *auth, char *data)
774 struct _extract_data *ed = (struct _extract_data *) data;
777 ed->fp = open_file (&ed->filename, "wb",
779 inputfilename, lineno, ed->cmd);
781 prefix (inputfilename, lineno);
783 "unable to open extraction file \"%s\"\n",
788 tt_WriteAuthFileEntry (ed->fp, auth);
796 match_auth(_tt_AuthFileEntry *a, _tt_AuthFileEntry *b, int *authDataSame)
798 int match = strcmp (a->protocol_name, b->protocol_name) == 0 &&
799 strcmp (a->network_id, b->network_id) == 0 &&
800 strcmp (a->auth_name, b->auth_name) == 0;
804 *authDataSame = (a->auth_data_length == b->auth_data_length &&
805 binaryEqual (a->auth_data, b->auth_data, a->auth_data_length));
815 merge_entries(_tt_AuthFileEntryList **firstp, _tt_AuthFileEntryList *second,
816 int *nnewp, int *nreplp, int *ndupp)
818 _tt_AuthFileEntryList *a, *b, *first, *tail;
819 int n = 0, nnew = 0, nrepl = 0, ndup = 0;
821 if (!second) return 0;
823 if (!*firstp) { /* if nothing to merge into */
825 for (tail = *firstp, n = 1; tail->next; n++, tail = tail->next) ;
834 * find end of first list and stick second list on it
836 for (tail = first; tail->next; tail = tail->next) ;
840 * run down list freeing duplicate entries; if an entry is okay, then
841 * bump the tail up to include it, otherwise, cut the entry out of
844 for (b = second; b; ) {
845 _tt_AuthFileEntryList *next = b->next; /* in case we free it */
852 if (match_auth (a->entry, b->entry, &authDataSame)) {
855 /* found a complete duplicate, ignore */
861 /* found a duplicate, but auth data differs */
863 _tt_AuthFileEntryList tmp; /* swap it in for old one */
868 tt_FreeAuthFileEntry (b->entry);
877 if (a == tail) break; /* if have looked at left side */
880 if (!duplicate && b) { /* if we didn't remove it */
881 tail = b; /* bump end of first list */
903 search_and_do(char *inputfilename, int lineno, int start,
904 int argc, char *argv[], int (*do_func)(), char *data)
909 _tt_AuthFileEntryList *l, *next;
910 char *protoname, *protodata, *netid, *authname;
912 for (l = ttauth_head; l; l = next)
916 protoname = protodata = netid = authname = NULL;
918 for (i = start; i < argc; i++)
920 if (!strncmp ("protoname=", argv[i], 10))
921 protoname = argv[i] + 10;
922 else if (!strncmp ("protodata=", argv[i], 10))
923 protodata = argv[i] + 10;
924 else if (!strncmp ("netid=", argv[i], 6))
926 else if (!strncmp ("authname=", argv[i], 9))
927 authname = argv[i] + 9;
932 if (protoname || protodata || netid || authname)
934 if (protoname && strcmp (protoname, l->entry->protocol_name))
937 if (protodata && !binaryEqual (protodata,
938 l->entry->protocol_data, l->entry->protocol_data_length))
941 if (netid && strcmp (netid, l->entry->network_id))
944 if (authname && strcmp (authname, l->entry->auth_name))
947 status = (*do_func) (inputfilename, lineno, l->entry, data);
955 errors -= status; /* since status is negative */
963 remove_entry(char *inputfilename, int lineno, _tt_AuthFileEntry *entry, char *data)
965 int *nremovedp = (int *) data;
966 _tt_AuthFileEntryList **listp = &ttauth_head;
967 _tt_AuthFileEntryList *list;
970 * unlink the auth we were asked to
972 while ((list = *listp)->entry != entry)
975 tt_FreeAuthFileEntry (list->entry); /* free the auth */
976 free (list); /* free the link */
977 ttauth_modified = True;
990 print_help(FILE *fp, const char *cmd)
996 if (!cmd) { /* if no cmd, print all help */
997 for (ct = command_table; ct->name; ct++) {
998 fprintf (fp, "%s\n\n", ct->helptext);
1002 int len = strlen (cmd);
1003 for (ct = command_table; ct->name; ct++) {
1004 if (strncmp (cmd, ct->name, len) == 0) {
1005 fprintf (fp, "%s\n\n", ct->helptext);
1015 do_help(char *inputfilename, int lineno, int argc, char *argv[])
1017 char *cmd = (argc > 1 ? argv[1] : NULL);
1020 n = print_help (stdout, cmd);
1022 if (n < 0 || (n == 0 && !cmd)) {
1023 prefix (inputfilename, lineno);
1024 fprintf (stderr, "internal error with help");
1026 fprintf (stderr, " on command \"%s\"", cmd);
1028 fprintf (stderr, "\n");
1033 prefix (inputfilename, lineno);
1034 /* already know that cmd is set in this case */
1035 fprintf (stderr, "no help for noexistent command \"%s\"\n", cmd);
1046 do_questionmark(char *inputfilename, int lineno, int argc, char *argv[])
1050 #define WIDEST_COLUMN 72
1051 int col = WIDEST_COLUMN;
1053 printf ("Commands:\n");
1054 for (ct = command_table; ct->name; ct++) {
1055 if ((col + ct->maxlen) > WIDEST_COLUMN) {
1056 if (ct != command_table) {
1057 putc ('\n', stdout);
1059 fputs (" ", stdout);
1060 col = 8; /* length of string above */
1062 fputs (ct->name, stdout);
1064 for (i = ct->maxlen; i < COMMAND_NAMES_PADDED_WIDTH; i++) {
1070 putc ('\n', stdout);
1073 /* allow bad lines since this is help */
1078 * list [displayname ...]
1081 do_list(char *inputfilename, int lineno, int argc, char *argv[])
1083 struct _list_data ld;
1088 register _tt_AuthFileEntryList *l;
1091 for (l = ttauth_head; l; l = l->next) {
1092 dump_entry (inputfilename, lineno, l->entry, (char *) &ld);
1099 return (search_and_do (inputfilename, lineno, 1, argc, argv,
1100 dump_entry, (char *) &ld));
1105 * merge filename [filename ...]
1108 do_merge(char *inputfilename, int lineno, int argc, char *argv[])
1112 _tt_AuthFileEntryList *head, *tail, *listhead, *listtail;
1113 int nentries, nnew, nrepl, ndup;
1116 prefix (inputfilename, lineno);
1117 badcommandline (argv[0]);
1121 listhead = listtail = NULL;
1123 for (i = 1; i < argc; i++) {
1124 char *filename = argv[i];
1126 Bool used_stdin = False;
1128 fp = open_file (&filename, "rb",
1129 &used_stdin, inputfilename, lineno,
1137 nentries = read_auth_entries (fp, &head, &tail);
1138 if (nentries == 0) {
1139 prefix (inputfilename, lineno);
1140 fprintf (stderr, "unable to read any entries from file \"%s\"\n",
1143 } else { /* link it in */
1144 add_to_list (listhead, listtail, head);
1147 if (!used_stdin) (void) fclose (fp);
1151 * if we have new entries, merge them in (freeing any duplicates)
1154 nentries = merge_entries (&ttauth_head, listhead,
1155 &nnew, &nrepl, &ndup);
1157 printf ("%d entries read in: %d new, %d replacement%s\n",
1158 nentries, nnew, nrepl, nrepl != 1 ? "s" : "");
1159 if (nentries > 0) ttauth_modified = True;
1166 * extract filename displayname [displayname ...]
1169 do_extract(char *inputfilename, int lineno, int argc, char *argv[])
1172 struct _extract_data ed;
1175 prefix (inputfilename, lineno);
1176 badcommandline (argv[0]);
1181 ed.filename = argv[1];
1185 errors = search_and_do (inputfilename, lineno, 2, argc, argv,
1186 extract_entry, (char *) &ed);
1190 "No matches found, authority file \"%s\" not written\n",
1194 printf ("%d entries written to \"%s\"\n",
1195 ed.nwritten, ed.filename);
1197 if (!ed.used_stdout) {
1198 (void) fclose (ed.fp);
1207 * add protoname protodata netid authname authdata
1210 do_add(char *inputfilename, int lineno, int argc, char *argv[])
1212 int n, nnew, nrepl, ndup;
1214 char *protodata_hex;
1215 char *protodata = NULL; /* not required */
1219 char *authdata = NULL;
1220 int protodata_len, authdata_len;
1221 _tt_AuthFileEntry *entry = NULL;
1222 _tt_AuthFileEntryList *list;
1225 if (argc != 6 || !argv[1] || !argv[2] ||
1226 !argv[3] || !argv[4] || !argv[5])
1228 prefix (inputfilename, lineno);
1229 badcommandline (argv[0]);
1233 protoname = argv[1];
1234 protodata_hex = argv[2];
1237 authdata_hex = argv[5];
1239 protodata_len = strlen (protodata_hex);
1240 if (protodata_len > 0)
1242 if (protodata_hex[0] == '"' && protodata_hex[protodata_len - 1] == '"')
1244 protodata = malloc (protodata_len - 1);
1247 strncpy (protodata, protodata_hex + 1, protodata_len - 2);
1251 goto add_bad_malloc;
1255 protodata_len = cvthexkey (protodata_hex, &protodata);
1256 if (protodata_len < 0)
1258 prefix (inputfilename, lineno);
1260 "protodata_hex contains odd number of or non-hex characters\n");
1267 authdata_len = strlen (authdata_hex);
1268 if (authdata_hex[0] == '"' && authdata_hex[authdata_len - 1] == '"')
1270 authdata = malloc (authdata_len - 1);
1273 strncpy (authdata, authdata_hex + 1, authdata_len - 2);
1277 goto add_bad_malloc;
1279 else if (!strcmp (protoname, SECURERPC) || !strcmp (protoname, K5AUTH))
1281 authdata = malloc (authdata_len + 1);
1283 strcpy (authdata, authdata_hex);
1285 goto add_bad_malloc;
1289 authdata_len = cvthexkey (authdata_hex, &authdata);
1290 if (authdata_len < 0)
1292 prefix (inputfilename, lineno);
1294 "authdata_hex contains odd number of or non-hex characters\n");
1301 entry = (_tt_AuthFileEntry *) malloc (sizeof (_tt_AuthFileEntry));
1304 goto add_bad_malloc;
1306 entry->protocol_name = copystring (protoname);
1307 entry->protocol_data_length = protodata_len;
1308 entry->protocol_data = protodata;
1309 /* Avoid a double free later on in the event of an error */
1311 entry->network_id = copystring (netid);
1312 entry->auth_name = copystring (authname);
1313 entry->auth_data_length = authdata_len;
1314 entry->auth_data = authdata;
1315 /* Avoid a double free later on in the event of an error */
1318 if (!entry->protocol_name ||
1319 (!entry->protocol_data && entry->protocol_data_length > 0) ||
1320 !entry->network_id || !entry->auth_name ||
1321 (!entry->auth_data && entry->auth_data_length > 0))
1323 goto add_bad_malloc;
1326 list = (_tt_AuthFileEntryList *) malloc (sizeof (_tt_AuthFileEntryList));
1329 goto add_bad_malloc;
1332 list->entry = entry;
1335 * merge it in; note that merge will deal with allocation
1338 n = merge_entries (&ttauth_head, list, &nnew, &nrepl, &ndup);
1341 ttauth_modified = True;
1344 prefix (inputfilename, lineno);
1348 fprintf (stderr, "no records added - all duplicate\n");
1353 fprintf (stderr, "unable to merge in added record\n");
1364 prefix (inputfilename, lineno);
1365 fprintf (stderr, "unable to allocate memory to add an entry\n");
1375 if (entry->protocol_name)
1376 free (entry->protocol_name);
1377 if (entry->protocol_data)
1378 free (entry->protocol_data);
1379 if (entry->network_id)
1380 free (entry->network_id);
1381 if (entry->auth_name)
1382 free (entry->auth_name);
1383 if (entry->auth_data)
1384 free (entry->auth_data);
1385 free ((char *) entry);
1392 * remove displayname
1395 do_remove(char *inputfilename, int lineno, int argc, char *argv[])
1401 prefix (inputfilename, lineno);
1402 badcommandline (argv[0]);
1406 errors = search_and_do (inputfilename, lineno, 1, argc, argv,
1407 remove_entry, (char *) &nremoved);
1408 if (verbose) printf ("%d entries removed\n", nremoved);
1416 do_info(char *inputfilename, int lineno, int argc, char *argv[])
1419 _tt_AuthFileEntryList *l;
1422 prefix (inputfilename, lineno);
1423 badcommandline (argv[0]);
1427 for (l = ttauth_head, n = 0; l; l = l->next, n++) ;
1429 printf ("Authority file: %s\n",
1430 ttauth_filename ? ttauth_filename : "(none)");
1431 printf ("File new: %s\n", ttauth_existed ? No : Yes);
1432 printf ("File locked: %s\n", ignore_locks ? No : Yes);
1433 printf ("Number of entries: %d\n", n);
1434 printf ("Changes honored: %s\n", ttauth_allowed ? Yes : No);
1435 printf ("Changes made: %s\n", ttauth_modified ? Yes : No);
1436 printf ("Current input: %s:%d\n", inputfilename, lineno);
1444 static Bool alldone = False;
1448 do_exit(char *inputfilename, int lineno, int argc, char *argv[])
1450 /* allow bogus stuff */
1460 do_quit(char *inputfilename, int lineno, int argc, char *argv[])
1462 /* allow bogus stuff */
1465 return -1; /* for picky compilers */
1473 do_source(char *inputfilename, int lineno, int argc, char *argv[])
1478 Bool used_stdin = False;
1480 int errors = 0, status;
1484 Bool prompt = False; /* only true if reading from tty */
1486 if (argc != 2 || !argv[1]) {
1487 prefix (inputfilename, lineno);
1488 badcommandline (argv[0]);
1494 fp = open_file (&script, "r", &used_stdin, inputfilename, lineno, argv[0]);
1499 if (verbose && used_stdin && isatty (fileno (fp))) prompt = True;
1504 printf ("ttauth> ");
1507 if (fgets (buf, sizeof buf, fp) == NULL) break;
1510 if (len == 0 || buf[0] == '#') continue;
1511 if (buf[len-1] != '\n') {
1512 prefix (script, sublineno);
1513 fprintf (stderr, "line too long\n");
1517 buf[--len] = '\0'; /* remove new line */
1518 subargv = split_into_words (buf, &subargc);
1520 status = process_command (script, sublineno, subargc, subargv);
1521 free ((char *) subargv);
1524 prefix (script, sublineno);
1525 fprintf (stderr, "unable to break line into words\n");