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 librararies 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
56 #include "api/c/api_auth.h"
57 #include "api/c/tt_c.h"
61 #define SECURERPC "SUN-DES-1"
62 #define K5AUTH "KERBEROS-V5-1"
64 #define TTAUTH_DEFAULT_RETRIES 10 /* number of competitors we expect */
65 #define TTAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */
66 #define TTAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */
68 #define add_to_list(h,t,e) {if (t) (t)->next = (e); else (h) = (e); (t) = (e);}
70 typedef struct _CommandTable { /* commands that are understood */
71 char *name; /* full name */
72 int minlen; /* unique prefix */
73 int maxlen; /* strlen(name) */
74 int (*processfunc)(); /* handler */
75 char *helptext; /* what to print for help */
78 struct _extract_data { /* for iterating */
79 FILE *fp; /* input source */
80 char *filename; /* name of input */
81 Bool used_stdout; /* whether or not need to close */
82 int nwritten; /* number of entries written */
83 char *cmd; /* for error messages */
86 struct _list_data { /* for iterating */
87 FILE *fp; /* output file */
94 static char *stdin_filename = "(stdin)"; /* for messages */
95 static char *stdout_filename = "(stdout)"; /* for messages */
96 static char *Yes = "yes"; /* for messages */
97 static char *No = "no"; /* for messages */
99 static int do_list(), do_merge(), do_extract(), do_add(), do_remove();
100 static int do_help(), do_source(), do_info(), do_exit();
101 static int do_quit(), do_questionmark();
103 static CommandTable command_table[] = { /* table of known commands */
104 { "add", 2, 3, do_add,
107 add protoname protodata netid authname authdata"
110 { "exit", 3, 4, do_exit,
112 exit save changes and exit program"
115 { "extract", 3, 7, do_extract,
117 extract extract entries into file\n\
118 extract filename <protoname=$> <protodata=$> <netid=$> <authname=$>"
121 { "help", 1, 4, do_help,
127 { "info", 1, 4, do_info,
129 info print information about entries"
132 { "list", 1, 4, do_list,
135 list <protoname=$> <protodata=$> <netid=$> <authname=$>"
138 { "merge", 1, 5, do_merge,
140 merge merge entries from files\n\
141 merge filename1 <filename2> <filename3> ..."
144 { "quit", 1, 4, do_quit,
146 quit abort changes and exit program" },
148 { "remove", 1, 6, do_remove,
150 remove remove entries\n\
151 remove <protoname=$> <protodata=$> <netid=$> <authname=$>"
154 { "source", 1, 6, do_source,
156 source read commands from file\n\
160 { "?", 1, 1, do_questionmark,
162 ? list available commands" },
164 { NULL, 0, 0, NULL, NULL },
167 #define COMMAND_NAMES_PADDED_WIDTH 10 /* wider than anything above */
170 static Bool okay_to_use_stdin = True; /* set to false after using */
172 static char *hex_table[] = { /* for printing hex digits */
173 "00", "01", "02", "03", "04", "05", "06", "07",
174 "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
175 "10", "11", "12", "13", "14", "15", "16", "17",
176 "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
177 "20", "21", "22", "23", "24", "25", "26", "27",
178 "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
179 "30", "31", "32", "33", "34", "35", "36", "37",
180 "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
181 "40", "41", "42", "43", "44", "45", "46", "47",
182 "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
183 "50", "51", "52", "53", "54", "55", "56", "57",
184 "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
185 "60", "61", "62", "63", "64", "65", "66", "67",
186 "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
187 "70", "71", "72", "73", "74", "75", "76", "77",
188 "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
189 "80", "81", "82", "83", "84", "85", "86", "87",
190 "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
191 "90", "91", "92", "93", "94", "95", "96", "97",
192 "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
193 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
194 "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
195 "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
196 "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
197 "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7",
198 "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
199 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
200 "d8", "d9", "da", "db", "dc", "dd", "de", "df",
201 "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7",
202 "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
203 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
204 "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
207 static unsigned int hexvalues[256]; /* for parsing hex input */
209 static int original_umask = 0; /* for restoring */
213 * private utility procedures
216 static char *copystring (src)
219 int len = strlen (src);
222 if (!src) return NULL;
223 cp = malloc (len + 1);
230 binaryEqual (a, b, len)
232 register char *a, *b;
233 register unsigned len;
242 static void prefix (fn, n)
246 fprintf (stderr, "%s: %s:%d: ", ProgramName, fn, n);
249 static void badcommandline (cmd)
252 fprintf (stderr, "bad \"%s\" command line\n", cmd);
255 static char *skip_space (s)
260 for ( ; *s && isascii(*s) && isspace(*s); s++)
266 static char *skip_nonspace (s)
271 /* put quoting into loop if need be */
272 for ( ; *s && isascii(*s) && !isspace(*s); s++)
277 static char **split_into_words (src, argcp) /* argvify string */
287 #define WORDSTOALLOC 4 /* most lines are short */
288 argv = (char **) malloc (WORDSTOALLOC * sizeof (char *));
289 if (!argv) return NULL;
291 total = WORDSTOALLOC;
294 * split the line up into separate, nul-terminated tokens; the last
295 * "token" will point to the empty string so that it can be bashed into
300 jword = skip_space (src);
301 src = skip_nonspace (jword);
305 total += WORDSTOALLOC;
306 argv = (char **) realloc (argv, total * sizeof (char *));
307 if (!argv) return NULL;
310 if (savec) src++; /* if not last on line advance */
311 } while (jword != src);
313 argv[--cur] = NULL; /* smash empty token to end list */
319 static FILE *open_file (filenamep, mode, usedstdp, srcfn, srcln, cmd)
329 if (strcmp (*filenamep, "-") == 0) {
331 /* select std descriptor to use */
332 if (mode[0] == 'r') {
333 if (okay_to_use_stdin) {
334 okay_to_use_stdin = False;
335 *filenamep = stdin_filename;
338 prefix (srcfn, srcln);
339 fprintf (stderr, "%s: stdin already in use\n", cmd);
343 *filenamep = stdout_filename;
344 return stdout; /* always okay to use stdout */
348 fp = fopen (*filenamep, mode);
350 prefix (srcfn, srcln);
351 fprintf (stderr, "%s: unable to open file %s\n", cmd, *filenamep);
357 static int read_auth_entries (fp, headp, tailp)
359 _tt_AuthFileEntryList **headp, **tailp;
361 _tt_AuthFileEntry *entry;
362 _tt_AuthFileEntryList *head, *tail;
367 /* put all records into linked list */
368 while ((entry = tt_ReadAuthFileEntry (fp)) != NULL) {
369 _tt_AuthFileEntryList *l =
370 (_tt_AuthFileEntryList *) malloc (sizeof (_tt_AuthFileEntryList));
373 "%s: unable to alloc entry reading auth file\n",
379 if (tail) /* if not first time through append */
382 head = l; /* first time through, so assign */
392 static int cvthexkey (hexstr, ptrp) /* turn hex key string into octets */
404 for (s = hexstr; *s; s++) {
405 if (!isascii(*s)) return -1;
406 if (isspace(*s)) continue;
407 if (!isxdigit(*s)) return -1;
411 /* if odd then there was an error */
412 if ((len & 1) == 1) return -1;
415 /* now we know that the input is good */
417 retval = malloc (len);
419 fprintf (stderr, "%s: unable to allocate %d bytes for hexkey\n",
424 for (us = (unsigned char *) retval, i = len; i > 0; hexstr++) {
426 if (isspace(c)) continue; /* already know it is ascii */
430 #define atoh(c) ((c) - (((c) >= '0' && (c) <= '9') ? '0' : ('a'-10)))
431 *us = (unsigned char)((atoh(savec) << 4) + atoh(c));
433 savec = 0; /* ready for next character */
444 static int dispatch_command (inputfilename, lineno, argc, argv, tab, statusp)
455 /* scan table for command */
458 for (ct = tab; ct->name; ct++) {
459 /* look for unique prefix */
460 if (n >= ct->minlen && n <= ct->maxlen &&
461 strncmp (cmd, ct->name, n) == 0) {
462 *statusp = (*(ct->processfunc))(inputfilename, lineno, argc, argv);
472 static _tt_AuthFileEntryList *ttauth_head = NULL; /* list of auth entries */
473 static Bool ttauth_existed = False; /* if was present at initialize */
474 static Bool ttauth_modified = False; /* if added, removed, or merged */
475 static Bool ttauth_allowed = True; /* if allowed to write auth file */
476 static char *ttauth_filename = NULL;
477 static Bool dieing = False;
479 #ifdef SIGNALRETURNSINT
480 #define _signal_t int
482 #define _signal_t void
486 static _signal_t die (sig)
490 exit (auth_finalize ());
492 #ifdef SIGNALRETURNSINT
493 return -1; /* for picky compilers */
497 static _signal_t catchsig (sig)
501 if (sig > 0) signal (sig, die); /* re-establish signal handler */
503 if (verbose && ttauth_modified) printf ("\r\n");
506 #ifdef SIGNALRETURNSINT
507 return -1; /* for picky compilers */
511 static void register_signals ()
513 signal (SIGINT, catchsig);
514 signal (SIGTERM, catchsig);
516 signal (SIGHUP, catchsig);
523 * public procedures for parsing lines of input
526 int auth_initialize (authfilename)
530 _tt_AuthFileEntryList *head, *tail;
536 bzero ((char *) hexvalues, sizeof hexvalues);
547 hexvalues['a'] = hexvalues['A'] = 0xa;
548 hexvalues['b'] = hexvalues['B'] = 0xb;
549 hexvalues['c'] = hexvalues['C'] = 0xc;
550 hexvalues['d'] = hexvalues['D'] = 0xd;
551 hexvalues['e'] = hexvalues['E'] = 0xe;
552 hexvalues['f'] = hexvalues['F'] = 0xf;
554 if (break_locks && verbose) {
555 printf ("Attempting to break locks on authority file %s\n",
560 if (break_locks) tt_UnlockAuthFile (authfilename);
562 n = tt_LockAuthFile (authfilename, TTAUTH_DEFAULT_RETRIES,
563 TTAUTH_DEFAULT_TIMEOUT,
564 (break_locks ? 0L : TTAUTH_DEFAULT_DEADTIME));
565 if (n != _tt_AuthLockSuccess) {
566 char *reason = "unknown error";
568 case _tt_AuthLockError:
571 case _tt_AuthLockTimeout:
575 fprintf (stderr, "%s: %s in locking authority file %s\n",
576 ProgramName, reason, authfilename);
581 /* these checks can only be done reliably after the file is locked */
582 exists = (access (authfilename, F_OK) == 0);
583 if (exists && access (authfilename, W_OK) != 0) {
585 "%s: %s not writable, changes will be ignored\n",
586 ProgramName, authfilename);
587 ttauth_allowed = False;
590 original_umask = umask (0077); /* disallow non-owner access */
592 authfp = fopen (authfilename, "rb");
594 int olderrno = errno;
596 /* if file there then error */
597 if (access (authfilename, F_OK) == 0) { /* then file does exist! */
600 } /* else ignore it */
602 "%s: creating new authority file %s\n",
603 ProgramName, authfilename);
605 ttauth_existed = True;
606 n = read_auth_entries (authfp, &head, &tail);
607 (void) fclose (authfp);
610 "%s: unable to read auth entries from file \"%s\"\n",
611 ProgramName, authfilename);
617 n = strlen (authfilename);
618 ttauth_filename = malloc (n + 1);
619 if (ttauth_filename) strcpy (ttauth_filename, authfilename);
620 ttauth_modified = False;
623 printf ("%s authority file %s\n",
624 ignore_locks ? "Ignoring locks on" : "Using", authfilename);
629 static int write_auth_file (tmp_nam)
633 _tt_AuthFileEntryList *list;
635 strcpy (tmp_nam, ttauth_filename);
636 strcat (tmp_nam, "-n"); /* for new */
637 (void) unlink (tmp_nam);
638 fp = fopen (tmp_nam, "wb"); /* umask is still set to 0077 */
640 fprintf (stderr, "%s: unable to open tmp file \"%s\"\n",
641 ProgramName, tmp_nam);
645 for (list = ttauth_head; list; list = list->next)
646 tt_WriteAuthFileEntry (fp, list->entry);
654 char temp_name[1024]; /* large filename size */
656 if (ttauth_modified) {
659 printf ("Aborting changes to authority file %s\n",
662 } else if (!ttauth_allowed) {
664 "%s: %s not writable, changes ignored\n",
665 ProgramName, ttauth_filename);
668 printf ("%s authority file %s\n",
669 ignore_locks ? "Ignoring locks and writing" :
670 "Writing", ttauth_filename);
673 if (write_auth_file (temp_name) == -1) {
675 "%s: unable to write authority file %s\n",
676 ProgramName, temp_name);
678 (void) unlink (ttauth_filename);
680 if (rename(temp_name, ttauth_filename) == -1)
682 if (link (temp_name, ttauth_filename) == -1)
686 "%s: unable to link authority file %s, use %s\n",
687 ProgramName, ttauth_filename, temp_name);
689 (void) unlink (temp_name);
696 tt_UnlockAuthFile (ttauth_filename);
698 (void) umask (original_umask);
702 int process_command (inputfilename, lineno, argc, argv)
710 if (argc < 1 || !argv || !argv[0]) return 1;
712 if (dispatch_command (inputfilename, lineno, argc, argv,
713 command_table, &status))
716 prefix (inputfilename, lineno);
717 fprintf (stderr, "unknown command \"%s\"\n", argv[0]);
726 static void fprintfhex (fp, len, cp)
731 unsigned char *ucp = (unsigned char *) cp;
733 for (; len > 0; len--, ucp++) {
734 register char *s = hex_table[*ucp];
742 static int dump_entry (inputfilename, lineno, auth, data)
745 _tt_AuthFileEntry *auth;
748 struct _list_data *ld = (struct _list_data *) data;
751 fprintf (fp, "%s", auth->protocol_name);
753 if (auth->protocol_data_length > 0)
754 fprintfhex (fp, auth->protocol_data_length, auth->protocol_data);
756 fprintf (fp, "\"\"");
758 fprintf (fp, "%s", auth->network_id);
760 fprintf (fp, "%s", auth->auth_name);
763 if (auth->auth_data_length == 0)
764 fprintf (fp, "\"\"");
765 else if (!strcmp(auth->auth_name, SECURERPC) ||
766 !strcmp(auth->auth_name, K5AUTH))
767 fwrite (auth->auth_data, sizeof (char), auth->auth_data_length, fp);
769 fprintfhex (fp, auth->auth_data_length, auth->auth_data);
775 static int extract_entry (inputfilename, lineno, auth, data)
778 _tt_AuthFileEntry *auth;
781 struct _extract_data *ed = (struct _extract_data *) data;
784 ed->fp = open_file (&ed->filename, "wb",
786 inputfilename, lineno, ed->cmd);
788 prefix (inputfilename, lineno);
790 "unable to open extraction file \"%s\"\n",
795 tt_WriteAuthFileEntry (ed->fp, auth);
802 static int match_auth (a, b, authDataSame)
803 register _tt_AuthFileEntry *a, *b;
806 int match = strcmp (a->protocol_name, b->protocol_name) == 0 &&
807 strcmp (a->network_id, b->network_id) == 0 &&
808 strcmp (a->auth_name, b->auth_name) == 0;
812 *authDataSame = (a->auth_data_length == b->auth_data_length &&
813 binaryEqual (a->auth_data, b->auth_data, a->auth_data_length));
822 static int merge_entries (firstp, second, nnewp, nreplp, ndupp)
823 _tt_AuthFileEntryList **firstp, *second;
824 int *nnewp, *nreplp, *ndupp;
826 _tt_AuthFileEntryList *a, *b, *first, *tail;
827 int n = 0, nnew = 0, nrepl = 0, ndup = 0;
829 if (!second) return 0;
831 if (!*firstp) { /* if nothing to merge into */
833 for (tail = *firstp, n = 1; tail->next; n++, tail = tail->next) ;
842 * find end of first list and stick second list on it
844 for (tail = first; tail->next; tail = tail->next) ;
848 * run down list freeing duplicate entries; if an entry is okay, then
849 * bump the tail up to include it, otherwise, cut the entry out of
852 for (b = second; b; ) {
853 _tt_AuthFileEntryList *next = b->next; /* in case we free it */
860 if (match_auth (a->entry, b->entry, &authDataSame)) {
863 /* found a complete duplicate, ignore */
869 /* found a duplicate, but auth data differs */
871 _tt_AuthFileEntryList tmp; /* swap it in for old one */
876 tt_FreeAuthFileEntry (b->entry);
885 if (a == tail) break; /* if have looked at left side */
888 if (!duplicate && b) { /* if we didn't remove it */
889 tail = b; /* bump end of first list */
910 static int search_and_do (inputfilename, lineno, start,
911 argc, argv, do_func, data)
923 _tt_AuthFileEntryList *l, *next;
924 char *protoname, *protodata, *netid, *authname;
926 for (l = ttauth_head; l; l = next)
930 protoname = protodata = netid = authname = NULL;
932 for (i = start; i < argc; i++)
934 if (!strncmp ("protoname=", argv[i], 10))
935 protoname = argv[i] + 10;
936 else if (!strncmp ("protodata=", argv[i], 10))
937 protodata = argv[i] + 10;
938 else if (!strncmp ("netid=", argv[i], 6))
940 else if (!strncmp ("authname=", argv[i], 9))
941 authname = argv[i] + 9;
946 if (protoname || protodata || netid || authname)
948 if (protoname && strcmp (protoname, l->entry->protocol_name))
951 if (protodata && !binaryEqual (protodata,
952 l->entry->protocol_data, l->entry->protocol_data_length))
955 if (netid && strcmp (netid, l->entry->network_id))
958 if (authname && strcmp (authname, l->entry->auth_name))
961 status = (*do_func) (inputfilename, lineno, l->entry, data);
969 errors -= status; /* since status is negative */
976 static int remove_entry (inputfilename, lineno, entry, data)
979 _tt_AuthFileEntry *entry;
982 int *nremovedp = (int *) data;
983 _tt_AuthFileEntryList **listp = &ttauth_head;
984 _tt_AuthFileEntryList *list;
987 * unlink the auth we were asked to
989 while ((list = *listp)->entry != entry)
992 tt_FreeAuthFileEntry (list->entry); /* free the auth */
993 free (list); /* free the link */
994 ttauth_modified = True;
1006 int print_help (fp, cmd)
1014 if (!cmd) { /* if no cmd, print all help */
1015 for (ct = command_table; ct->name; ct++) {
1016 fprintf (fp, "%s\n\n", ct->helptext);
1020 int len = strlen (cmd);
1021 for (ct = command_table; ct->name; ct++) {
1022 if (strncmp (cmd, ct->name, len) == 0) {
1023 fprintf (fp, "%s\n\n", ct->helptext);
1032 static int do_help (inputfilename, lineno, argc, argv)
1033 char *inputfilename;
1038 char *cmd = (argc > 1 ? argv[1] : NULL);
1041 n = print_help (stdout, cmd);
1043 if (n < 0 || (n == 0 && !cmd)) {
1044 prefix (inputfilename, lineno);
1045 fprintf (stderr, "internal error with help");
1047 fprintf (stderr, " on command \"%s\"", cmd);
1049 fprintf (stderr, "\n");
1054 prefix (inputfilename, lineno);
1055 /* already know that cmd is set in this case */
1056 fprintf (stderr, "no help for noexistent command \"%s\"\n", cmd);
1066 static int do_questionmark (inputfilename, lineno, argc, argv)
1067 char *inputfilename;
1074 #define WIDEST_COLUMN 72
1075 int col = WIDEST_COLUMN;
1077 printf ("Commands:\n");
1078 for (ct = command_table; ct->name; ct++) {
1079 if ((col + ct->maxlen) > WIDEST_COLUMN) {
1080 if (ct != command_table) {
1081 putc ('\n', stdout);
1083 fputs (" ", stdout);
1084 col = 8; /* length of string above */
1086 fputs (ct->name, stdout);
1088 for (i = ct->maxlen; i < COMMAND_NAMES_PADDED_WIDTH; i++) {
1094 putc ('\n', stdout);
1097 /* allow bad lines since this is help */
1102 * list [displayname ...]
1104 static int do_list (inputfilename, lineno, argc, argv)
1105 char *inputfilename;
1110 struct _list_data ld;
1115 register _tt_AuthFileEntryList *l;
1118 for (l = ttauth_head; l; l = l->next) {
1119 dump_entry (inputfilename, lineno, l->entry, (char *) &ld);
1126 return (search_and_do (inputfilename, lineno, 1, argc, argv,
1127 dump_entry, (char *) &ld));
1132 * merge filename [filename ...]
1134 static int do_merge (inputfilename, lineno, argc, argv)
1135 char *inputfilename;
1142 _tt_AuthFileEntryList *head, *tail, *listhead, *listtail;
1143 int nentries, nnew, nrepl, ndup;
1146 prefix (inputfilename, lineno);
1147 badcommandline (argv[0]);
1151 listhead = listtail = NULL;
1153 for (i = 1; i < argc; i++) {
1154 char *filename = argv[i];
1156 Bool used_stdin = False;
1158 fp = open_file (&filename, "rb",
1159 &used_stdin, inputfilename, lineno,
1167 nentries = read_auth_entries (fp, &head, &tail);
1168 if (nentries == 0) {
1169 prefix (inputfilename, lineno);
1170 fprintf (stderr, "unable to read any entries from file \"%s\"\n",
1173 } else { /* link it in */
1174 add_to_list (listhead, listtail, head);
1177 if (!used_stdin) (void) fclose (fp);
1181 * if we have new entries, merge them in (freeing any duplicates)
1184 nentries = merge_entries (&ttauth_head, listhead,
1185 &nnew, &nrepl, &ndup);
1187 printf ("%d entries read in: %d new, %d replacement%s\n",
1188 nentries, nnew, nrepl, nrepl != 1 ? "s" : "");
1189 if (nentries > 0) ttauth_modified = True;
1196 * extract filename displayname [displayname ...]
1198 static int do_extract (inputfilename, lineno, argc, argv)
1199 char *inputfilename;
1205 struct _extract_data ed;
1208 prefix (inputfilename, lineno);
1209 badcommandline (argv[0]);
1214 ed.filename = argv[1];
1218 errors = search_and_do (inputfilename, lineno, 2, argc, argv,
1219 extract_entry, (char *) &ed);
1223 "No matches found, authority file \"%s\" not written\n",
1227 printf ("%d entries written to \"%s\"\n",
1228 ed.nwritten, ed.filename);
1230 if (!ed.used_stdout) {
1231 (void) fclose (ed.fp);
1240 * add protoname protodata netid authname authdata
1242 static int do_add (inputfilename, lineno, argc, argv)
1243 char *inputfilename;
1248 int n, nnew, nrepl, ndup;
1250 char *protodata_hex;
1251 char *protodata = NULL; /* not required */
1256 int protodata_len, authdata_len;
1257 _tt_AuthFileEntry *entry;
1258 _tt_AuthFileEntryList *list;
1261 if (argc != 6 || !argv[1] || !argv[2] ||
1262 !argv[3] || !argv[4] || !argv[5])
1264 prefix (inputfilename, lineno);
1265 badcommandline (argv[0]);
1269 protoname = argv[1];
1270 protodata_hex = argv[2];
1273 authdata_hex = argv[5];
1275 protodata_len = strlen (protodata_hex);
1276 if (protodata_len > 0)
1278 if (protodata_hex[0] == '"' && protodata_hex[protodata_len - 1] == '"')
1280 protodata = malloc (protodata_len - 1);
1283 strncpy (protodata, protodata_hex + 1, protodata_len - 2);
1287 goto add_bad_malloc;
1291 protodata_len = cvthexkey (protodata_hex, &protodata);
1292 if (protodata_len < 0)
1294 prefix (inputfilename, lineno);
1296 "protodata_hex contains odd number of or non-hex characters\n");
1302 authdata_len = strlen (authdata_hex);
1303 if (authdata_hex[0] == '"' && authdata_hex[authdata_len - 1] == '"')
1305 authdata = malloc (authdata_len - 1);
1308 strncpy (authdata, authdata_hex + 1, authdata_len - 2);
1312 goto add_bad_malloc;
1314 else if (!strcmp (protoname, SECURERPC) || !strcmp (protoname, K5AUTH))
1316 authdata = malloc (authdata_len + 1);
1318 strcpy (authdata, authdata_hex);
1320 goto add_bad_malloc;
1324 authdata_len = cvthexkey (authdata_hex, &authdata);
1325 if (authdata_len < 0)
1327 prefix (inputfilename, lineno);
1329 "authdata_hex contains odd number of or non-hex characters\n");
1335 entry = (_tt_AuthFileEntry *) malloc (sizeof (_tt_AuthFileEntry));
1338 goto add_bad_malloc;
1340 entry->protocol_name = copystring (protoname);
1341 entry->protocol_data_length = protodata_len;
1342 entry->protocol_data = protodata;
1343 entry->network_id = copystring (netid);
1344 entry->auth_name = copystring (authname);
1345 entry->auth_data_length = authdata_len;
1346 entry->auth_data = authdata;
1348 if (!entry->protocol_name ||
1349 (!entry->protocol_data && entry->protocol_data_length > 0) ||
1350 !entry->network_id || !entry->auth_name ||
1351 (!entry->auth_data && entry->auth_data_length > 0))
1353 goto add_bad_malloc;
1356 list = (_tt_AuthFileEntryList *) malloc (sizeof (_tt_AuthFileEntryList));
1359 goto add_bad_malloc;
1362 list->entry = entry;
1365 * merge it in; note that merge will deal with allocation
1368 n = merge_entries (&ttauth_head, list, &nnew, &nrepl, &ndup);
1371 ttauth_modified = True;
1374 prefix (inputfilename, lineno);
1378 fprintf (stderr, "no records added - all duplicate\n");
1383 fprintf (stderr, "unable to merge in added record\n");
1394 prefix (inputfilename, lineno);
1395 fprintf (stderr, "unable to allocate memory to add an entry\n");
1405 if (entry->protocol_name)
1406 free (entry->protocol_name);
1407 if (entry->protocol_data)
1408 free (entry->protocol_data);
1409 if (entry->network_id)
1410 free (entry->network_id);
1411 if (entry->auth_name)
1412 free (entry->auth_name);
1413 if (entry->auth_data)
1414 free (entry->auth_data);
1415 free ((char *) entry);
1422 * remove displayname
1424 static int do_remove (inputfilename, lineno, argc, argv)
1425 char *inputfilename;
1434 prefix (inputfilename, lineno);
1435 badcommandline (argv[0]);
1439 errors = search_and_do (inputfilename, lineno, 1, argc, argv,
1440 remove_entry, (char *) &nremoved);
1441 if (verbose) printf ("%d entries removed\n", nremoved);
1448 static int do_info (inputfilename, lineno, argc, argv)
1449 char *inputfilename;
1455 _tt_AuthFileEntryList *l;
1458 prefix (inputfilename, lineno);
1459 badcommandline (argv[0]);
1463 for (l = ttauth_head, n = 0; l; l = l->next, n++) ;
1465 printf ("Authority file: %s\n",
1466 ttauth_filename ? ttauth_filename : "(none)");
1467 printf ("File new: %s\n", ttauth_existed ? No : Yes);
1468 printf ("File locked: %s\n", ignore_locks ? No : Yes);
1469 printf ("Number of entries: %d\n", n);
1470 printf ("Changes honored: %s\n", ttauth_allowed ? Yes : No);
1471 printf ("Changes made: %s\n", ttauth_modified ? Yes : No);
1472 printf ("Current input: %s:%d\n", inputfilename, lineno);
1480 static Bool alldone = False;
1483 static int do_exit (inputfilename, lineno, argc, argv)
1484 char *inputfilename;
1489 /* allow bogus stuff */
1498 static int do_quit (inputfilename, lineno, argc, argv)
1499 char *inputfilename;
1504 /* allow bogus stuff */
1507 return -1; /* for picky compilers */
1514 static int do_source (inputfilename, lineno, argc, argv)
1515 char *inputfilename;
1523 Bool used_stdin = False;
1525 int errors = 0, status;
1529 Bool prompt = False; /* only true if reading from tty */
1531 if (argc != 2 || !argv[1]) {
1532 prefix (inputfilename, lineno);
1533 badcommandline (argv[0]);
1539 fp = open_file (&script, "r", &used_stdin, inputfilename, lineno, argv[0]);
1544 if (verbose && used_stdin && isatty (fileno (fp))) prompt = True;
1549 printf ("ttauth> ");
1552 if (fgets (buf, sizeof buf, fp) == NULL) break;
1555 if (len == 0 || buf[0] == '#') continue;
1556 if (buf[len-1] != '\n') {
1557 prefix (script, sublineno);
1558 fprintf (stderr, "line too long\n");
1562 buf[--len] = '\0'; /* remove new line */
1563 subargv = split_into_words (buf, &subargc);
1565 status = process_command (script, sublineno, subargc, subargv);
1566 free ((char *) subargv);
1569 prefix (script, sublineno);
1570 fprintf (stderr, "unable to break line into words\n");