Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37728057
en ru br
ALT Linux repos
S:1.0.9-alt1
5.0: 1.0.2-alt1
4.1: 1.0.2-alt1
4.0: 1.0.1-alt3

Group :: System/X11
RPM: iceauth

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

pax_global_header00006660000000000000000000000064114627214170014517gustar00rootroot0000000000000052 comment=b39fab5b9af70282ab640a8a9d6b56671aeda78b
iceauth-1.0.4/000075500000000000000000000000001146272141700131415ustar00rootroot00000000000000iceauth-1.0.4/.gitignore000064400000000000000000000017601146272141700151350ustar00rootroot00000000000000#
# X.Org module default exclusion patterns
# The next section if for module specific patterns
#
# Do not edit the following section
# GNU Build System (Autotools)
aclocal.m4
autom4te.cache/
autoscan.log
ChangeLog
compile
config.guess
config.h
config.h.in
config.log
config-ml.in
config.py
config.status
config.status.lineno
config.sub
configure
configure.scan
depcomp
.deps/
INSTALL
install-sh
.libs/
libtool
libtool.m4
ltmain.sh
lt~obsolete.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
Makefile
Makefile.in
mdate-sh
missing
mkinstalldirs
*.pc
py-compile
stamp-h?
symlink-tree
texinfo.tex
ylwrap

# Do not edit the following section
# Edit Compile Debug Document Distribute
*~
*.[0-9]
*.[0-9]x
*.bak
*.bin
core
*.dll
*.exe
*-ISO*.bdf
*-JIS*.bdf
*-KOI8*.bdf
*.kld
*.ko
*.ko.cmd
*.lai
*.l[oa]
*.[oa]
*.obj
*.patch
*.so
*.pcf.gz
*.pdb
*.tar.bz2
*.tar.gz
#
# Add & Override patterns for iceauth
#
# Edit the following section as needed
# For example, !report.pc overrides *.pc. See 'man gitignore'
#
iceauth
iceauth-1.0.4/COPYING000064400000000000000000000021611146272141700141740ustar00rootroot00000000000000Copyright 1989, 1998 The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.

iceauth-1.0.4/Makefile.am000064400000000000000000000037551146272141700152070ustar00rootroot00000000000000#
# Copyright 2005 Red Hat, Inc.
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of Red Hat not be used in
# advertising or publicity pertaining to distribution of the software without
# specific, written prior permission. Red Hat makes no
# representations about the suitability of this software for any purpose. It
# is provided "as is" without express or implied warranty.
#
# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.

bin_PROGRAMS = iceauth

AM_CFLAGS = $(CWARNFLAGS) $(ICEAUTH_CFLAGS)
iceauth_LDADD = $(ICEAUTH_LIBS)

iceauth_SOURCES = \
iceauth.c \
iceauth.h \
process.c

appman_PRE = \
iceauth.man


appmandir = $(APP_MAN_DIR)

appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@)

EXTRA_DIST = $(appman_PRE) autogen.sh
MAINTAINERCLEANFILES = ChangeLog INSTALL
CLEANFILES = $(appman_DATA)


.PHONY: ChangeLog INSTALL

INSTALL:
$(INSTALL_CMD)

ChangeLog:
$(CHANGELOG_CMD)

dist-hook: ChangeLog INSTALL

SUFFIXES = .$(APP_MAN_SUFFIX) .man

# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
.man.$(APP_MAN_SUFFIX):
$(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@

if LINT
ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
lint:
$(LINT) $(ALL_LINT_FLAGS) $(iceauth_SOURCES)
endif LINT
iceauth-1.0.4/README000064400000000000000000000014751146272141700140300ustar00rootroot00000000000000The iceauth program is used to edit and display the authorization
information used in connecting with ICE. It operates very much
like the xauth program for X11 connection authentication records.

All questions regarding this software should be directed at the
Xorg mailing list:

http://lists.freedesktop.org/mailman/listinfo/xorg

Please submit bug reports to the Xorg bugzilla:

https://bugs.freedesktop.org/enter_bug.cgi?product=xorg

The master development code repository can be found at:

git://anongit.freedesktop.org/git/xorg/app/iceauth

http://cgit.freedesktop.org/xorg/app/iceauth

For patch submission instructions, see:

http://www.x.org/wiki/Development/Documentation/SubmittingPatches

For more information on the git code manager, see:

http://wiki.x.org/wiki/GitPage

iceauth-1.0.4/autogen.sh000075500000000000000000000003041146272141700151370ustar00rootroot00000000000000#! /bin/sh

srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.

ORIGDIR=`pwd`
cd $srcdir

autoreconf -v --install || exit 1
cd $ORIGDIR || exit $?

$srcdir/configure --enable-maintainer-mode "$@"

iceauth-1.0.4/configure.ac000064400000000000000000000034621146272141700154340ustar00rootroot00000000000000
dnl Copyright 2005 Red Hat, Inc.
dnl
dnl Permission to use, copy, modify, distribute, and sell this software and its
dnl documentation for any purpose is hereby granted without fee, provided that
dnl the above copyright notice appear in all copies and that both that
dnl copyright notice and this permission notice appear in supporting
dnl documentation, and that the name of Red Hat not be used in
dnl advertising or publicity pertaining to distribution of the software without
dnl specific, written prior permission. Red Hat makes no
dnl representations about the suitability of this software for any purpose. It
dnl is provided "as is" without express or implied warranty.
dnl
dnl RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
dnl EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
dnl DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
dnl TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dnl PERFORMANCE OF THIS SOFTWARE.
dnl
dnl Process this file with autoconf to create configure.

AC_PREREQ([2.60])
AC_INIT([iceauth], [1.0.4],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [iceauth])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE

AM_CONFIG_HEADER(config.h)

# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
m4_ifndef([XORG_MACROS_VERSION],
[m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
XORG_MACROS_VERSION(1.8)

AC_PROG_CC
AC_PROG_INSTALL

AC_TYPE_SIGNAL

XORG_DEFAULT_OPTIONS

# Checks for pkg-config packages
PKG_CHECK_MODULES(ICEAUTH, xproto ice)

XORG_WITH_LINT

AC_OUTPUT([Makefile])
iceauth-1.0.4/iceauth.c000064400000000000000000000103401146272141700147250ustar00rootroot00000000000000/*
* xauth - manipulate authorization file
*
*
Copyright 1989, 1998 The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
* *
* Original Author of "xauth" : Jim Fulton, MIT X Consortium
* Modified into "iceauth" : Ralph Mor, X Consortium
*/

#include "iceauth.h"


/*
* global data
*/
const char *ProgramName; /* argv[0], set at top of main() */
int verbose = -1; /* print certain messages */
Bool ignore_locks = False; /* for error recovery */
Bool break_locks = False; /* for error recovery */

/*
* local data
*/

static char *authfilename = NULL; /* filename of cookie file */
static char *defcmds[] = { "source", "-", NULL }; /* default command */
static int ndefcmds = 2;
static const char *defsource = "(stdin)";


/*
* utility routines
*/
static void usage (void)
{
static const char prefixmsg[] =
"\n"
"where options include:\n"
" -f authfilename name of authority file to use\n"
" -v turn on extra messages\n"
" -q turn off extra messages\n"
" -i ignore locks on authority file\n"
" -b break locks on authority file\n"
"\n"
"and commands have the following syntax:\n";
static const char suffixmsg[] =
"A dash may be used with the \"merge\" and \"source\" to read from the\n"
"standard input. Commands beginning with \"n\" use numeric format.\n";

fprintf (stderr, "usage: %s [-options ...] [command arg ...]\n",
ProgramName);
fprintf (stderr, "%s\n", prefixmsg);
print_help (stderr, " "); /* match prefix indentation */
fprintf (stderr, "\n%s\n", suffixmsg);
exit (1);
}


/*
* The main routine - parses command line and calls action procedures
*/
int
main (int argc, char *argv[])
{
int i;
const char *sourcename = defsource;
char **arglist = defcmds;
int nargs = ndefcmds;
int status;

ProgramName = argv[0];

for (i = 1; i < argc; i++) {
char *arg = argv[i];

if (arg[0] == '-') {
char *flag;

for (flag = (arg + 1); *flag; flag++) {
switch (*flag) {
case 'f': /* -f authfilename */
if (++i >= argc) usage ();
authfilename = argv[i];
continue;
case 'v': /* -v */
verbose = 1;
continue;
case 'q': /* -q */
verbose = 0;
continue;
case 'b': /* -b */
break_locks = True;
continue;
case 'i': /* -i */
ignore_locks = True;
continue;
default:
usage ();
}
}
} else {
sourcename = "(argv)";
nargs = argc - i;
arglist = argv + i;
if (verbose == -1) verbose = 0;
break;
}
}

if (verbose == -1) { /* set default, don't junk stdout */
verbose = (isatty(fileno(stdout)) != 0);
}

if (!authfilename) {
authfilename = IceAuthFileName (); /* static name, do not free */
if (!authfilename) {
fprintf (stderr,
"%s: unable to generate an authority file name\n",
ProgramName);
exit (1);
}
}
if (auth_initialize (authfilename) != 0) {
/* error message printed in auth_initialize */
exit (1);
}

status = process_command (sourcename, 1, nargs, arglist);

(void) auth_finalize ();
exit ((status != 0) ? 1 : 0);
}
iceauth-1.0.4/iceauth.h000064400000000000000000000034021146272141700147330ustar00rootroot00000000000000/*
*
Copyright 1989, 1998 The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
* *
* Author: Jim Fulton, MIT X Consortium
*/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h>
#include <X11/Xos.h>
#include <X11/ICE/ICElib.h>
#include <X11/ICE/ICEutil.h>
#include <X11/Xfuncs.h>

#ifndef True
typedef int Bool;
#define False 0
#define True 1
#endif

extern const char *ProgramName;

#include <stdlib.h>

extern int auth_initialize ( char *authfilename );
extern int auth_finalize ( void );
extern int process_command ( const char *inputfilename, int lineno, int argc, char **argv );
extern int print_help ( FILE *fp, const char *cmd );

extern int verbose;
extern Bool ignore_locks;
extern Bool break_locks;
iceauth-1.0.4/iceauth.man000064400000000000000000000035271146272141700152670ustar00rootroot00000000000000.\" Copyright 1994, 1998 The Open Group
.\"
.\" Permission to use, copy, modify, distribute, and sell this software and its
.\" documentation for any purpose is hereby granted without fee, provided that
.\" the above copyright notice appear in all copies and that both that
.\" copyright notice and this permission notice appear in supporting
.\" documentation.
.\"
.\" The above copyright notice and this permission notice shall be included in
.\" all copies or substantial portions of the Software.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
.\" THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
.\" OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
.\" SOFTWARE.
.\"
.\" Except as contained in this notice, the name of The Open Group shall not
.\" be used in advertising or otherwise to promote the sale, use or other
.\" dealing in this Software without prior written authorization from the
.\" The Open Group.
.\"
.TH ICEAUTH 1 __xorgversion__
.SH NAME
iceauth \- ICE authority file utility
.SH SYNOPSIS
.B iceauth
[ \fB\-f\fP \fIauthfile\fP ] [ \fB\-vqib\fP ] [ \fIcommand arg ...\fP ]
.SH DESCRIPTION
.PP
The \fIiceauth\fP program is used to edit and display the authorization
information used in connecting with ICE. This program is usually
used to extract authorization records from one machine and merge them in on
another (as is the case when using remote logins or granting access to
other users). Commands (described below) may be entered interactively,
on the \fIiceauth\fP command line, or in scripts.
.SH AUTHOR
Ralph Mor, X Consortium
iceauth-1.0.4/process.c000064400000000000000000001131541146272141700147700ustar00rootroot00000000000000/*
*
Copyright 1989, 1998 The Open Group

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
* *
* Original Author of "xauth" : Jim Fulton, MIT X Consortium
* Modified into "iceauth" : Ralph Mor, X Consortium
*/

#include "iceauth.h"
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>

#define SECURERPC "SUN-DES-1"
#define K5AUTH "KERBEROS-V5-1"

#define ICEAUTH_DEFAULT_RETRIES 10 /* number of competitors we expect */
#define ICEAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */
#define ICEAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */

typedef struct _AuthList { /* linked list of entries */
struct _AuthList *next;
IceAuthFileEntry *auth;
} AuthList;

#define add_to_list(h,t,e) {if (t) (t)->next = (e); else (h) = (e); (t) = (e);}

typedef int (*ProcessFunc)(const char *, int, int, char **);
typedef int (*DoFunc)(const char *, int, IceAuthFileEntry *, char *);

typedef struct _CommandTable { /* commands that are understood */
char *name; /* full name */
int minlen; /* unique prefix */
int maxlen; /* strlen(name) */
ProcessFunc processfunc; /* handler */
char *helptext; /* what to print for help */
} CommandTable;

struct _extract_data { /* for iterating */
FILE *fp; /* input source */
char *filename; /* name of input */
Bool used_stdout; /* whether or not need to close */
int nwritten; /* number of entries written */
char *cmd; /* for error messages */
};

struct _list_data { /* for iterating */
FILE *fp; /* output file */
};


/*
* private data
*/
static char *stdin_filename = "(stdin)"; /* for messages */
static char *stdout_filename = "(stdout)"; /* for messages */
static const char *Yes = "yes"; /* for messages */
static const char *No = "no"; /* for messages */

static int binaryEqual ( const char *a, const char *b, unsigned len );
static void prefix ( const char *fn, int n );
static void badcommandline ( const char *cmd );
static char *skip_space ( char *s );
static char *skip_nonspace ( char *s );
static char **split_into_words ( char *src, int *argcp );
static FILE *open_file ( char **filenamep, const char *mode, Bool *usedstdp, const char *srcfn, int srcln, const char *cmd );
static int read_auth_entries ( FILE *fp, AuthList **headp, AuthList **tailp );
static int cvthexkey ( char *hexstr, char **ptrp );
static int dispatch_command ( const char *inputfilename, int lineno, int argc, char **argv, const CommandTable *tab, int *statusp );
static void die ( int sig );
static void catchsig ( int sig );
static void register_signals ( void );
static int write_auth_file ( char *tmp_nam, size_t tmp_nam_len );
static void fprintfhex ( FILE *fp, unsigned int len, const char *cp );
static int dump_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, char *data );
static int extract_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, char *data );
static int match_auth ( IceAuthFileEntry *a, IceAuthFileEntry *b, int *authDataSame );
static int merge_entries ( AuthList **firstp, AuthList *second, int *nnewp, int *nreplp, int *ndupp );
static int search_and_do ( const char *inputfilename, int lineno, int start, int argc, char *argv[], DoFunc do_func, char *data );
static int remove_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, char *data );
static int do_help ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_questionmark ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_list ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_merge ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_extract ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_add ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_remove ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_info ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_exit ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_quit ( const char *inputfilename, int lineno, int argc, char **argv );
static int do_source ( const char *inputfilename, int lineno, int argc, char **argv );

static const CommandTable command_table[] = { /* table of known commands */
{ "add", 2, 3, do_add,
"\
add add an entry\n\
add protoname protodata netid authname authdata"
},

{ "exit", 3, 4, do_exit,
"\
exit save changes and exit program"
},

{ "extract", 3, 7, do_extract,
"\
extract extract entries into file\n\
extract filename <protoname=$> <protodata=$> <netid=$> <authname=$>"
},

{ "help", 1, 4, do_help,
"\
help print help\n\
help <topic>"
},

{ "info", 1, 4, do_info,
"\
info print information about entries"
},

{ "list", 1, 4, do_list,
"\
list list entries\n\
list <protoname=$> <protodata=$> <netid=$> <authname=$>"
},

{ "merge", 1, 5, do_merge,
"\
merge merge entries from files\n\
merge filename1 <filename2> <filename3> ..."
},

{ "quit", 1, 4, do_quit,
"\
quit abort changes and exit program" },

{ "remove", 1, 6, do_remove,
"\
remove remove entries\n\
remove <protoname=$> <protodata=$> <netid=$> <authname=$>"
},

{ "source", 1, 6, do_source,
"\
source read commands from file\n\
source filename"
},

{ "?", 1, 1, do_questionmark,
"\
? list available commands" },

{ NULL, 0, 0, NULL, NULL },
};

#define COMMAND_NAMES_PADDED_WIDTH 10 /* wider than anything above */


static Bool okay_to_use_stdin = True; /* set to false after using */

static const char * const hex_table[] = { /* for printing hex digits */
"00", "01", "02", "03", "04", "05", "06", "07",
"08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
"10", "11", "12", "13", "14", "15", "16", "17",
"18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
"20", "21", "22", "23", "24", "25", "26", "27",
"28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
"30", "31", "32", "33", "34", "35", "36", "37",
"38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
"40", "41", "42", "43", "44", "45", "46", "47",
"48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
"50", "51", "52", "53", "54", "55", "56", "57",
"58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
"60", "61", "62", "63", "64", "65", "66", "67",
"68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
"70", "71", "72", "73", "74", "75", "76", "77",
"78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
"80", "81", "82", "83", "84", "85", "86", "87",
"88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
"90", "91", "92", "93", "94", "95", "96", "97",
"98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
"a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
"b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7",
"c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
"d8", "d9", "da", "db", "dc", "dd", "de", "df",
"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7",
"e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
};

static unsigned int hexvalues[256]; /* for parsing hex input */

static mode_t original_umask = 0; /* for restoring */


/*
* private utility procedures
*/

#define copystring(s) ( s != NULL ? strdup(s) : NULL )

static int
binaryEqual (
register const char *a,
register const char *b,
register unsigned len)

{
while (len--)
if (*a++ != *b++)
return 0;
return 1;
}

static void prefix (const char *fn, int n)
{
fprintf (stderr, "%s: %s:%d: ", ProgramName, fn, n);
}

static void badcommandline (const char *cmd)
{
fprintf (stderr, "bad \"%s\" command line\n", cmd);
}

static char *skip_space (register char *s)
{
if (!s) return NULL;

for ( ; *s && isascii(*s) && isspace(*s); s++)
;
return s;
}


static char *skip_nonspace (register char *s)
{
if (!s) return NULL;

/* put quoting into loop if need be */
for ( ; *s && isascii(*s) && !isspace(*s); s++)
;
return s;
}

static char **split_into_words ( /* argvify string */
char *src,
int *argcp)
{
char *jword;
char savec;
char **argv;
int cur, total;

*argcp = 0;
#define WORDSTOALLOC 4 /* most lines are short */
argv = (char **) malloc (WORDSTOALLOC * sizeof (char *));
if (!argv) return NULL;
cur = 0;
total = WORDSTOALLOC;

/*
* split the line up into separate, nul-terminated tokens; the last
* "token" will point to the empty string so that it can be bashed into
* a null pointer.
*/

do {
jword = skip_space (src);
src = skip_nonspace (jword);
savec = *src;
*src = '\0';
if (cur == total) {
total += WORDSTOALLOC;
argv = (char **) realloc (argv, total * sizeof (char *));
if (!argv) return NULL;
}
argv[cur++] = jword;
if (savec) src++; /* if not last on line advance */
} while (jword != src);

argv[--cur] = NULL; /* smash empty token to end list */
*argcp = cur;
return argv;
}


static FILE *open_file (
char **filenamep,
const char *mode,
Bool *usedstdp,
const char *srcfn,
int srcln,
const char *cmd)
{
FILE *fp;

if (strcmp (*filenamep, "-") == 0) {
*usedstdp = True;
/* select std descriptor to use */
if (mode[0] == 'r') {
if (okay_to_use_stdin) {
okay_to_use_stdin = False;
*filenamep = stdin_filename;
return stdin;
} else {
prefix (srcfn, srcln);
fprintf (stderr, "%s: stdin already in use\n", cmd);
return NULL;
}
} else {
*filenamep = stdout_filename;
return stdout; /* always okay to use stdout */
}
}

fp = fopen (*filenamep, mode);
if (!fp) {
prefix (srcfn, srcln);
fprintf (stderr, "%s: unable to open file %s\n", cmd, *filenamep);
}
return fp;
}


static int read_auth_entries (FILE *fp, AuthList **headp, AuthList **tailp)
{
IceAuthFileEntry *auth;
AuthList *head, *tail;
int n;

head = tail = NULL;
n = 0;
/* put all records into linked list */
while ((auth = IceReadAuthFileEntry (fp)) != NULL) {
AuthList *l = (AuthList *) malloc (sizeof (AuthList));
if (!l) {
fprintf (stderr,
"%s: unable to alloc entry reading auth file\n",
ProgramName);
exit (1);
}
l->next = NULL;
l->auth = auth;
if (tail) /* if not first time through append */
tail->next = l;
else
head = l; /* first time through, so assign */
tail = l;
n++;
}
*headp = head;
*tailp = tail;
return n;
}


static int cvthexkey ( /* turn hex key string into octets */
char *hexstr,
char **ptrp)
{
int i;
int len = 0;
char *retval, *s;
unsigned char *us;
char c;
char savec = '\0';

/* count */
for (s = hexstr; *s; s++) {
if (!isascii(*s)) return -1;
if (isspace(*s)) continue;
if (!isxdigit(*s)) return -1;
len++;
}

/* if odd then there was an error */
if ((len & 1) == 1) return -1;


/* now we know that the input is good */
len >>= 1;
retval = malloc (len);
if (!retval) {
fprintf (stderr, "%s: unable to allocate %d bytes for hexkey\n",
ProgramName, len);
return -1;
}

for (us = (unsigned char *) retval, i = len; i > 0; hexstr++) {
c = *hexstr;
if (isspace(c)) continue; /* already know it is ascii */
if (isupper(c))
c = tolower(c);
if (savec) {
#define atoh(c) ((c) - (((c) >= '0' && (c) <= '9') ? '0' : ('a'-10)))
*us = (unsigned char)((atoh(savec) << 4) + atoh(c));
#undef atoh
savec = 0; /* ready for next character */
us++;
i--;
} else {
savec = c;
}
}
*ptrp = retval;
return len;
}

static int dispatch_command (
const char *inputfilename,
int lineno,
int argc,
char **argv,
const CommandTable *tab,
int *statusp)
{
const CommandTable *ct;
char *cmd;
int n;
/* scan table for command */
cmd = argv[0];
n = strlen (cmd);
for (ct = tab; ct->name; ct++) {
/* look for unique prefix */
if (n >= ct->minlen && n <= ct->maxlen &&
strncmp (cmd, ct->name, n) == 0) {
*statusp = (*(ct->processfunc))(inputfilename, lineno, argc, argv);
return 1;
}
}

*statusp = 1;
return 0;
}


static AuthList *iceauth_head = NULL; /* list of auth entries */
static Bool iceauth_existed = False; /* if was present at initialize */
static Bool iceauth_modified = False; /* if added, removed, or merged */
static Bool iceauth_allowed = True; /* if allowed to write auth file */
static char *iceauth_filename = NULL;
static volatile Bool dieing = False;

#ifdef RETSIGTYPE /* autoconf AC_TYPE_SIGNAL */
# define _signal_t RETSIGTYPE
#else /* Imake */
#ifdef SIGNALRETURNSINT
#define _signal_t int
#else
#define _signal_t void
#endif
#endif /* RETSIGTYPE */

/* poor man's puts(), for under signal handlers */
#define WRITES(fd, S) (void)write((fd), (S), strlen((S)))

/* ARGSUSED */
static _signal_t die (int sig)
{
dieing = True;
_exit (auth_finalize ());
/* NOTREACHED */
#ifdef SIGNALRETURNSINT
return -1; /* for picky compilers */
#endif
}

static _signal_t catchsig (int sig)
{
#ifdef SYSV
if (sig > 0) signal (sig, die); /* re-establish signal handler */
#endif
/*
* fileno() might not be reentrant, avoid it if possible, and use
* stderr instead of stdout
*/
#ifdef STDERR_FILENO
if (verbose && iceauth_modified) WRITES(STDERR_FILENO, "\r\n");
#else
if (verbose && iceauth_modified) WRITES(fileno(stderr), "\r\n");
#endif
die (sig);
/* NOTREACHED */
#ifdef SIGNALRETURNSINT
return -1; /* for picky compilers */
#endif
}

static void register_signals (void)
{
signal (SIGINT, catchsig);
signal (SIGTERM, catchsig);
#ifdef SIGHUP
signal (SIGHUP, catchsig);
#endif
return;
}


/*
* public procedures for parsing lines of input
*/

int auth_initialize ( char *authfilename )
{
int n;
AuthList *head, *tail;
FILE *authfp;
Bool exists;

register_signals ();

bzero ((char *) hexvalues, sizeof hexvalues);
hexvalues['0'] = 0;
hexvalues['1'] = 1;
hexvalues['2'] = 2;
hexvalues['3'] = 3;
hexvalues['4'] = 4;
hexvalues['5'] = 5;
hexvalues['6'] = 6;
hexvalues['7'] = 7;
hexvalues['8'] = 8;
hexvalues['9'] = 9;
hexvalues['a'] = hexvalues['A'] = 0xa;
hexvalues['b'] = hexvalues['B'] = 0xb;
hexvalues['c'] = hexvalues['C'] = 0xc;
hexvalues['d'] = hexvalues['D'] = 0xd;
hexvalues['e'] = hexvalues['E'] = 0xe;
hexvalues['f'] = hexvalues['F'] = 0xf;

if (break_locks && verbose) {
printf ("Attempting to break locks on authority file %s\n",
authfilename);
}

iceauth_filename = strdup(authfilename);

if (ignore_locks) {
if (break_locks) IceUnlockAuthFile (authfilename);
} else {
n = IceLockAuthFile (authfilename, ICEAUTH_DEFAULT_RETRIES,
ICEAUTH_DEFAULT_TIMEOUT,
(break_locks ? 0L : ICEAUTH_DEFAULT_DEADTIME));
if (n != IceAuthLockSuccess) {
char *reason = "unknown error";
switch (n) {
case IceAuthLockError:
reason = "error";
break;
case IceAuthLockTimeout:
reason = "timeout";
break;
}
fprintf (stderr, "%s: %s in locking authority file %s\n",
ProgramName, reason, authfilename);
return -1;
}
}

/* these checks can only be done reliably after the file is locked */
exists = (access (authfilename, F_OK) == 0);
if (exists && access (authfilename, W_OK) != 0) {
fprintf (stderr,
"%s: %s not writable, changes will be ignored\n",
ProgramName, authfilename);
iceauth_allowed = False;
}

original_umask = umask (0077); /* disallow non-owner access */

authfp = fopen (authfilename, "rb");
if (!authfp) {
int olderrno = errno;

/* if file there then error */
if (access (authfilename, F_OK) == 0) { /* then file does exist! */
errno = olderrno;
return -1;
} /* else ignore it */
fprintf (stderr,
"%s: creating new authority file %s\n",
ProgramName, authfilename);
} else {
iceauth_existed = True;
n = read_auth_entries (authfp, &head, &tail);
(void) fclose (authfp);
if (n < 0) {
fprintf (stderr,
"%s: unable to read auth entries from file \"%s\"\n",
ProgramName, authfilename);
return -1;
}
iceauth_head = head;
}

iceauth_modified = False;

if (verbose) {
printf ("%s authority file %s\n",
ignore_locks ? "Ignoring locks on" : "Using", authfilename);
}
return 0;
}

static int write_auth_file (char *tmp_nam, size_t tmp_nam_len)
{
FILE *fp;
AuthList *list;

if ((strlen(iceauth_filename) + 3) > tmp_nam_len) {
strncpy(tmp_nam, "filename too long", tmp_nam_len);
tmp_nam[tmp_nam_len - 1] = '\0';
return -1;
}

strcpy (tmp_nam, iceauth_filename);
strcat (tmp_nam, "-n"); /* for new */
(void) unlink (tmp_nam);
fp = fopen (tmp_nam, "wb"); /* umask is still set to 0077 */
if (!fp) {
fprintf (stderr, "%s: unable to open tmp file \"%s\"\n",
ProgramName, tmp_nam);
return -1;
}

for (list = iceauth_head; list; list = list->next)
IceWriteAuthFileEntry (fp, list->auth);

(void) fclose (fp);
return 0;
}

int auth_finalize (void)
{
char temp_name[1024]; /* large filename size */

if (iceauth_modified) {
if (dieing) {
if (verbose) {
/*
* called from a signal handler -- printf is *not* reentrant; also
* fileno() might not be reentrant, avoid it if possible, and use
* stderr instead of stdout
*/
#ifdef STDERR_FILENO
WRITES(STDERR_FILENO, "\nAborting changes to authority file ");
WRITES(STDERR_FILENO, iceauth_filename);
WRITES(STDERR_FILENO, "\n");
#else
WRITES(fileno(stderr), "\nAborting changes to authority file ");
WRITES(fileno(stderr), iceauth_filename);
WRITES(fileno(stderr), "\n");
#endif
}
} else if (!iceauth_allowed) {
fprintf (stderr,
"%s: %s not writable, changes ignored\n",
ProgramName, iceauth_filename);
} else {
if (verbose) {
printf ("%s authority file %s\n",
ignore_locks ? "Ignoring locks and writing" :
"Writing", iceauth_filename);
}
temp_name[0] = '\0';
if (write_auth_file (temp_name, sizeof(temp_name)) == -1) {
fprintf (stderr,
"%s: unable to write authority file %s\n",
ProgramName, temp_name);
} else {
(void) unlink (iceauth_filename);
#if defined(WIN32) || defined(__UNIXOS2__)
if (rename(temp_name, iceauth_filename) == -1)
#else
if (link (temp_name, iceauth_filename) == -1)
#endif
{
fprintf (stderr,
"%s: unable to link authority file %s, use %s\n",
ProgramName, iceauth_filename, temp_name);
} else {
(void) unlink (temp_name);
}
}
}
}

if (!ignore_locks && (iceauth_filename != NULL)) {
IceUnlockAuthFile (iceauth_filename);
}
(void) umask (original_umask);
return 0;
}

int process_command (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
int status;

if (argc < 1 || !argv || !argv[0]) return 1;

if (dispatch_command (inputfilename, lineno, argc, argv,
command_table, &status))
return status;

prefix (inputfilename, lineno);
fprintf (stderr, "unknown command \"%s\"\n", argv[0]);
return 1;
}


/*
* utility routines
*/

static void fprintfhex (
register FILE *fp,
unsigned int len,
const char *cp)
{
const unsigned char *ucp = (const unsigned char *) cp;

for (; len > 0; len--, ucp++) {
register const char *s = hex_table[*ucp];
putc (s[0], fp);
putc (s[1], fp);
}
return;
}

/* ARGSUSED */
static int dump_entry (
const char *inputfilename,
int lineno,
IceAuthFileEntry *auth,
char *data)
{
struct _list_data *ld = (struct _list_data *) data;
FILE *fp = ld->fp;

fprintf (fp, "%s", auth->protocol_name);
putc (' ', fp);
if (auth->protocol_data_length > 0)
fprintfhex (fp, auth->protocol_data_length, auth->protocol_data);
else
fprintf (fp, "\"\"");
putc (' ', fp);
fprintf (fp, "%s", auth->network_id);
putc (' ', fp);
fprintf (fp, "%s", auth->auth_name);
putc (' ', fp);

if (auth->auth_data_length == 0)
fprintf (fp, "\"\"");
else if (!strcmp(auth->auth_name, SECURERPC) ||
!strcmp(auth->auth_name, K5AUTH))
fwrite (auth->auth_data, sizeof (char), auth->auth_data_length, fp);
else
fprintfhex (fp, auth->auth_data_length, auth->auth_data);
putc ('\n', fp);

return 0;
}

static int extract_entry (
const char *inputfilename,
int lineno,
IceAuthFileEntry *auth,
char *data)
{
struct _extract_data *ed = (struct _extract_data *) data;

if (!ed->fp) {
ed->fp = open_file (&ed->filename, "wb",
&ed->used_stdout,
inputfilename, lineno, ed->cmd);
if (!ed->fp) {
prefix (inputfilename, lineno);
fprintf (stderr,
"unable to open extraction file \"%s\"\n",
ed->filename);
return -1;
}
}
IceWriteAuthFileEntry (ed->fp, auth);
ed->nwritten++;

return 0;
}


static int match_auth (
register IceAuthFileEntry *a,
register IceAuthFileEntry *b,
int *authDataSame)
{
int match = strcmp (a->protocol_name, b->protocol_name) == 0 &&
strcmp (a->network_id, b->network_id) == 0 &&
strcmp (a->auth_name, b->auth_name) == 0;

if (match)
{
*authDataSame = (a->auth_data_length == b->auth_data_length &&
binaryEqual (a->auth_data, b->auth_data, a->auth_data_length));
}
else
*authDataSame = 0;

return (match);
}


static int merge_entries (
AuthList **firstp, AuthList *second,
int *nnewp, int *nreplp, int *ndupp)
{
AuthList *a, *b, *first, *tail;
int n = 0, nnew = 0, nrepl = 0, ndup = 0;

if (!second) return 0;

if (!*firstp) { /* if nothing to merge into */
*firstp = second;
for (tail = *firstp, n = 1; tail->next; n++, tail = tail->next) ;
*nnewp = n;
*nreplp = 0;
*ndupp = 0;
return n;
}

first = *firstp;
/*
* find end of first list and stick second list on it
*/
for (tail = first; tail->next; tail = tail->next) ;
tail->next = second;

/*
* run down list freeing duplicate entries; if an entry is okay, then
* bump the tail up to include it, otherwise, cut the entry out of
* the chain.
*/
for (b = second; b; ) {
AuthList *next = b->next; /* in case we free it */
int duplicate;

duplicate = 0;
a = first;
for (;;) {
int authDataSame;
if (match_auth (a->auth, b->auth, &authDataSame)) {
if (authDataSame)
{
/* found a complete duplicate, ignore */
duplicate = 1;
break;
}
else
{
/* found a duplicate, but auth data differs */

AuthList tmp; /* swap it in for old one */
tmp = *a;
*a = *b;
*b = tmp;
a->next = b->next;
IceFreeAuthFileEntry (b->auth);
free ((char *) b);
b = NULL;
tail->next = next;
nrepl++;
nnew--;
break;
}
}
if (a == tail) break; /* if have looked at left side */
a = a->next;
}
if (!duplicate && b) { /* if we didn't remove it */
tail = b; /* bump end of first list */
}
b = next;

if (duplicate)
ndup++;
else
{
n++;
nnew++;
}
}

*nnewp = nnew;
*nreplp = nrepl;
*ndupp = ndup;
return n;

}


static int search_and_do (
const char *inputfilename,
int lineno,
int start,
int argc,
char *argv[],
DoFunc do_func,
char *data)
{
int i;
int status = 0;
int errors = 0;
AuthList *l, *next;
char *protoname, *protodata, *netid, *authname;

for (l = iceauth_head; l; l = next)
{
next = l->next;

protoname = protodata = netid = authname = NULL;

for (i = start; i < argc; i++)
{
if (!strncmp ("protoname=", argv[i], 10))
protoname = argv[i] + 10;
else if (!strncmp ("protodata=", argv[i], 10))
protodata = argv[i] + 10;
else if (!strncmp ("netid=", argv[i], 6))
netid = argv[i] + 6;
else if (!strncmp ("authname=", argv[i], 9))
authname = argv[i] + 9;
}

status = 0;

if (protoname || protodata || netid || authname)
{
if (protoname && strcmp (protoname, l->auth->protocol_name))
continue;

if (protodata && !binaryEqual (protodata,
l->auth->protocol_data, l->auth->protocol_data_length))
continue;

if (netid && strcmp (netid, l->auth->network_id))
continue;

if (authname && strcmp (authname, l->auth->auth_name))
continue;

status = (*do_func) (inputfilename, lineno, l->auth, data);

if (status < 0)
break;
}
}

if (status < 0)
errors -= status; /* since status is negative */

return (errors);
}


/* ARGSUSED */
static int remove_entry (
const char *inputfilename,
int lineno,
IceAuthFileEntry *auth,
char *data)
{
int *nremovedp = (int *) data;
AuthList **listp = &iceauth_head;
AuthList *list;

/*
* unlink the auth we were asked to
*/
while ((list = *listp)->auth != auth)
listp = &list->next;
*listp = list->next;
IceFreeAuthFileEntry (list->auth); /* free the auth */
free (list); /* free the link */
iceauth_modified = True;
(*nremovedp)++;
return 1;
}

/*
* action routines
*/

/*
* help
*/
int print_help (
FILE *fp,
const char *cmd)
{
const CommandTable *ct;
int n = 0;

fprintf (fp, "\n");
if (!cmd) { /* if no cmd, print all help */
for (ct = command_table; ct->name; ct++) {
fprintf (fp, "%s\n\n", ct->helptext);
n++;
}
} else {
int len = strlen (cmd);
for (ct = command_table; ct->name; ct++) {
if (strncmp (cmd, ct->name, len) == 0) {
fprintf (fp, "%s\n\n", ct->helptext);
n++;
}
}
}

return n;
}

static int do_help (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
char *cmd = (argc > 1 ? argv[1] : NULL);
int n;

n = print_help (stdout, cmd);

if (n < 0 || (n == 0 && !cmd)) {
prefix (inputfilename, lineno);
fprintf (stderr, "internal error with help");
if (cmd) {
fprintf (stderr, " on command \"%s\"", cmd);
}
fprintf (stderr, "\n");
return 1;
}

if (n == 0) {
prefix (inputfilename, lineno);
/* already know that cmd is set in this case */
fprintf (stderr, "no help for noexistent command \"%s\"\n", cmd);
}

return 0;
}

/*
* questionmark
*/
/* ARGSUSED */
static int do_questionmark (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
const CommandTable *ct;
int i;
#define WIDEST_COLUMN 72
int col = WIDEST_COLUMN;

printf ("Commands:\n");
for (ct = command_table; ct->name; ct++) {
if ((col + ct->maxlen) > WIDEST_COLUMN) {
if (ct != command_table) {
putc ('\n', stdout);
}
fputs (" ", stdout);
col = 8; /* length of string above */
}
fputs (ct->name, stdout);
col += ct->maxlen;
for (i = ct->maxlen; i < COMMAND_NAMES_PADDED_WIDTH; i++) {
putc (' ', stdout);
col++;
}
}
if (col != 0) {
putc ('\n', stdout);
}

/* allow bad lines since this is help */
return 0;
}

/*
* list [displayname ...]
*/
static int do_list (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
struct _list_data ld;

ld.fp = stdout;

if (argc == 1) {
register AuthList *l;

if (iceauth_head) {
for (l = iceauth_head; l; l = l->next) {
dump_entry (inputfilename, lineno, l->auth, (char *) &ld);
}
}
return 0;
}
else
{
return (search_and_do (inputfilename, lineno, 1, argc, argv,
dump_entry, (char *) &ld));
}
}

/*
* merge filename [filename ...]
*/
static int do_merge (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
int i;
int errors = 0;
AuthList *head, *tail, *listhead, *listtail;
int nentries, nnew, nrepl, ndup;

if (argc < 2) {
prefix (inputfilename, lineno);
badcommandline (argv[0]);
return 1;
}

listhead = listtail = NULL;

for (i = 1; i < argc; i++) {
char *filename = argv[i];
FILE *fp;
Bool used_stdin = False;

fp = open_file (&filename, "rb",
&used_stdin, inputfilename, lineno,
argv[0]);
if (!fp) {
errors++;
continue;
}

head = tail = NULL;
nentries = read_auth_entries (fp, &head, &tail);
if (nentries == 0) {
prefix (inputfilename, lineno);
fprintf (stderr, "unable to read any entries from file \"%s\"\n",
filename);
errors++;
} else { /* link it in */
add_to_list (listhead, listtail, head);
}

if (!used_stdin) (void) fclose (fp);
}

/*
* if we have new entries, merge them in (freeing any duplicates)
*/
if (listhead) {
nentries = merge_entries (&iceauth_head, listhead,
&nnew, &nrepl, &ndup);
if (verbose)
printf ("%d entries read in: %d new, %d replacement%s\n",
nentries, nnew, nrepl, nrepl != 1 ? "s" : "");
if (nentries > 0) iceauth_modified = True;
}

return 0;
}

/*
* extract filename displayname [displayname ...]
*/
static int do_extract (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
int errors;
struct _extract_data ed;

if (argc < 3) {
prefix (inputfilename, lineno);
badcommandline (argv[0]);
return 1;
}

ed.fp = NULL;
ed.filename = argv[1];
ed.nwritten = 0;
ed.cmd = argv[0];

errors = search_and_do (inputfilename, lineno, 2, argc, argv,
extract_entry, (char *) &ed);

if (!ed.fp) {
fprintf (stderr,
"No matches found, authority file \"%s\" not written\n",
ed.filename);
} else {
if (verbose) {
printf ("%d entries written to \"%s\"\n",
ed.nwritten, ed.filename);
}
if (!ed.used_stdout) {
(void) fclose (ed.fp);
}
}

return errors;
}


/*
* add protoname protodata netid authname authdata
*/
static int do_add (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
int n, nnew, nrepl, ndup;
char *protoname;
char *protodata_hex;
char *protodata = NULL; /* not required */
char *netid;
char *authname;
char *authdata_hex;
char *authdata = NULL;
int protodata_len, authdata_len;
IceAuthFileEntry *auth = NULL;
AuthList *list;
int status = 0;

if (argc != 6 || !argv[1] || !argv[2] ||
!argv[3] || !argv[4] || !argv[5])
{
prefix (inputfilename, lineno);
badcommandline (argv[0]);
return 1;
}

protoname = argv[1];
protodata_hex = argv[2];
netid = argv[3];
authname = argv[4];
authdata_hex = argv[5];

protodata_len = strlen (protodata_hex);
if (protodata_len > 0)
{
if (protodata_hex[0] == '"' && protodata_hex[protodata_len - 1] == '"')
{
protodata = malloc (protodata_len - 1);
if (protodata)
{
strncpy (protodata, protodata_hex + 1, protodata_len - 2);
protodata_len -= 2;
}
else
goto add_bad_malloc;
}
else
{
protodata_len = cvthexkey (protodata_hex, &protodata);
if (protodata_len < 0)
{
prefix (inputfilename, lineno);
fprintf (stderr,
"protodata_hex contains odd number of or non-hex characters\n");
return (1);
}
}
}

authdata_len = strlen (authdata_hex);
if (authdata_hex[0] == '"' && authdata_hex[authdata_len - 1] == '"')
{
authdata = malloc (authdata_len - 1);
if (authdata)
{
strncpy (authdata, authdata_hex + 1, authdata_len - 2);
authdata_len -= 2;
}
else
goto add_bad_malloc;
}
else if (!strcmp (protoname, SECURERPC) || !strcmp (protoname, K5AUTH))
{
authdata = malloc (authdata_len + 1);
if (authdata)
strcpy (authdata, authdata_hex);
else
goto add_bad_malloc;
}
else
{
authdata_len = cvthexkey (authdata_hex, &authdata);
if (authdata_len < 0)
{
prefix (inputfilename, lineno);
fprintf (stderr,
"authdata_hex contains odd number of or non-hex characters\n");
free (protodata);
return (1);
}
}

auth = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry));

if (!auth)
goto add_bad_malloc;

auth->protocol_name = copystring (protoname);
auth->protocol_data_length = protodata_len;
auth->protocol_data = protodata;
auth->network_id = copystring (netid);
auth->auth_name = copystring (authname);
auth->auth_data_length = authdata_len;
auth->auth_data = authdata;

if (!auth->protocol_name ||
(!auth->protocol_data && auth->protocol_data_length > 0) ||
!auth->network_id || !auth->auth_name ||
(!auth->auth_data && auth->auth_data_length > 0))
{
goto add_bad_malloc;
}

list = (AuthList *) malloc (sizeof (AuthList));

if (!list)
goto add_bad_malloc;

list->next = NULL;
list->auth = auth;

/*
* merge it in; note that merge will deal with allocation
*/

n = merge_entries (&iceauth_head, list, &nnew, &nrepl, &ndup);

if (n > 0)
iceauth_modified = True;
else
{
prefix (inputfilename, lineno);
if (ndup > 0)
{
status = 0;
fprintf (stderr, "no records added - all duplicate\n");
}
else
{
status = 1;
fprintf (stderr, "unable to merge in added record\n");
}
goto cant_add;
}

return 0;


add_bad_malloc:

status = 1;
prefix (inputfilename, lineno);
fprintf (stderr, "unable to allocate memory to add an entry\n");

cant_add:

if (protodata)
free (protodata);
if (authdata)
free (authdata);
if (auth)
{
if (auth->protocol_name)
free (auth->protocol_name);
/* auth->protocol_data already freed,
since it's the same as protodata */
if (auth->network_id)
free (auth->network_id);
if (auth->auth_name)
free (auth->auth_name);
/* auth->auth_data already freed,
since it's the same as authdata */
free ((char *) auth);
}

return status;
}

/*
* remove displayname
*/
static int do_remove (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
int nremoved = 0;
int errors;

if (argc < 2) {
prefix (inputfilename, lineno);
badcommandline (argv[0]);
return 1;
}

errors = search_and_do (inputfilename, lineno, 1, argc, argv,
remove_entry, (char *) &nremoved);
if (verbose) printf ("%d entries removed\n", nremoved);
return errors;
}

/*
* info
*/
static int do_info (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
int n;
AuthList *l;

if (argc != 1) {
prefix (inputfilename, lineno);
badcommandline (argv[0]);
return 1;
}

for (l = iceauth_head, n = 0; l; l = l->next, n++) ;

printf ("Authority file: %s\n",
iceauth_filename ? iceauth_filename : "(none)");
printf ("File new: %s\n", iceauth_existed ? No : Yes);
printf ("File locked: %s\n", ignore_locks ? No : Yes);
printf ("Number of entries: %d\n", n);
printf ("Changes honored: %s\n", iceauth_allowed ? Yes : No);
printf ("Changes made: %s\n", iceauth_modified ? Yes : No);
printf ("Current input: %s:%d\n", inputfilename, lineno);
return 0;
}


/*
* exit
*/
static Bool alldone = False;

/* ARGSUSED */
static int do_exit (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
/* allow bogus stuff */
alldone = True;
return 0;
}

/*
* quit
*/
/* ARGSUSED */
static int do_quit (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
/* allow bogus stuff */
die (0);
/* NOTREACHED */
return -1; /* for picky compilers */
}


/*
* source filename
*/
static int do_source (
const char *inputfilename,
int lineno,
int argc,
char **argv)
{
char *script;
char buf[BUFSIZ];
FILE *fp;
Bool used_stdin = False;
int len;
int errors = 0, status;
int sublineno = 0;
char **subargv;
int subargc;
Bool prompt = False; /* only true if reading from tty */

if (argc != 2 || !argv[1]) {
prefix (inputfilename, lineno);
badcommandline (argv[0]);
return 1;
}

script = argv[1];

fp = open_file (&script, "r", &used_stdin, inputfilename, lineno, argv[0]);
if (!fp) {
return 1;
}

if (verbose && used_stdin && isatty (fileno (fp))) prompt = True;

while (!alldone) {
buf[0] = '\0';
if (prompt) {
printf ("iceauth> ");
fflush (stdout);
}
if (fgets (buf, sizeof buf, fp) == NULL) break;
sublineno++;
len = strlen (buf);
if (len == 0 || buf[0] == '#') continue;
if (buf[len-1] != '\n') {
prefix (script, sublineno);
fprintf (stderr, "line too long\n");
errors++;
break;
}
buf[--len] = '\0'; /* remove new line */
subargv = split_into_words (buf, &subargc);
if (subargv) {
status = process_command (script, sublineno, subargc, subargv);
free ((char *) subargv);
errors += status;
} else {
prefix (script, sublineno);
fprintf (stderr, "unable to break line into words\n");
errors++;
}
}

if (!used_stdin) {
(void) fclose (fp);
}
return errors;
}
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin