2
* $Xorg: process.c,v 1.5 2001/02/09 02:05:31 xorgcvs Exp $
5
Copyright 1989, 1998 The Open Group
7
Permission to use, copy, modify, distribute, and sell this software and its
8
documentation for any purpose is hereby granted without fee, provided that
9
the above copyright notice appear in all copies and that both that
10
copyright notice and this permission notice appear in supporting
13
The above copyright notice and this permission notice shall be included in
14
all copies or substantial portions of the Software.
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
Except as contained in this notice, the name of The Open Group shall not be
24
used in advertising or otherwise to promote the sale, use or other dealings
25
in this Software without prior written authorization from The Open Group.
27
* Original Author of "xauth" : Jim Fulton, MIT X Consortium
28
* Modified into "iceauth" : Ralph Mor, X Consortium
31
/* $XFree86: xc/programs/iceauth/process.c,v 3.7 2001/12/14 20:00:49 dawes Exp $ */
36
#include <sys/types.h>
40
#define SECURERPC "SUN-DES-1"
41
#define K5AUTH "KERBEROS-V5-1"
43
#define ICEAUTH_DEFAULT_RETRIES 10 /* number of competitors we expect */
44
#define ICEAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */
45
#define ICEAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */
47
typedef struct _AuthList { /* linked list of entries */
48
struct _AuthList *next;
49
IceAuthFileEntry *auth;
52
#define add_to_list(h,t,e) {if (t) (t)->next = (e); else (h) = (e); (t) = (e);}
54
typedef int (*ProcessFunc)(const char *, int, int, char **);
55
typedef int (*DoFunc)(const char *, int, IceAuthFileEntry *, char *);
57
typedef struct _CommandTable { /* commands that are understood */
58
char *name; /* full name */
59
int minlen; /* unique prefix */
60
int maxlen; /* strlen(name) */
61
ProcessFunc processfunc; /* handler */
62
char *helptext; /* what to print for help */
65
struct _extract_data { /* for iterating */
66
FILE *fp; /* input source */
67
char *filename; /* name of input */
68
Bool used_stdout; /* whether or not need to close */
69
int nwritten; /* number of entries written */
70
char *cmd; /* for error messages */
73
struct _list_data { /* for iterating */
74
FILE *fp; /* output file */
81
static char *stdin_filename = "(stdin)"; /* for messages */
82
static char *stdout_filename = "(stdout)"; /* for messages */
83
static const char *Yes = "yes"; /* for messages */
84
static const char *No = "no"; /* for messages */
86
static int binaryEqual ( const char *a, const char *b, unsigned len );
87
static void prefix ( const char *fn, int n );
88
static void badcommandline ( const char *cmd );
89
static char *skip_space ( char *s );
90
static char *skip_nonspace ( char *s );
91
static char **split_into_words ( char *src, int *argcp );
92
static FILE *open_file ( char **filenamep, const char *mode, Bool *usedstdp, const char *srcfn, int srcln, const char *cmd );
93
static int read_auth_entries ( FILE *fp, AuthList **headp, AuthList **tailp );
94
static int cvthexkey ( char *hexstr, char **ptrp );
95
static int dispatch_command ( const char *inputfilename, int lineno, int argc, char **argv, const CommandTable *tab, int *statusp );
96
static void die ( int sig );
97
static void catchsig ( int sig );
98
static void register_signals ( void );
99
static int write_auth_file ( char *tmp_nam, size_t tmp_nam_len );
100
static void fprintfhex ( FILE *fp, unsigned int len, const char *cp );
101
static int dump_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, char *data );
102
static int extract_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, char *data );
103
static int match_auth ( IceAuthFileEntry *a, IceAuthFileEntry *b, int *authDataSame );
104
static int merge_entries ( AuthList **firstp, AuthList *second, int *nnewp, int *nreplp, int *ndupp );
105
static int search_and_do ( const char *inputfilename, int lineno, int start, int argc, char *argv[], DoFunc do_func, char *data );
106
static int remove_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, char *data );
107
static int do_help ( const char *inputfilename, int lineno, int argc, char **argv );
108
static int do_questionmark ( const char *inputfilename, int lineno, int argc, char **argv );
109
static int do_list ( const char *inputfilename, int lineno, int argc, char **argv );
110
static int do_merge ( const char *inputfilename, int lineno, int argc, char **argv );
111
static int do_extract ( const char *inputfilename, int lineno, int argc, char **argv );
112
static int do_add ( const char *inputfilename, int lineno, int argc, char **argv );
113
static int do_remove ( const char *inputfilename, int lineno, int argc, char **argv );
114
static int do_info ( const char *inputfilename, int lineno, int argc, char **argv );
115
static int do_exit ( const char *inputfilename, int lineno, int argc, char **argv );
116
static int do_quit ( const char *inputfilename, int lineno, int argc, char **argv );
117
static int do_source ( const char *inputfilename, int lineno, int argc, char **argv );
119
static const CommandTable command_table[] = { /* table of known commands */
120
{ "add", 2, 3, do_add,
123
add protoname protodata netid authname authdata"
126
{ "exit", 3, 4, do_exit,
128
exit save changes and exit program"
131
{ "extract", 3, 7, do_extract,
133
extract extract entries into file\n\
134
extract filename <protoname=$> <protodata=$> <netid=$> <authname=$>"
137
{ "help", 1, 4, do_help,
143
{ "info", 1, 4, do_info,
145
info print information about entries"
148
{ "list", 1, 4, do_list,
151
list <protoname=$> <protodata=$> <netid=$> <authname=$>"
154
{ "merge", 1, 5, do_merge,
156
merge merge entries from files\n\
157
merge filename1 <filename2> <filename3> ..."
160
{ "quit", 1, 4, do_quit,
162
quit abort changes and exit program" },
164
{ "remove", 1, 6, do_remove,
166
remove remove entries\n\
167
remove <protoname=$> <protodata=$> <netid=$> <authname=$>"
170
{ "source", 1, 6, do_source,
172
source read commands from file\n\
176
{ "?", 1, 1, do_questionmark,
178
? list available commands" },
180
{ NULL, 0, 0, NULL, NULL },
183
#define COMMAND_NAMES_PADDED_WIDTH 10 /* wider than anything above */
186
static Bool okay_to_use_stdin = True; /* set to false after using */
188
static const char * const hex_table[] = { /* for printing hex digits */
189
"00", "01", "02", "03", "04", "05", "06", "07",
190
"08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
191
"10", "11", "12", "13", "14", "15", "16", "17",
192
"18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
193
"20", "21", "22", "23", "24", "25", "26", "27",
194
"28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
195
"30", "31", "32", "33", "34", "35", "36", "37",
196
"38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
197
"40", "41", "42", "43", "44", "45", "46", "47",
198
"48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
199
"50", "51", "52", "53", "54", "55", "56", "57",
200
"58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
201
"60", "61", "62", "63", "64", "65", "66", "67",
202
"68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
203
"70", "71", "72", "73", "74", "75", "76", "77",
204
"78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
205
"80", "81", "82", "83", "84", "85", "86", "87",
206
"88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
207
"90", "91", "92", "93", "94", "95", "96", "97",
208
"98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
209
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
210
"a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
211
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
212
"b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
213
"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7",
214
"c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
215
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
216
"d8", "d9", "da", "db", "dc", "dd", "de", "df",
217
"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7",
218
"e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
219
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
220
"f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
223
static unsigned int hexvalues[256]; /* for parsing hex input */
225
static mode_t original_umask = 0; /* for restoring */
229
* private utility procedures
232
#define copystring(s) ( s != NULL ? strdup(s) : NULL )
236
register const char *a,
237
register const char *b,
238
register unsigned len)
247
static void prefix (const char *fn, int n)
249
fprintf (stderr, "%s: %s:%d: ", ProgramName, fn, n);
252
static void badcommandline (const char *cmd)
254
fprintf (stderr, "bad \"%s\" command line\n", cmd);
257
static char *skip_space (register char *s)
261
for ( ; *s && isascii(*s) && isspace(*s); s++)
267
static char *skip_nonspace (register char *s)
271
/* put quoting into loop if need be */
272
for ( ; *s && isascii(*s) && !isspace(*s); s++)
277
static char **split_into_words ( /* 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 (
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 (FILE *fp, AuthList **headp, AuthList **tailp)
359
IceAuthFileEntry *auth;
360
AuthList *head, *tail;
365
/* put all records into linked list */
366
while ((auth = IceReadAuthFileEntry (fp)) != NULL) {
367
AuthList *l = (AuthList *) malloc (sizeof (AuthList));
370
"%s: unable to alloc entry reading auth file\n",
376
if (tail) /* if not first time through append */
379
head = l; /* first time through, so assign */
389
static int cvthexkey ( /* turn hex key string into octets */
401
for (s = hexstr; *s; s++) {
402
if (!isascii(*s)) return -1;
403
if (isspace(*s)) continue;
404
if (!isxdigit(*s)) return -1;
408
/* if odd then there was an error */
409
if ((len & 1) == 1) return -1;
412
/* now we know that the input is good */
414
retval = malloc (len);
416
fprintf (stderr, "%s: unable to allocate %d bytes for hexkey\n",
421
for (us = (unsigned char *) retval, i = len; i > 0; hexstr++) {
423
if (isspace(c)) continue; /* already know it is ascii */
427
#define atoh(c) ((c) - (((c) >= '0' && (c) <= '9') ? '0' : ('a'-10)))
428
*us = (unsigned char)((atoh(savec) << 4) + atoh(c));
430
savec = 0; /* ready for next character */
441
static int dispatch_command (
442
const char *inputfilename,
446
const CommandTable *tab,
449
const CommandTable *ct;
452
/* scan table for command */
455
for (ct = tab; ct->name; ct++) {
456
/* look for unique prefix */
457
if (n >= ct->minlen && n <= ct->maxlen &&
458
strncmp (cmd, ct->name, n) == 0) {
459
*statusp = (*(ct->processfunc))(inputfilename, lineno, argc, argv);
469
static AuthList *iceauth_head = NULL; /* list of auth entries */
470
static Bool iceauth_existed = False; /* if was present at initialize */
471
static Bool iceauth_modified = False; /* if added, removed, or merged */
472
static Bool iceauth_allowed = True; /* if allowed to write auth file */
473
static char *iceauth_filename = NULL;
474
static volatile Bool dieing = False;
476
#ifdef RETSIGTYPE /* autoconf AC_TYPE_SIGNAL */
477
# define _signal_t RETSIGTYPE
479
#ifdef SIGNALRETURNSINT
480
#define _signal_t int
482
#define _signal_t void
484
#endif /* RETSIGTYPE */
486
/* poor man's puts(), for under signal handlers */
487
#define WRITES(fd, S) (void)write((fd), (S), strlen((S)))
490
static _signal_t die (int sig)
493
_exit (auth_finalize ());
495
#ifdef SIGNALRETURNSINT
496
return -1; /* for picky compilers */
500
static _signal_t catchsig (int sig)
503
if (sig > 0) signal (sig, die); /* re-establish signal handler */
506
* fileno() might not be reentrant, avoid it if possible, and use
507
* stderr instead of stdout
510
if (verbose && iceauth_modified) WRITES(STDERR_FILENO, "\r\n");
512
if (verbose && iceauth_modified) WRITES(fileno(stderr), "\r\n");
516
#ifdef SIGNALRETURNSINT
517
return -1; /* for picky compilers */
521
static void register_signals (void)
523
signal (SIGINT, catchsig);
524
signal (SIGTERM, catchsig);
526
signal (SIGHUP, catchsig);
533
* public procedures for parsing lines of input
536
int auth_initialize ( char *authfilename )
539
AuthList *head, *tail;
545
bzero ((char *) hexvalues, sizeof hexvalues);
556
hexvalues['a'] = hexvalues['A'] = 0xa;
557
hexvalues['b'] = hexvalues['B'] = 0xb;
558
hexvalues['c'] = hexvalues['C'] = 0xc;
559
hexvalues['d'] = hexvalues['D'] = 0xd;
560
hexvalues['e'] = hexvalues['E'] = 0xe;
561
hexvalues['f'] = hexvalues['F'] = 0xf;
563
if (break_locks && verbose) {
564
printf ("Attempting to break locks on authority file %s\n",
568
iceauth_filename = strdup(authfilename);
571
if (break_locks) IceUnlockAuthFile (authfilename);
573
n = IceLockAuthFile (authfilename, ICEAUTH_DEFAULT_RETRIES,
574
ICEAUTH_DEFAULT_TIMEOUT,
575
(break_locks ? 0L : ICEAUTH_DEFAULT_DEADTIME));
576
if (n != IceAuthLockSuccess) {
577
char *reason = "unknown error";
579
case IceAuthLockError:
582
case IceAuthLockTimeout:
586
fprintf (stderr, "%s: %s in locking authority file %s\n",
587
ProgramName, reason, authfilename);
592
/* these checks can only be done reliably after the file is locked */
593
exists = (access (authfilename, F_OK) == 0);
594
if (exists && access (authfilename, W_OK) != 0) {
596
"%s: %s not writable, changes will be ignored\n",
597
ProgramName, authfilename);
598
iceauth_allowed = False;
601
original_umask = umask (0077); /* disallow non-owner access */
603
authfp = fopen (authfilename, "rb");
605
int olderrno = errno;
607
/* if file there then error */
608
if (access (authfilename, F_OK) == 0) { /* then file does exist! */
611
} /* else ignore it */
613
"%s: creating new authority file %s\n",
614
ProgramName, authfilename);
616
iceauth_existed = True;
617
n = read_auth_entries (authfp, &head, &tail);
618
(void) fclose (authfp);
621
"%s: unable to read auth entries from file \"%s\"\n",
622
ProgramName, authfilename);
628
iceauth_modified = False;
631
printf ("%s authority file %s\n",
632
ignore_locks ? "Ignoring locks on" : "Using", authfilename);
637
static int write_auth_file (char *tmp_nam, size_t tmp_nam_len)
642
if ((strlen(iceauth_filename) + 3) > tmp_nam_len) {
643
strncpy(tmp_nam, "filename too long", tmp_nam_len);
644
tmp_nam[tmp_nam_len - 1] = '\0';
648
strcpy (tmp_nam, iceauth_filename);
649
strcat (tmp_nam, "-n"); /* for new */
650
(void) unlink (tmp_nam);
651
fp = fopen (tmp_nam, "wb"); /* umask is still set to 0077 */
653
fprintf (stderr, "%s: unable to open tmp file \"%s\"\n",
654
ProgramName, tmp_nam);
658
for (list = iceauth_head; list; list = list->next)
659
IceWriteAuthFileEntry (fp, list->auth);
665
int auth_finalize (void)
667
char temp_name[1024]; /* large filename size */
669
if (iceauth_modified) {
673
* called from a signal handler -- printf is *not* reentrant; also
674
* fileno() might not be reentrant, avoid it if possible, and use
675
* stderr instead of stdout
678
WRITES(STDERR_FILENO, "\nAborting changes to authority file ");
679
WRITES(STDERR_FILENO, iceauth_filename);
680
WRITES(STDERR_FILENO, "\n");
682
WRITES(fileno(stderr), "\nAborting changes to authority file ");
683
WRITES(fileno(stderr), iceauth_filename);
684
WRITES(fileno(stderr), "\n");
687
} else if (!iceauth_allowed) {
689
"%s: %s not writable, changes ignored\n",
690
ProgramName, iceauth_filename);
693
printf ("%s authority file %s\n",
694
ignore_locks ? "Ignoring locks and writing" :
695
"Writing", iceauth_filename);
698
if (write_auth_file (temp_name, sizeof(temp_name)) == -1) {
700
"%s: unable to write authority file %s\n",
701
ProgramName, temp_name);
703
(void) unlink (iceauth_filename);
704
#if defined(WIN32) || defined(__UNIXOS2__)
705
if (rename(temp_name, iceauth_filename) == -1)
707
if (link (temp_name, iceauth_filename) == -1)
711
"%s: unable to link authority file %s, use %s\n",
712
ProgramName, iceauth_filename, temp_name);
714
(void) unlink (temp_name);
720
if (!ignore_locks && (iceauth_filename != NULL)) {
721
IceUnlockAuthFile (iceauth_filename);
723
(void) umask (original_umask);
727
int process_command (
728
const char *inputfilename,
735
if (argc < 1 || !argv || !argv[0]) return 1;
737
if (dispatch_command (inputfilename, lineno, argc, argv,
738
command_table, &status))
741
prefix (inputfilename, lineno);
742
fprintf (stderr, "unknown command \"%s\"\n", argv[0]);
751
static void fprintfhex (
756
const unsigned char *ucp = (const unsigned char *) cp;
758
for (; len > 0; len--, ucp++) {
759
register const char *s = hex_table[*ucp];
767
static int dump_entry (
768
const char *inputfilename,
770
IceAuthFileEntry *auth,
773
struct _list_data *ld = (struct _list_data *) data;
776
fprintf (fp, "%s", auth->protocol_name);
778
if (auth->protocol_data_length > 0)
779
fprintfhex (fp, auth->protocol_data_length, auth->protocol_data);
781
fprintf (fp, "\"\"");
783
fprintf (fp, "%s", auth->network_id);
785
fprintf (fp, "%s", auth->auth_name);
788
if (auth->auth_data_length == 0)
789
fprintf (fp, "\"\"");
790
else if (!strcmp(auth->auth_name, SECURERPC) ||
791
!strcmp(auth->auth_name, K5AUTH))
792
fwrite (auth->auth_data, sizeof (char), auth->auth_data_length, fp);
794
fprintfhex (fp, auth->auth_data_length, auth->auth_data);
800
static int extract_entry (
801
const char *inputfilename,
803
IceAuthFileEntry *auth,
806
struct _extract_data *ed = (struct _extract_data *) data;
809
ed->fp = open_file (&ed->filename, "wb",
811
inputfilename, lineno, ed->cmd);
813
prefix (inputfilename, lineno);
815
"unable to open extraction file \"%s\"\n",
820
IceWriteAuthFileEntry (ed->fp, auth);
827
static int match_auth (
828
register IceAuthFileEntry *a,
829
register IceAuthFileEntry *b,
832
int match = strcmp (a->protocol_name, b->protocol_name) == 0 &&
833
strcmp (a->network_id, b->network_id) == 0 &&
834
strcmp (a->auth_name, b->auth_name) == 0;
838
*authDataSame = (a->auth_data_length == b->auth_data_length &&
839
binaryEqual (a->auth_data, b->auth_data, a->auth_data_length));
848
static int merge_entries (
849
AuthList **firstp, AuthList *second,
850
int *nnewp, int *nreplp, int *ndupp)
852
AuthList *a, *b, *first, *tail;
853
int n = 0, nnew = 0, nrepl = 0, ndup = 0;
855
if (!second) return 0;
857
if (!*firstp) { /* if nothing to merge into */
859
for (tail = *firstp, n = 1; tail->next; n++, tail = tail->next) ;
868
* find end of first list and stick second list on it
870
for (tail = first; tail->next; tail = tail->next) ;
874
* run down list freeing duplicate entries; if an entry is okay, then
875
* bump the tail up to include it, otherwise, cut the entry out of
878
for (b = second; b; ) {
879
AuthList *next = b->next; /* in case we free it */
886
if (match_auth (a->auth, b->auth, &authDataSame)) {
889
/* found a complete duplicate, ignore */
895
/* found a duplicate, but auth data differs */
897
AuthList tmp; /* swap it in for old one */
902
IceFreeAuthFileEntry (b->auth);
911
if (a == tail) break; /* if have looked at left side */
914
if (!duplicate && b) { /* if we didn't remove it */
915
tail = b; /* bump end of first list */
936
static int search_and_do (
937
const char *inputfilename,
949
char *protoname, *protodata, *netid, *authname;
951
for (l = iceauth_head; l; l = next)
955
protoname = protodata = netid = authname = NULL;
957
for (i = start; i < argc; i++)
959
if (!strncmp ("protoname=", argv[i], 10))
960
protoname = argv[i] + 10;
961
else if (!strncmp ("protodata=", argv[i], 10))
962
protodata = argv[i] + 10;
963
else if (!strncmp ("netid=", argv[i], 6))
965
else if (!strncmp ("authname=", argv[i], 9))
966
authname = argv[i] + 9;
971
if (protoname || protodata || netid || authname)
973
if (protoname && strcmp (protoname, l->auth->protocol_name))
976
if (protodata && !binaryEqual (protodata,
977
l->auth->protocol_data, l->auth->protocol_data_length))
980
if (netid && strcmp (netid, l->auth->network_id))
983
if (authname && strcmp (authname, l->auth->auth_name))
986
status = (*do_func) (inputfilename, lineno, l->auth, data);
994
errors -= status; /* since status is negative */
1001
static int remove_entry (
1002
const char *inputfilename,
1004
IceAuthFileEntry *auth,
1007
int *nremovedp = (int *) data;
1008
AuthList **listp = &iceauth_head;
1012
* unlink the auth we were asked to
1014
while ((list = *listp)->auth != auth)
1015
listp = &list->next;
1016
*listp = list->next;
1017
IceFreeAuthFileEntry (list->auth); /* free the auth */
1018
free (list); /* free the link */
1019
iceauth_modified = True;
1035
const CommandTable *ct;
1039
if (!cmd) { /* if no cmd, print all help */
1040
for (ct = command_table; ct->name; ct++) {
1041
fprintf (fp, "%s\n\n", ct->helptext);
1045
int len = strlen (cmd);
1046
for (ct = command_table; ct->name; ct++) {
1047
if (strncmp (cmd, ct->name, len) == 0) {
1048
fprintf (fp, "%s\n\n", ct->helptext);
1057
static int do_help (
1058
const char *inputfilename,
1063
char *cmd = (argc > 1 ? argv[1] : NULL);
1066
n = print_help (stdout, cmd);
1068
if (n < 0 || (n == 0 && !cmd)) {
1069
prefix (inputfilename, lineno);
1070
fprintf (stderr, "internal error with help");
1072
fprintf (stderr, " on command \"%s\"", cmd);
1074
fprintf (stderr, "\n");
1079
prefix (inputfilename, lineno);
1080
/* already know that cmd is set in this case */
1081
fprintf (stderr, "no help for noexistent command \"%s\"\n", cmd);
1091
static int do_questionmark (
1092
const char *inputfilename,
1097
const CommandTable *ct;
1099
#define WIDEST_COLUMN 72
1100
int col = WIDEST_COLUMN;
1102
printf ("Commands:\n");
1103
for (ct = command_table; ct->name; ct++) {
1104
if ((col + ct->maxlen) > WIDEST_COLUMN) {
1105
if (ct != command_table) {
1106
putc ('\n', stdout);
1108
fputs (" ", stdout);
1109
col = 8; /* length of string above */
1111
fputs (ct->name, stdout);
1113
for (i = ct->maxlen; i < COMMAND_NAMES_PADDED_WIDTH; i++) {
1119
putc ('\n', stdout);
1122
/* allow bad lines since this is help */
1127
* list [displayname ...]
1129
static int do_list (
1130
const char *inputfilename,
1135
struct _list_data ld;
1140
register AuthList *l;
1143
for (l = iceauth_head; l; l = l->next) {
1144
dump_entry (inputfilename, lineno, l->auth, (char *) &ld);
1151
return (search_and_do (inputfilename, lineno, 1, argc, argv,
1152
dump_entry, (char *) &ld));
1157
* merge filename [filename ...]
1159
static int do_merge (
1160
const char *inputfilename,
1167
AuthList *head, *tail, *listhead, *listtail;
1168
int nentries, nnew, nrepl, ndup;
1171
prefix (inputfilename, lineno);
1172
badcommandline (argv[0]);
1176
listhead = listtail = NULL;
1178
for (i = 1; i < argc; i++) {
1179
char *filename = argv[i];
1181
Bool used_stdin = False;
1183
fp = open_file (&filename, "rb",
1184
&used_stdin, inputfilename, lineno,
1192
nentries = read_auth_entries (fp, &head, &tail);
1193
if (nentries == 0) {
1194
prefix (inputfilename, lineno);
1195
fprintf (stderr, "unable to read any entries from file \"%s\"\n",
1198
} else { /* link it in */
1199
add_to_list (listhead, listtail, head);
1202
if (!used_stdin) (void) fclose (fp);
1206
* if we have new entries, merge them in (freeing any duplicates)
1209
nentries = merge_entries (&iceauth_head, listhead,
1210
&nnew, &nrepl, &ndup);
1212
printf ("%d entries read in: %d new, %d replacement%s\n",
1213
nentries, nnew, nrepl, nrepl != 1 ? "s" : "");
1214
if (nentries > 0) iceauth_modified = True;
1221
* extract filename displayname [displayname ...]
1223
static int do_extract (
1224
const char *inputfilename,
1230
struct _extract_data ed;
1233
prefix (inputfilename, lineno);
1234
badcommandline (argv[0]);
1239
ed.filename = argv[1];
1243
errors = search_and_do (inputfilename, lineno, 2, argc, argv,
1244
extract_entry, (char *) &ed);
1248
"No matches found, authority file \"%s\" not written\n",
1252
printf ("%d entries written to \"%s\"\n",
1253
ed.nwritten, ed.filename);
1255
if (!ed.used_stdout) {
1256
(void) fclose (ed.fp);
1265
* add protoname protodata netid authname authdata
1268
const char *inputfilename,
1273
int n, nnew, nrepl, ndup;
1275
char *protodata_hex;
1276
char *protodata = NULL; /* not required */
1280
char *authdata = NULL;
1281
int protodata_len, authdata_len;
1282
IceAuthFileEntry *auth = NULL;
1286
if (argc != 6 || !argv[1] || !argv[2] ||
1287
!argv[3] || !argv[4] || !argv[5])
1289
prefix (inputfilename, lineno);
1290
badcommandline (argv[0]);
1294
protoname = argv[1];
1295
protodata_hex = argv[2];
1298
authdata_hex = argv[5];
1300
protodata_len = strlen (protodata_hex);
1301
if (protodata_len > 0)
1303
if (protodata_hex[0] == '"' && protodata_hex[protodata_len - 1] == '"')
1305
protodata = malloc (protodata_len - 1);
1308
strncpy (protodata, protodata_hex + 1, protodata_len - 2);
1312
goto add_bad_malloc;
1316
protodata_len = cvthexkey (protodata_hex, &protodata);
1317
if (protodata_len < 0)
1319
prefix (inputfilename, lineno);
1321
"protodata_hex contains odd number of or non-hex characters\n");
1327
authdata_len = strlen (authdata_hex);
1328
if (authdata_hex[0] == '"' && authdata_hex[authdata_len - 1] == '"')
1330
authdata = malloc (authdata_len - 1);
1333
strncpy (authdata, authdata_hex + 1, authdata_len - 2);
1337
goto add_bad_malloc;
1339
else if (!strcmp (protoname, SECURERPC) || !strcmp (protoname, K5AUTH))
1341
authdata = malloc (authdata_len + 1);
1343
strcpy (authdata, authdata_hex);
1345
goto add_bad_malloc;
1349
authdata_len = cvthexkey (authdata_hex, &authdata);
1350
if (authdata_len < 0)
1352
prefix (inputfilename, lineno);
1354
"authdata_hex contains odd number of or non-hex characters\n");
1360
auth = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry));
1363
goto add_bad_malloc;
1365
auth->protocol_name = copystring (protoname);
1366
auth->protocol_data_length = protodata_len;
1367
auth->protocol_data = protodata;
1368
auth->network_id = copystring (netid);
1369
auth->auth_name = copystring (authname);
1370
auth->auth_data_length = authdata_len;
1371
auth->auth_data = authdata;
1373
if (!auth->protocol_name ||
1374
(!auth->protocol_data && auth->protocol_data_length > 0) ||
1375
!auth->network_id || !auth->auth_name ||
1376
(!auth->auth_data && auth->auth_data_length > 0))
1378
goto add_bad_malloc;
1381
list = (AuthList *) malloc (sizeof (AuthList));
1384
goto add_bad_malloc;
1390
* merge it in; note that merge will deal with allocation
1393
n = merge_entries (&iceauth_head, list, &nnew, &nrepl, &ndup);
1396
iceauth_modified = True;
1399
prefix (inputfilename, lineno);
1403
fprintf (stderr, "no records added - all duplicate\n");
1408
fprintf (stderr, "unable to merge in added record\n");
1419
prefix (inputfilename, lineno);
1420
fprintf (stderr, "unable to allocate memory to add an entry\n");
1430
if (auth->protocol_name)
1431
free (auth->protocol_name);
1432
/* auth->protocol_data already freed,
1433
since it's the same as protodata */
1434
if (auth->network_id)
1435
free (auth->network_id);
1436
if (auth->auth_name)
1437
free (auth->auth_name);
1438
/* auth->auth_data already freed,
1439
since it's the same as authdata */
1440
free ((char *) auth);
1447
* remove displayname
1449
static int do_remove (
1450
const char *inputfilename,
1459
prefix (inputfilename, lineno);
1460
badcommandline (argv[0]);
1464
errors = search_and_do (inputfilename, lineno, 1, argc, argv,
1465
remove_entry, (char *) &nremoved);
1466
if (verbose) printf ("%d entries removed\n", nremoved);
1473
static int do_info (
1474
const char *inputfilename,
1483
prefix (inputfilename, lineno);
1484
badcommandline (argv[0]);
1488
for (l = iceauth_head, n = 0; l; l = l->next, n++) ;
1490
printf ("Authority file: %s\n",
1491
iceauth_filename ? iceauth_filename : "(none)");
1492
printf ("File new: %s\n", iceauth_existed ? No : Yes);
1493
printf ("File locked: %s\n", ignore_locks ? No : Yes);
1494
printf ("Number of entries: %d\n", n);
1495
printf ("Changes honored: %s\n", iceauth_allowed ? Yes : No);
1496
printf ("Changes made: %s\n", iceauth_modified ? Yes : No);
1497
printf ("Current input: %s:%d\n", inputfilename, lineno);
1505
static Bool alldone = False;
1508
static int do_exit (
1509
const char *inputfilename,
1514
/* allow bogus stuff */
1523
static int do_quit (
1524
const char *inputfilename,
1529
/* allow bogus stuff */
1532
return -1; /* for picky compilers */
1539
static int do_source (
1540
const char *inputfilename,
1548
Bool used_stdin = False;
1550
int errors = 0, status;
1554
Bool prompt = False; /* only true if reading from tty */
1556
if (argc != 2 || !argv[1]) {
1557
prefix (inputfilename, lineno);
1558
badcommandline (argv[0]);
1564
fp = open_file (&script, "r", &used_stdin, inputfilename, lineno, argv[0]);
1569
if (verbose && used_stdin && isatty (fileno (fp))) prompt = True;
1574
printf ("iceauth> ");
1577
if (fgets (buf, sizeof buf, fp) == NULL) break;
1580
if (len == 0 || buf[0] == '#') continue;
1581
if (buf[len-1] != '\n') {
1582
prefix (script, sublineno);
1583
fprintf (stderr, "line too long\n");
1587
buf[--len] = '\0'; /* remove new line */
1588
subargv = split_into_words (buf, &subargc);
1590
status = process_command (script, sublineno, subargc, subargv);
1591
free ((char *) subargv);
1594
prefix (script, sublineno);
1595
fprintf (stderr, "unable to break line into words\n");