~ubuntu-branches/ubuntu/karmic/x11-xserver-utils/karmic

« back to all changes in this revision

Viewing changes to iceauth/process.c

  • Committer: Bazaar Package Importer
  • Author(s): Brice Goglin, Julien Cristau, Brice Goglin
  • Date: 2007-08-17 09:58:34 UTC
  • Revision ID: james.westby@ubuntu.com-20070817095834-ywge2nyzj1s3rqnd
Tags: 7.3+1
[ Julien Cristau ]
* iceauth 1.0.2.
  + removes blank line in the manpage (closes: #25285).
* xmodmap 1.0.3.
  + manpage updated to state that -pm is the default (closes: #236198)
* xgamma 1.0.2.
  + the manpage now explains how to print the gamma value more clearly
    (closes: #296021).
* xsetroot 1.0.2.
* xrdb 1.0.4.
  + fixes manpage typo (closes: #276286).
* Add upstream URL to debian/copyright, and update it from xgamma's COPYING
  file.

[ Brice Goglin ]
* Add menu entries for xrefresh and xvidtune.
* sessreg 1.0.3.
* xset 1.0.3.
* Add myself to Uploaders, and remove Branden with his permission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Xorg: process.c,v 1.5 2001/02/09 02:05:31 xorgcvs Exp $
 
3
 * $XdotOrg: $
 
4
 * 
 
5
Copyright 1989, 1998  The Open Group
 
6
 
 
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
 
11
documentation.
 
12
 
 
13
The above copyright notice and this permission notice shall be included in
 
14
all copies or substantial portions of the Software.
 
15
 
 
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.
 
22
 
 
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.
 
26
 * *
 
27
 * Original Author of "xauth" : Jim Fulton, MIT X Consortium
 
28
 * Modified into "iceauth"    : Ralph Mor, X Consortium
 
29
 */
 
30
 
 
31
/* $XFree86: xc/programs/iceauth/process.c,v 3.7 2001/12/14 20:00:49 dawes Exp $ */
 
32
 
 
33
#include "iceauth.h"
 
34
#include <ctype.h>
 
35
#include <errno.h>
 
36
#include <sys/types.h>
 
37
#include <sys/stat.h>
 
38
#include <signal.h>
 
39
 
 
40
#define SECURERPC "SUN-DES-1"
 
41
#define K5AUTH "KERBEROS-V5-1"
 
42
 
 
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 */
 
46
 
 
47
typedef struct _AuthList {              /* linked list of entries */
 
48
    struct _AuthList *next;
 
49
    IceAuthFileEntry *auth;
 
50
} AuthList;
 
51
 
 
52
#define add_to_list(h,t,e) {if (t) (t)->next = (e); else (h) = (e); (t) = (e);}
 
53
 
 
54
typedef int (*ProcessFunc)(const char *, int, int, char **);
 
55
typedef int (*DoFunc)(const char *, int, IceAuthFileEntry *, char *);
 
56
 
 
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 */
 
63
} CommandTable;
 
64
 
 
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 */
 
71
};
 
72
 
 
73
struct _list_data {                     /* for iterating */
 
74
    FILE *fp;                           /* output file */
 
75
};
 
76
 
 
77
 
 
78
/*
 
79
 * private data
 
80
 */
 
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 */
 
85
 
 
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 );
 
118
 
 
119
static const CommandTable command_table[] = {   /* table of known commands */
 
120
{ "add", 2, 3, do_add,
 
121
"\
 
122
add       add an entry\n\
 
123
          add protoname protodata netid authname authdata"
 
124
},
 
125
 
 
126
{ "exit", 3, 4, do_exit,
 
127
"\
 
128
exit      save changes and exit program"
 
129
},
 
130
 
 
131
{ "extract", 3, 7, do_extract,
 
132
"\
 
133
extract   extract entries into file\n\
 
134
          extract filename <protoname=$> <protodata=$> <netid=$> <authname=$>"
 
135
},
 
136
 
 
137
{ "help", 1, 4, do_help,
 
138
"\
 
139
help      print help\n\
 
140
          help <topic>"
 
141
},
 
142
 
 
143
{ "info", 1, 4, do_info,
 
144
"\
 
145
info      print information about entries"
 
146
},
 
147
 
 
148
{ "list", 1, 4, do_list,
 
149
"\
 
150
list      list entries\n\
 
151
          list <protoname=$> <protodata=$> <netid=$> <authname=$>"
 
152
},
 
153
 
 
154
{ "merge", 1, 5, do_merge,
 
155
"\
 
156
merge     merge entries from files\n\
 
157
          merge filename1 <filename2> <filename3> ..."
 
158
},
 
159
 
 
160
{ "quit", 1, 4, do_quit,
 
161
"\
 
162
quit      abort changes and exit program" },
 
163
 
 
164
{ "remove", 1, 6, do_remove,
 
165
"\
 
166
remove    remove entries\n\
 
167
          remove <protoname=$> <protodata=$> <netid=$> <authname=$>"
 
168
},
 
169
 
 
170
{ "source", 1, 6, do_source,
 
171
"\
 
172
source    read commands from file\n\
 
173
          source filename"
 
174
},
 
175
 
 
176
{ "?", 1, 1, do_questionmark,
 
177
"\
 
178
?         list available commands" },
 
179
 
 
180
{ NULL, 0, 0, NULL, NULL },
 
181
};
 
182
 
 
183
#define COMMAND_NAMES_PADDED_WIDTH 10   /* wider than anything above */
 
184
 
 
185
 
 
186
static Bool okay_to_use_stdin = True;   /* set to false after using */
 
187
 
 
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", 
 
221
};
 
222
 
 
223
static unsigned int hexvalues[256];     /* for parsing hex input */
 
224
 
 
225
static mode_t original_umask = 0;       /* for restoring */
 
226
 
 
227
 
 
228
/*
 
229
 * private utility procedures
 
230
 */
 
231
 
 
232
#define copystring(s)   ( s != NULL ? strdup(s) : NULL )
 
233
 
 
234
static int
 
235
binaryEqual (
 
236
    register const char *a,
 
237
    register const char *b,
 
238
    register unsigned   len)
 
239
 
 
240
{
 
241
    while (len--)
 
242
        if (*a++ != *b++)
 
243
            return 0;
 
244
    return 1;
 
245
}
 
246
 
 
247
static void prefix (const char *fn, int n)
 
248
{
 
249
    fprintf (stderr, "%s: %s:%d:  ", ProgramName, fn, n);
 
250
}
 
251
 
 
252
static void badcommandline (const char *cmd)
 
253
{
 
254
    fprintf (stderr, "bad \"%s\" command line\n", cmd);
 
255
}
 
256
 
 
257
static char *skip_space (register char *s)
 
258
{
 
259
    if (!s) return NULL;
 
260
 
 
261
    for ( ; *s && isascii(*s) && isspace(*s); s++)
 
262
        ;
 
263
    return s;
 
264
}
 
265
 
 
266
 
 
267
static char *skip_nonspace (register char *s)
 
268
{
 
269
    if (!s) return NULL;
 
270
 
 
271
    /* put quoting into loop if need be */
 
272
    for ( ; *s && isascii(*s) && !isspace(*s); s++)
 
273
        ;
 
274
    return s;
 
275
}
 
276
 
 
277
static char **split_into_words (  /* argvify string */
 
278
    char *src,
 
279
    int *argcp)
 
280
{
 
281
    char *jword;
 
282
    char savec;
 
283
    char **argv;
 
284
    int cur, total;
 
285
 
 
286
    *argcp = 0;
 
287
#define WORDSTOALLOC 4                  /* most lines are short */
 
288
    argv = (char **) malloc (WORDSTOALLOC * sizeof (char *));
 
289
    if (!argv) return NULL;
 
290
    cur = 0;
 
291
    total = WORDSTOALLOC;
 
292
 
 
293
    /*
 
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
 
296
     * a null pointer.
 
297
     */
 
298
 
 
299
    do {
 
300
        jword = skip_space (src);
 
301
        src = skip_nonspace (jword);
 
302
        savec = *src;
 
303
        *src = '\0';
 
304
        if (cur == total) {
 
305
            total += WORDSTOALLOC;
 
306
            argv = (char **) realloc (argv, total * sizeof (char *));
 
307
            if (!argv) return NULL;
 
308
        }
 
309
        argv[cur++] = jword;
 
310
        if (savec) src++;               /* if not last on line advance */
 
311
    } while (jword != src);
 
312
 
 
313
    argv[--cur] = NULL;                 /* smash empty token to end list */
 
314
    *argcp = cur;
 
315
    return argv;
 
316
}
 
317
 
 
318
 
 
319
static FILE *open_file (
 
320
    char **filenamep,
 
321
    const char *mode,
 
322
    Bool *usedstdp,
 
323
    const char *srcfn,
 
324
    int srcln,
 
325
    const char *cmd)
 
326
{
 
327
    FILE *fp;
 
328
 
 
329
    if (strcmp (*filenamep, "-") == 0) {
 
330
        *usedstdp = True;
 
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;
 
336
                return stdin;
 
337
            } else {
 
338
                prefix (srcfn, srcln);
 
339
                fprintf (stderr, "%s:  stdin already in use\n", cmd);
 
340
                return NULL;
 
341
            }
 
342
        } else {
 
343
            *filenamep = stdout_filename;
 
344
            return stdout;              /* always okay to use stdout */
 
345
        }
 
346
    }
 
347
 
 
348
    fp = fopen (*filenamep, mode);
 
349
    if (!fp) {
 
350
        prefix (srcfn, srcln);
 
351
        fprintf (stderr, "%s:  unable to open file %s\n", cmd, *filenamep);
 
352
    }
 
353
    return fp;
 
354
}
 
355
 
 
356
 
 
357
static int read_auth_entries (FILE *fp, AuthList **headp, AuthList **tailp)
 
358
{
 
359
    IceAuthFileEntry *auth;
 
360
    AuthList *head, *tail;
 
361
    int n;
 
362
 
 
363
    head = tail = NULL;
 
364
    n = 0;
 
365
                                        /* put all records into linked list */
 
366
    while ((auth = IceReadAuthFileEntry (fp)) != NULL) {
 
367
        AuthList *l = (AuthList *) malloc (sizeof (AuthList));
 
368
        if (!l) {
 
369
            fprintf (stderr,
 
370
                     "%s:  unable to alloc entry reading auth file\n",
 
371
                     ProgramName);
 
372
            exit (1);
 
373
        }
 
374
        l->next = NULL;
 
375
        l->auth = auth;
 
376
        if (tail)                       /* if not first time through append */
 
377
          tail->next = l;
 
378
        else
 
379
          head = l;                     /* first time through, so assign */
 
380
        tail = l;
 
381
        n++;
 
382
    }
 
383
    *headp = head;
 
384
    *tailp = tail;
 
385
    return n;
 
386
}
 
387
 
 
388
 
 
389
static int cvthexkey (  /* turn hex key string into octets */
 
390
    char *hexstr,
 
391
    char **ptrp)
 
392
{
 
393
    int i;
 
394
    int len = 0;
 
395
    char *retval, *s;
 
396
    unsigned char *us;
 
397
    char c;
 
398
    char savec = '\0';
 
399
 
 
400
    /* count */
 
401
    for (s = hexstr; *s; s++) {
 
402
        if (!isascii(*s)) return -1;
 
403
        if (isspace(*s)) continue;
 
404
        if (!isxdigit(*s)) return -1;
 
405
        len++;
 
406
    }
 
407
 
 
408
    /* if odd then there was an error */
 
409
    if ((len & 1) == 1) return -1;
 
410
 
 
411
 
 
412
    /* now we know that the input is good */
 
413
    len >>= 1;
 
414
    retval = malloc (len);
 
415
    if (!retval) {
 
416
        fprintf (stderr, "%s:  unable to allocate %d bytes for hexkey\n",
 
417
                 ProgramName, len);
 
418
        return -1;
 
419
    }
 
420
 
 
421
    for (us = (unsigned char *) retval, i = len; i > 0; hexstr++) {
 
422
        c = *hexstr;
 
423
        if (isspace(c)) continue;        /* already know it is ascii */
 
424
        if (isupper(c))
 
425
            c = tolower(c);
 
426
        if (savec) {
 
427
#define atoh(c) ((c) - (((c) >= '0' && (c) <= '9') ? '0' : ('a'-10)))
 
428
            *us = (unsigned char)((atoh(savec) << 4) + atoh(c));
 
429
#undef atoh
 
430
            savec = 0;          /* ready for next character */
 
431
            us++;
 
432
            i--;
 
433
        } else {
 
434
            savec = c;
 
435
        }
 
436
    }
 
437
    *ptrp = retval;
 
438
    return len;
 
439
}
 
440
 
 
441
static int dispatch_command (
 
442
    const char *inputfilename,
 
443
    int lineno,
 
444
    int argc,
 
445
    char **argv,
 
446
    const CommandTable *tab,
 
447
    int *statusp)
 
448
{
 
449
    const CommandTable *ct;
 
450
    char *cmd;
 
451
    int n;
 
452
                                        /* scan table for command */
 
453
    cmd = argv[0];
 
454
    n = strlen (cmd);
 
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);
 
460
            return 1;
 
461
        }
 
462
    }
 
463
 
 
464
    *statusp = 1;
 
465
    return 0;
 
466
}
 
467
 
 
468
 
 
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;
 
475
 
 
476
#ifdef RETSIGTYPE /* autoconf AC_TYPE_SIGNAL */
 
477
# define _signal_t RETSIGTYPE
 
478
#else /* Imake */
 
479
#ifdef SIGNALRETURNSINT
 
480
#define _signal_t int
 
481
#else
 
482
#define _signal_t void
 
483
#endif
 
484
#endif /* RETSIGTYPE */
 
485
 
 
486
/* poor man's puts(), for under signal handlers */
 
487
#define WRITES(fd, S) (void)write((fd), (S), strlen((S)))
 
488
 
 
489
/* ARGSUSED */
 
490
static _signal_t die (int sig)
 
491
{
 
492
    dieing = True;
 
493
    _exit (auth_finalize ());
 
494
    /* NOTREACHED */
 
495
#ifdef SIGNALRETURNSINT
 
496
    return -1;                          /* for picky compilers */
 
497
#endif
 
498
}
 
499
 
 
500
static _signal_t catchsig (int sig)
 
501
{
 
502
#ifdef SYSV
 
503
    if (sig > 0) signal (sig, die);     /* re-establish signal handler */
 
504
#endif
 
505
    /*
 
506
     * fileno() might not be reentrant, avoid it if possible, and use
 
507
     * stderr instead of stdout
 
508
     */
 
509
#ifdef STDERR_FILENO
 
510
    if (verbose && iceauth_modified) WRITES(STDERR_FILENO, "\r\n");
 
511
#else
 
512
    if (verbose && iceauth_modified) WRITES(fileno(stderr), "\r\n");
 
513
#endif
 
514
    die (sig);
 
515
    /* NOTREACHED */
 
516
#ifdef SIGNALRETURNSINT
 
517
    return -1;                          /* for picky compilers */
 
518
#endif
 
519
}
 
520
 
 
521
static void register_signals (void)
 
522
{
 
523
    signal (SIGINT, catchsig);
 
524
    signal (SIGTERM, catchsig);
 
525
#ifdef SIGHUP
 
526
    signal (SIGHUP, catchsig);
 
527
#endif
 
528
    return;
 
529
}
 
530
 
 
531
 
 
532
/*
 
533
 * public procedures for parsing lines of input
 
534
 */
 
535
 
 
536
int auth_initialize ( char *authfilename )
 
537
{
 
538
    int n;
 
539
    AuthList *head, *tail;
 
540
    FILE *authfp;
 
541
    Bool exists;
 
542
 
 
543
    register_signals ();
 
544
 
 
545
    bzero ((char *) hexvalues, sizeof hexvalues);
 
546
    hexvalues['0'] = 0;
 
547
    hexvalues['1'] = 1;
 
548
    hexvalues['2'] = 2;
 
549
    hexvalues['3'] = 3;
 
550
    hexvalues['4'] = 4;
 
551
    hexvalues['5'] = 5;
 
552
    hexvalues['6'] = 6;
 
553
    hexvalues['7'] = 7;
 
554
    hexvalues['8'] = 8;
 
555
    hexvalues['9'] = 9;
 
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;
 
562
 
 
563
    if (break_locks && verbose) {
 
564
        printf ("Attempting to break locks on authority file %s\n",
 
565
                authfilename);
 
566
    }
 
567
 
 
568
    iceauth_filename = strdup(authfilename);
 
569
    
 
570
    if (ignore_locks) {
 
571
        if (break_locks) IceUnlockAuthFile (authfilename);
 
572
    } else {
 
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";
 
578
            switch (n) {
 
579
              case IceAuthLockError:
 
580
                reason = "error";
 
581
                break;
 
582
              case IceAuthLockTimeout:
 
583
                reason = "timeout";
 
584
                break;
 
585
            }
 
586
            fprintf (stderr, "%s:  %s in locking authority file %s\n",
 
587
                     ProgramName, reason, authfilename);
 
588
            return -1;
 
589
        }
 
590
    }
 
591
 
 
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) {
 
595
        fprintf (stderr,
 
596
         "%s:  %s not writable, changes will be ignored\n",
 
597
                 ProgramName, authfilename);
 
598
        iceauth_allowed = False;
 
599
    }
 
600
 
 
601
    original_umask = umask (0077);      /* disallow non-owner access */
 
602
 
 
603
    authfp = fopen (authfilename, "rb");
 
604
    if (!authfp) {
 
605
        int olderrno = errno;
 
606
 
 
607
                                        /* if file there then error */
 
608
        if (access (authfilename, F_OK) == 0) {  /* then file does exist! */
 
609
            errno = olderrno;
 
610
            return -1;
 
611
        }                               /* else ignore it */
 
612
        fprintf (stderr, 
 
613
                 "%s:  creating new authority file %s\n",
 
614
                 ProgramName, authfilename);
 
615
    } else {
 
616
        iceauth_existed = True;
 
617
        n = read_auth_entries (authfp, &head, &tail);
 
618
        (void) fclose (authfp);
 
619
        if (n < 0) {
 
620
            fprintf (stderr,
 
621
                     "%s:  unable to read auth entries from file \"%s\"\n",
 
622
                     ProgramName, authfilename);
 
623
            return -1;
 
624
        }
 
625
        iceauth_head = head;
 
626
    }
 
627
 
 
628
    iceauth_modified = False;
 
629
 
 
630
    if (verbose) {
 
631
        printf ("%s authority file %s\n", 
 
632
                ignore_locks ? "Ignoring locks on" : "Using", authfilename);
 
633
    }
 
634
    return 0;
 
635
}
 
636
 
 
637
static int write_auth_file (char *tmp_nam, size_t tmp_nam_len)
 
638
{
 
639
    FILE *fp;
 
640
    AuthList *list;
 
641
 
 
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';
 
645
        return -1;
 
646
    }
 
647
    
 
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 */
 
652
    if (!fp) {
 
653
        fprintf (stderr, "%s:  unable to open tmp file \"%s\"\n",
 
654
                 ProgramName, tmp_nam);
 
655
        return -1;
 
656
    } 
 
657
 
 
658
    for (list = iceauth_head; list; list = list->next)
 
659
        IceWriteAuthFileEntry (fp, list->auth);
 
660
 
 
661
    (void) fclose (fp);
 
662
    return 0;
 
663
}
 
664
 
 
665
int auth_finalize (void)
 
666
{
 
667
    char temp_name[1024];                       /* large filename size */
 
668
 
 
669
    if (iceauth_modified) {
 
670
        if (dieing) {
 
671
            if (verbose) {
 
672
                /*
 
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
 
676
                 */
 
677
#ifdef STDERR_FILENO
 
678
                WRITES(STDERR_FILENO, "\nAborting changes to authority file ");
 
679
                WRITES(STDERR_FILENO, iceauth_filename);
 
680
                WRITES(STDERR_FILENO, "\n");
 
681
#else
 
682
                WRITES(fileno(stderr), "\nAborting changes to authority file ");
 
683
                WRITES(fileno(stderr), iceauth_filename);
 
684
                WRITES(fileno(stderr), "\n");
 
685
#endif
 
686
            }
 
687
        } else if (!iceauth_allowed) {
 
688
            fprintf (stderr, 
 
689
                     "%s:  %s not writable, changes ignored\n",
 
690
                     ProgramName, iceauth_filename);
 
691
        } else {
 
692
            if (verbose) {
 
693
                printf ("%s authority file %s\n", 
 
694
                        ignore_locks ? "Ignoring locks and writing" :
 
695
                        "Writing", iceauth_filename);
 
696
            }
 
697
            temp_name[0] = '\0';
 
698
            if (write_auth_file (temp_name, sizeof(temp_name)) == -1) {
 
699
                fprintf (stderr,
 
700
                         "%s:  unable to write authority file %s\n",
 
701
                         ProgramName, temp_name);
 
702
            } else {
 
703
                (void) unlink (iceauth_filename);
 
704
#if defined(WIN32) || defined(__UNIXOS2__)
 
705
                if (rename(temp_name, iceauth_filename) == -1)
 
706
#else
 
707
                if (link (temp_name, iceauth_filename) == -1)
 
708
#endif
 
709
                {
 
710
                    fprintf (stderr,
 
711
                     "%s:  unable to link authority file %s, use %s\n",
 
712
                             ProgramName, iceauth_filename, temp_name);
 
713
                } else {
 
714
                    (void) unlink (temp_name);
 
715
                }
 
716
            }
 
717
        }
 
718
    }
 
719
 
 
720
    if (!ignore_locks && (iceauth_filename != NULL)) {
 
721
        IceUnlockAuthFile (iceauth_filename);
 
722
    }
 
723
    (void) umask (original_umask);
 
724
    return 0;
 
725
}
 
726
 
 
727
int process_command (
 
728
    const char *inputfilename,
 
729
    int lineno,
 
730
    int argc,
 
731
    char **argv)
 
732
{
 
733
    int status;
 
734
 
 
735
    if (argc < 1 || !argv || !argv[0]) return 1;
 
736
 
 
737
    if (dispatch_command (inputfilename, lineno, argc, argv,
 
738
                          command_table, &status))
 
739
      return status;
 
740
 
 
741
    prefix (inputfilename, lineno);
 
742
    fprintf (stderr, "unknown command \"%s\"\n", argv[0]);
 
743
    return 1;
 
744
}
 
745
 
 
746
 
 
747
/*
 
748
 * utility routines
 
749
 */
 
750
 
 
751
static void fprintfhex (
 
752
    register FILE *fp,
 
753
    unsigned int len,
 
754
    const char *cp)
 
755
{
 
756
    const unsigned char *ucp = (const unsigned char *) cp;
 
757
 
 
758
    for (; len > 0; len--, ucp++) {
 
759
        register const char *s = hex_table[*ucp];
 
760
        putc (s[0], fp);
 
761
        putc (s[1], fp);
 
762
    }
 
763
    return;
 
764
}
 
765
 
 
766
/* ARGSUSED */
 
767
static int dump_entry (
 
768
    const char *inputfilename,
 
769
    int lineno,
 
770
    IceAuthFileEntry *auth,
 
771
    char *data)
 
772
{
 
773
    struct _list_data *ld = (struct _list_data *) data;
 
774
    FILE *fp = ld->fp;
 
775
 
 
776
    fprintf (fp, "%s", auth->protocol_name);
 
777
    putc (' ', fp);
 
778
    if (auth->protocol_data_length > 0)
 
779
        fprintfhex (fp, auth->protocol_data_length, auth->protocol_data);
 
780
    else
 
781
        fprintf (fp, "\"\"");
 
782
    putc (' ', fp);
 
783
    fprintf (fp, "%s", auth->network_id);
 
784
    putc (' ', fp);
 
785
    fprintf (fp, "%s", auth->auth_name);
 
786
    putc (' ', fp);
 
787
 
 
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);
 
793
    else
 
794
        fprintfhex (fp, auth->auth_data_length, auth->auth_data);
 
795
    putc ('\n', fp);
 
796
 
 
797
    return 0;
 
798
}
 
799
 
 
800
static int extract_entry (
 
801
    const char *inputfilename,
 
802
    int lineno,
 
803
    IceAuthFileEntry *auth,
 
804
    char *data)
 
805
{
 
806
    struct _extract_data *ed = (struct _extract_data *) data;
 
807
 
 
808
    if (!ed->fp) {
 
809
        ed->fp = open_file (&ed->filename, "wb",
 
810
                            &ed->used_stdout,
 
811
                            inputfilename, lineno, ed->cmd);
 
812
        if (!ed->fp) {
 
813
            prefix (inputfilename, lineno);
 
814
            fprintf (stderr,
 
815
                     "unable to open extraction file \"%s\"\n",
 
816
                     ed->filename);
 
817
            return -1;
 
818
        }
 
819
    }
 
820
    IceWriteAuthFileEntry (ed->fp, auth);
 
821
    ed->nwritten++;
 
822
 
 
823
    return 0;
 
824
}
 
825
 
 
826
 
 
827
static int match_auth (
 
828
    register IceAuthFileEntry *a,
 
829
    register IceAuthFileEntry *b,
 
830
    int *authDataSame)
 
831
{
 
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;
 
835
 
 
836
    if (match)
 
837
    {
 
838
        *authDataSame = (a->auth_data_length == b->auth_data_length &&
 
839
            binaryEqual (a->auth_data, b->auth_data, a->auth_data_length));
 
840
    }
 
841
    else
 
842
        *authDataSame = 0;
 
843
 
 
844
    return (match);
 
845
}
 
846
 
 
847
 
 
848
static int merge_entries (
 
849
    AuthList **firstp, AuthList *second,
 
850
    int *nnewp, int *nreplp, int *ndupp)
 
851
{
 
852
    AuthList *a, *b, *first, *tail;
 
853
    int n = 0, nnew = 0, nrepl = 0, ndup = 0;
 
854
 
 
855
    if (!second) return 0;
 
856
 
 
857
    if (!*firstp) {                     /* if nothing to merge into */
 
858
        *firstp = second;
 
859
        for (tail = *firstp, n = 1; tail->next; n++, tail = tail->next) ;
 
860
        *nnewp = n;
 
861
        *nreplp = 0;
 
862
        *ndupp = 0;
 
863
        return n;
 
864
    }
 
865
 
 
866
    first = *firstp;
 
867
    /*
 
868
     * find end of first list and stick second list on it
 
869
     */
 
870
    for (tail = first; tail->next; tail = tail->next) ;
 
871
    tail->next = second;
 
872
 
 
873
    /*
 
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
 
876
     * the chain.
 
877
     */
 
878
    for (b = second; b; ) {
 
879
        AuthList *next = b->next;       /* in case we free it */
 
880
        int duplicate;
 
881
 
 
882
        duplicate = 0;
 
883
        a = first;
 
884
        for (;;) {
 
885
            int authDataSame;
 
886
            if (match_auth (a->auth, b->auth, &authDataSame)) {
 
887
                if (authDataSame)
 
888
                {
 
889
                    /* found a complete duplicate, ignore */
 
890
                    duplicate = 1;
 
891
                    break;
 
892
                }
 
893
                else
 
894
                {
 
895
                    /* found a duplicate, but auth data differs */
 
896
 
 
897
                    AuthList tmp;               /* swap it in for old one */
 
898
                    tmp = *a;
 
899
                    *a = *b;
 
900
                    *b = tmp;
 
901
                    a->next = b->next;
 
902
                    IceFreeAuthFileEntry (b->auth);
 
903
                    free ((char *) b);
 
904
                    b = NULL;
 
905
                    tail->next = next;
 
906
                    nrepl++;
 
907
                    nnew--;
 
908
                    break;
 
909
                }
 
910
            }
 
911
            if (a == tail) break;       /* if have looked at left side */
 
912
            a = a->next;
 
913
        }
 
914
        if (!duplicate && b) {          /* if we didn't remove it */
 
915
            tail = b;                   /* bump end of first list */
 
916
        }
 
917
        b = next;
 
918
 
 
919
        if (duplicate)
 
920
            ndup++;
 
921
        else
 
922
        {
 
923
            n++;
 
924
            nnew++;
 
925
        }
 
926
    }
 
927
 
 
928
    *nnewp = nnew;
 
929
    *nreplp = nrepl;
 
930
    *ndupp = ndup;
 
931
    return n;
 
932
 
 
933
}
 
934
 
 
935
 
 
936
static int search_and_do (
 
937
    const char *inputfilename,
 
938
    int lineno,
 
939
    int start,
 
940
    int argc,
 
941
    char *argv[],
 
942
    DoFunc do_func,
 
943
    char *data)
 
944
{
 
945
    int i;
 
946
    int status = 0;
 
947
    int errors = 0;
 
948
    AuthList *l, *next;
 
949
    char *protoname, *protodata, *netid, *authname;
 
950
 
 
951
    for (l = iceauth_head; l; l = next)
 
952
    {
 
953
        next = l->next;
 
954
 
 
955
        protoname = protodata = netid = authname = NULL;
 
956
 
 
957
        for (i = start; i < argc; i++)
 
958
        {
 
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))
 
964
                netid = argv[i] + 6;
 
965
            else if (!strncmp ("authname=", argv[i], 9))
 
966
                authname = argv[i] + 9;
 
967
        }
 
968
 
 
969
        status = 0;
 
970
 
 
971
        if (protoname || protodata || netid || authname)
 
972
        {
 
973
            if (protoname && strcmp (protoname, l->auth->protocol_name))
 
974
                continue;
 
975
 
 
976
            if (protodata && !binaryEqual (protodata,
 
977
                l->auth->protocol_data, l->auth->protocol_data_length))
 
978
                continue;
 
979
 
 
980
            if (netid && strcmp (netid, l->auth->network_id))
 
981
                continue;
 
982
 
 
983
            if (authname && strcmp (authname, l->auth->auth_name))
 
984
                continue;
 
985
 
 
986
            status = (*do_func) (inputfilename, lineno, l->auth, data);
 
987
 
 
988
            if (status < 0)
 
989
                break;
 
990
        }
 
991
    }
 
992
 
 
993
    if (status < 0)
 
994
        errors -= status;               /* since status is negative */
 
995
 
 
996
    return (errors);
 
997
}
 
998
 
 
999
 
 
1000
/* ARGSUSED */
 
1001
static int remove_entry (
 
1002
    const char *inputfilename,
 
1003
    int lineno,
 
1004
    IceAuthFileEntry *auth,
 
1005
    char *data)
 
1006
{
 
1007
    int *nremovedp = (int *) data;
 
1008
    AuthList **listp = &iceauth_head;
 
1009
    AuthList *list;
 
1010
 
 
1011
    /*
 
1012
     * unlink the auth we were asked to
 
1013
     */
 
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;
 
1020
    (*nremovedp)++;
 
1021
    return 1;
 
1022
}
 
1023
 
 
1024
/*
 
1025
 * action routines
 
1026
 */
 
1027
 
 
1028
/*
 
1029
 * help
 
1030
 */
 
1031
int print_help (
 
1032
    FILE *fp,
 
1033
    const char *cmd)
 
1034
{
 
1035
    const CommandTable *ct;
 
1036
    int n = 0;
 
1037
 
 
1038
    fprintf (fp, "\n");
 
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);
 
1042
            n++;
 
1043
        }
 
1044
    } else {
 
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);
 
1049
                n++;
 
1050
            }
 
1051
        }
 
1052
    }
 
1053
        
 
1054
    return n;
 
1055
}
 
1056
 
 
1057
static int do_help (
 
1058
    const char *inputfilename,
 
1059
    int lineno,
 
1060
    int argc,
 
1061
    char **argv)
 
1062
{
 
1063
    char *cmd = (argc > 1 ? argv[1] : NULL);
 
1064
    int n;
 
1065
 
 
1066
    n = print_help (stdout, cmd);
 
1067
 
 
1068
    if (n < 0 || (n == 0 && !cmd)) {
 
1069
        prefix (inputfilename, lineno);
 
1070
        fprintf (stderr, "internal error with help");
 
1071
        if (cmd) {
 
1072
            fprintf (stderr, " on command \"%s\"", cmd);
 
1073
        }
 
1074
        fprintf (stderr, "\n");
 
1075
        return 1;
 
1076
    }
 
1077
 
 
1078
    if (n == 0) {
 
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);
 
1082
    }
 
1083
 
 
1084
    return 0;
 
1085
}
 
1086
 
 
1087
/*
 
1088
 * questionmark
 
1089
 */
 
1090
/* ARGSUSED */
 
1091
static int do_questionmark (
 
1092
    const char *inputfilename,
 
1093
    int lineno,
 
1094
    int argc,
 
1095
    char **argv)
 
1096
{
 
1097
    const CommandTable *ct;
 
1098
    int i;
 
1099
#define WIDEST_COLUMN 72
 
1100
    int col = WIDEST_COLUMN;
 
1101
 
 
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);
 
1107
            }
 
1108
            fputs ("        ", stdout);
 
1109
            col = 8;                    /* length of string above */
 
1110
        }
 
1111
        fputs (ct->name, stdout);
 
1112
        col += ct->maxlen;
 
1113
        for (i = ct->maxlen; i < COMMAND_NAMES_PADDED_WIDTH; i++) {
 
1114
            putc (' ', stdout);
 
1115
            col++;
 
1116
        }
 
1117
    }
 
1118
    if (col != 0) {
 
1119
        putc ('\n', stdout);
 
1120
    }
 
1121
 
 
1122
    /* allow bad lines since this is help */
 
1123
    return 0;
 
1124
}
 
1125
 
 
1126
/*
 
1127
 * list [displayname ...]
 
1128
 */
 
1129
static int do_list (
 
1130
    const char *inputfilename,
 
1131
    int lineno,
 
1132
    int argc,
 
1133
    char **argv)
 
1134
{
 
1135
    struct _list_data ld;
 
1136
 
 
1137
    ld.fp = stdout;
 
1138
 
 
1139
    if (argc == 1) {
 
1140
        register AuthList *l;
 
1141
 
 
1142
        if (iceauth_head) {
 
1143
            for (l = iceauth_head; l; l = l->next) {
 
1144
                dump_entry (inputfilename, lineno, l->auth, (char *) &ld);
 
1145
            }
 
1146
        }
 
1147
        return 0;
 
1148
    }
 
1149
    else
 
1150
    {
 
1151
        return (search_and_do (inputfilename, lineno, 1, argc, argv,
 
1152
            dump_entry, (char *) &ld));
 
1153
    }
 
1154
}
 
1155
 
 
1156
/*
 
1157
 * merge filename [filename ...]
 
1158
 */
 
1159
static int do_merge (
 
1160
    const char *inputfilename,
 
1161
    int lineno,
 
1162
    int argc,
 
1163
    char **argv)
 
1164
{
 
1165
    int i;
 
1166
    int errors = 0;
 
1167
    AuthList *head, *tail, *listhead, *listtail;
 
1168
    int nentries, nnew, nrepl, ndup;
 
1169
 
 
1170
    if (argc < 2) {
 
1171
        prefix (inputfilename, lineno);
 
1172
        badcommandline (argv[0]);
 
1173
        return 1;
 
1174
    }
 
1175
 
 
1176
    listhead = listtail = NULL;
 
1177
 
 
1178
    for (i = 1; i < argc; i++) {
 
1179
        char *filename = argv[i];
 
1180
        FILE *fp;
 
1181
        Bool used_stdin = False;
 
1182
 
 
1183
        fp = open_file (&filename, "rb",
 
1184
                        &used_stdin, inputfilename, lineno,
 
1185
                        argv[0]);
 
1186
        if (!fp) {
 
1187
            errors++;
 
1188
            continue;
 
1189
        }
 
1190
 
 
1191
        head = tail = NULL;
 
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",
 
1196
                     filename);
 
1197
            errors++;
 
1198
        } else {                        /* link it in */
 
1199
            add_to_list (listhead, listtail, head);
 
1200
        }
 
1201
 
 
1202
        if (!used_stdin) (void) fclose (fp);
 
1203
    }
 
1204
 
 
1205
    /*
 
1206
     * if we have new entries, merge them in (freeing any duplicates)
 
1207
     */
 
1208
    if (listhead) {
 
1209
        nentries = merge_entries (&iceauth_head, listhead,
 
1210
            &nnew, &nrepl, &ndup);
 
1211
        if (verbose) 
 
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;
 
1215
    }
 
1216
 
 
1217
    return 0;
 
1218
}
 
1219
 
 
1220
/*
 
1221
 * extract filename displayname [displayname ...]
 
1222
 */
 
1223
static int do_extract (
 
1224
    const char *inputfilename,
 
1225
    int lineno,
 
1226
    int argc,
 
1227
    char **argv)
 
1228
{
 
1229
    int errors;
 
1230
    struct _extract_data ed;
 
1231
 
 
1232
    if (argc < 3) {
 
1233
        prefix (inputfilename, lineno);
 
1234
        badcommandline (argv[0]);
 
1235
        return 1;
 
1236
    }
 
1237
 
 
1238
    ed.fp = NULL;
 
1239
    ed.filename = argv[1];
 
1240
    ed.nwritten = 0;
 
1241
    ed.cmd = argv[0];
 
1242
 
 
1243
    errors = search_and_do (inputfilename, lineno, 2, argc, argv, 
 
1244
        extract_entry, (char *) &ed);
 
1245
 
 
1246
    if (!ed.fp) {
 
1247
        fprintf (stderr, 
 
1248
                 "No matches found, authority file \"%s\" not written\n",
 
1249
                 ed.filename);
 
1250
    } else {
 
1251
        if (verbose) {
 
1252
            printf ("%d entries written to \"%s\"\n", 
 
1253
                    ed.nwritten, ed.filename);
 
1254
        }
 
1255
        if (!ed.used_stdout) {
 
1256
            (void) fclose (ed.fp);
 
1257
        }
 
1258
    }
 
1259
 
 
1260
    return errors;
 
1261
}
 
1262
 
 
1263
 
 
1264
/*
 
1265
 * add protoname protodata netid authname authdata
 
1266
 */
 
1267
static int do_add (
 
1268
    const char *inputfilename,
 
1269
    int lineno,
 
1270
    int argc,
 
1271
    char **argv)
 
1272
 
1273
    int n, nnew, nrepl, ndup;
 
1274
    char *protoname;
 
1275
    char *protodata_hex;
 
1276
    char *protodata = NULL; /* not required */
 
1277
    char *netid;
 
1278
    char *authname;
 
1279
    char *authdata_hex;
 
1280
    char *authdata = NULL;
 
1281
    int protodata_len, authdata_len;
 
1282
    IceAuthFileEntry *auth = NULL;
 
1283
    AuthList *list;
 
1284
    int status = 0;
 
1285
 
 
1286
    if (argc != 6 || !argv[1] || !argv[2] ||
 
1287
        !argv[3] || !argv[4] || !argv[5])
 
1288
    {
 
1289
        prefix (inputfilename, lineno);
 
1290
        badcommandline (argv[0]);
 
1291
        return 1;
 
1292
    }
 
1293
 
 
1294
    protoname = argv[1];
 
1295
    protodata_hex = argv[2];
 
1296
    netid = argv[3];
 
1297
    authname = argv[4];
 
1298
    authdata_hex = argv[5];
 
1299
 
 
1300
    protodata_len = strlen (protodata_hex);
 
1301
    if (protodata_len > 0)
 
1302
    {
 
1303
        if (protodata_hex[0] == '"' && protodata_hex[protodata_len - 1] == '"')
 
1304
        {
 
1305
            protodata = malloc (protodata_len - 1);
 
1306
            if (protodata)
 
1307
            {
 
1308
                strncpy (protodata, protodata_hex + 1, protodata_len - 2);
 
1309
                protodata_len -= 2;
 
1310
            }
 
1311
            else
 
1312
                goto add_bad_malloc;
 
1313
        }
 
1314
        else
 
1315
        {
 
1316
            protodata_len = cvthexkey (protodata_hex, &protodata);
 
1317
            if (protodata_len < 0)
 
1318
            {
 
1319
                prefix (inputfilename, lineno);
 
1320
                fprintf (stderr,
 
1321
               "protodata_hex contains odd number of or non-hex characters\n");
 
1322
                return (1);
 
1323
            }
 
1324
        }
 
1325
    }
 
1326
 
 
1327
    authdata_len = strlen (authdata_hex);
 
1328
    if (authdata_hex[0] == '"' && authdata_hex[authdata_len - 1] == '"')
 
1329
    {
 
1330
        authdata = malloc (authdata_len - 1);
 
1331
        if (authdata)
 
1332
        {
 
1333
            strncpy (authdata, authdata_hex + 1, authdata_len - 2);
 
1334
            authdata_len -= 2;
 
1335
        }
 
1336
        else
 
1337
            goto add_bad_malloc;
 
1338
    }
 
1339
    else if (!strcmp (protoname, SECURERPC) || !strcmp (protoname, K5AUTH))
 
1340
    {
 
1341
        authdata = malloc (authdata_len + 1);
 
1342
        if (authdata)
 
1343
            strcpy (authdata, authdata_hex);
 
1344
        else
 
1345
            goto add_bad_malloc;
 
1346
    }
 
1347
    else
 
1348
    {
 
1349
        authdata_len = cvthexkey (authdata_hex, &authdata);
 
1350
        if (authdata_len < 0)
 
1351
        {
 
1352
            prefix (inputfilename, lineno);
 
1353
            fprintf (stderr,
 
1354
               "authdata_hex contains odd number of or non-hex characters\n");
 
1355
            free (protodata);
 
1356
            return (1);
 
1357
        }
 
1358
    }
 
1359
 
 
1360
    auth = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry));
 
1361
 
 
1362
    if (!auth)
 
1363
        goto add_bad_malloc;
 
1364
 
 
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;
 
1372
 
 
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))
 
1377
    {
 
1378
        goto add_bad_malloc;
 
1379
    }
 
1380
 
 
1381
    list = (AuthList *) malloc (sizeof (AuthList));
 
1382
 
 
1383
    if (!list)
 
1384
        goto add_bad_malloc;
 
1385
 
 
1386
    list->next = NULL;
 
1387
    list->auth = auth;
 
1388
 
 
1389
    /*
 
1390
     * merge it in; note that merge will deal with allocation
 
1391
     */
 
1392
 
 
1393
    n = merge_entries (&iceauth_head, list, &nnew, &nrepl, &ndup);
 
1394
 
 
1395
    if (n > 0)
 
1396
        iceauth_modified = True;
 
1397
    else
 
1398
    {
 
1399
        prefix (inputfilename, lineno);
 
1400
        if (ndup > 0)
 
1401
        {
 
1402
            status = 0;
 
1403
            fprintf (stderr, "no records added - all duplicate\n");
 
1404
        }
 
1405
        else
 
1406
        {
 
1407
            status = 1;
 
1408
            fprintf (stderr, "unable to merge in added record\n");
 
1409
        }
 
1410
        goto cant_add;
 
1411
    }
 
1412
 
 
1413
    return 0;
 
1414
 
 
1415
 
 
1416
add_bad_malloc:
 
1417
 
 
1418
    status = 1;
 
1419
    prefix (inputfilename, lineno);
 
1420
    fprintf (stderr, "unable to allocate memory to add an entry\n");
 
1421
 
 
1422
cant_add:
 
1423
 
 
1424
    if (protodata)
 
1425
        free (protodata);
 
1426
    if (authdata)
 
1427
        free (authdata);
 
1428
    if (auth)
 
1429
    {
 
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);
 
1441
    }
 
1442
 
 
1443
    return status;
 
1444
}
 
1445
 
 
1446
/*
 
1447
 * remove displayname
 
1448
 */
 
1449
static int do_remove (
 
1450
    const char *inputfilename,
 
1451
    int lineno,
 
1452
    int argc,
 
1453
    char **argv)
 
1454
{
 
1455
    int nremoved = 0;
 
1456
    int errors;
 
1457
 
 
1458
    if (argc < 2) {
 
1459
        prefix (inputfilename, lineno);
 
1460
        badcommandline (argv[0]);
 
1461
        return 1;
 
1462
    }
 
1463
 
 
1464
    errors = search_and_do (inputfilename, lineno, 1, argc, argv,
 
1465
        remove_entry, (char *) &nremoved);
 
1466
    if (verbose) printf ("%d entries removed\n", nremoved);
 
1467
    return errors;
 
1468
}
 
1469
 
 
1470
/*
 
1471
 * info
 
1472
 */
 
1473
static int do_info (
 
1474
    const char *inputfilename,
 
1475
    int lineno,
 
1476
    int argc,
 
1477
    char **argv)
 
1478
{
 
1479
    int n;
 
1480
    AuthList *l;
 
1481
 
 
1482
    if (argc != 1) {
 
1483
        prefix (inputfilename, lineno);
 
1484
        badcommandline (argv[0]);
 
1485
        return 1;
 
1486
    }
 
1487
 
 
1488
    for (l = iceauth_head, n = 0; l; l = l->next, n++) ;
 
1489
 
 
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);
 
1498
    return 0;
 
1499
}
 
1500
 
 
1501
 
 
1502
/*
 
1503
 * exit
 
1504
 */
 
1505
static Bool alldone = False;
 
1506
 
 
1507
/* ARGSUSED */
 
1508
static int do_exit (
 
1509
    const char *inputfilename,
 
1510
    int lineno,
 
1511
    int argc,
 
1512
    char **argv)
 
1513
{
 
1514
    /* allow bogus stuff */
 
1515
    alldone = True;
 
1516
    return 0;
 
1517
}
 
1518
 
 
1519
/*
 
1520
 * quit
 
1521
 */
 
1522
/* ARGSUSED */
 
1523
static int do_quit (
 
1524
    const char *inputfilename,
 
1525
    int lineno,
 
1526
    int argc,
 
1527
    char **argv)
 
1528
{
 
1529
    /* allow bogus stuff */
 
1530
    die (0);
 
1531
    /* NOTREACHED */
 
1532
    return -1;                          /* for picky compilers */
 
1533
}
 
1534
 
 
1535
 
 
1536
/*
 
1537
 * source filename
 
1538
 */
 
1539
static int do_source (
 
1540
    const char *inputfilename,
 
1541
    int lineno,
 
1542
    int argc,
 
1543
    char **argv)
 
1544
{
 
1545
    char *script;
 
1546
    char buf[BUFSIZ];
 
1547
    FILE *fp;
 
1548
    Bool used_stdin = False;
 
1549
    int len;
 
1550
    int errors = 0, status;
 
1551
    int sublineno = 0;
 
1552
    char **subargv;
 
1553
    int subargc;
 
1554
    Bool prompt = False;                /* only true if reading from tty */
 
1555
 
 
1556
    if (argc != 2 || !argv[1]) {
 
1557
        prefix (inputfilename, lineno);
 
1558
        badcommandline (argv[0]);
 
1559
        return 1;
 
1560
    }
 
1561
 
 
1562
    script = argv[1];
 
1563
 
 
1564
    fp = open_file (&script, "r", &used_stdin, inputfilename, lineno, argv[0]);
 
1565
    if (!fp) {
 
1566
        return 1;
 
1567
    }
 
1568
 
 
1569
    if (verbose && used_stdin && isatty (fileno (fp))) prompt = True;
 
1570
 
 
1571
    while (!alldone) {
 
1572
        buf[0] = '\0';
 
1573
        if (prompt) {
 
1574
            printf ("iceauth> ");
 
1575
            fflush (stdout);
 
1576
        }
 
1577
        if (fgets (buf, sizeof buf, fp) == NULL) break;
 
1578
        sublineno++;
 
1579
        len = strlen (buf);
 
1580
        if (len == 0 || buf[0] == '#') continue;
 
1581
        if (buf[len-1] != '\n') {
 
1582
            prefix (script, sublineno);
 
1583
            fprintf (stderr, "line too long\n");
 
1584
            errors++;
 
1585
            break;
 
1586
        }
 
1587
        buf[--len] = '\0';              /* remove new line */
 
1588
        subargv = split_into_words (buf, &subargc);
 
1589
        if (subargv) {
 
1590
            status = process_command (script, sublineno, subargc, subargv);
 
1591
            free ((char *) subargv);
 
1592
            errors += status;
 
1593
        } else {
 
1594
            prefix (script, sublineno);
 
1595
            fprintf (stderr, "unable to break line into words\n");
 
1596
            errors++;
 
1597
        }
 
1598
    }
 
1599
 
 
1600
    if (!used_stdin) {
 
1601
        (void) fclose (fp);
 
1602
    }
 
1603
    return errors;
 
1604
}