Newsgroups: comp.sources.unix
From: spaf@cs.purdue.edu (Gene Spafford)
Subject: v27i164: tripwire-1.1 - security integrity monitor, V1.1, Part18/26
References: <1.756157401.21864@gw.home.vix.com>
Sender: unix-sources-moderator@gw.home.vix.com
Approved: vixie@gw.home.vix.com

Submitted-By: spaf@cs.purdue.edu (Gene Spafford)
Posting-Number: Volume 27, Issue 164
Archive-Name: tripwire-1.1/part18

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 18 (of 25)."
# Contents:  tripwire-1.1 tripwire-1.1/docs tripwire-1.1/src
#   tripwire-1.1/docs/designag tripwire-1.1/src/main.c
# Wrapped by spaf@uther.cs.purdue.edu on Thu Dec 16 11:42:46 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'tripwire-1.1' ; then
    echo shar: Creating directory \"'tripwire-1.1'\"
    mkdir 'tripwire-1.1'
fi
if test ! -d 'tripwire-1.1/docs' ; then
    echo shar: Creating directory \"'tripwire-1.1/docs'\"
    mkdir 'tripwire-1.1/docs'
fi
if test ! -d 'tripwire-1.1/src' ; then
    echo shar: Creating directory \"'tripwire-1.1/src'\"
    mkdir 'tripwire-1.1/src'
fi
if test -f 'tripwire-1.1/docs/designag' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.1/docs/designag'\"
else
echo shar: Extracting \"'tripwire-1.1/docs/designag'\" \(18295 characters\)
sed "s/^X//" >'tripwire-1.1/docs/designag' <<'END_OF_FILE'
X/originalCTM matrix currentmatrix def
X
XBegin %I Rect
X1 0 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0.75 SetP
X[ 1 0 0 1 216 314.424 ] concat
X240 107 360 147 Rect
XEnd
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 1 0 0 1 470.5 446.424 ] concat
X[
X(Tripwire report)
X] Text
XEnd
X
XBegin %I Rect
X1 0 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
Xnone SetP %I p n
X[ 1.06164 0 0 0.943047 137.817 385.784 ] concat
X174 34 270 84 Rect
XEnd
X
XBegin %I Rect
X1 0 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
Xnone SetP %I p n
X[ 1.14319 0 0 1 86.6956 263 ] concat
X115 162 182 192 Rect
XEnd
X
XBegin %I Rect
X1 0 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0.75 SetP
X[ 0.734718 0 0 0.643057 76.2459 276.794 ] concat
X180 316 304 415 Rect
XEnd
X
XBegin %I Pict
X[ 1 0 0 1 -0.256439 -160.506 ] concat
X
XBegin %I Rect
X1 0 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0.75 SetP
X[ 0.994279 0 0 0.545658 53.5482 336.813 ] concat
X51 278 123 365 Rect
XEnd
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 1.05109 0 0 1.01053 112.396 526.883 ] concat
X[
X(tw.config)
X(    file)
X] Text
XEnd
X
XEnd %I eop
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 0.994595 0 0 1.01575 221.151 532.854 ] concat
X[
X(    newly)
X(generated)
X( database)
X] Text
XEnd
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 1 0 0 1 228.959 447 ] concat
X[
X(compare)
X] Text
XEnd
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 1 0 0 1 328.5 455 ] concat
X[
X(      apply)
X(select-masks)
X] Text
XEnd
X
XBegin %I Pict
X[ 1 0 0 1 0 -16 ] concat
X
XBegin %I Rect
X1 0 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0.75 SetP
X[ 0.734718 0 0 0.643058 76.246 132.794 ] concat
X180 316 304 415 Rect
XEnd
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 1 0 0 1 224 384 ] concat
X[
X(     old )
X(database)
X] Text
XEnd
X
XEnd %I eop
X
XBegin %I Line
X1 1 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0 SetP
X[ 1 -0 -0 1 96 309 ] concat
X160 147 160 171 Line
XEnd
X
XBegin %I Line
X1 0 1 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0 SetP
X[ 1 -0 -0 1 96 309 ] concat
X200 131 224 131 Line
XEnd
X
XBegin %I Line
X1 0 1 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0 SetP
X[ 1 -0 -0 1 200 309 ] concat
X224 131 256 131 Line
XEnd
X
XBegin %I Line
X1 0 1 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0 SetP
X[ 1 -0 -0 1 96 309 ] concat
X80 203 112 203 Line
XEnd
X
XBegin %I Pict
Xnone SetP %I p n
X[ 1 0 0 1 0 -24 ] concat
X
XBegin %I Rect
X1 0 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0.75 SetP
X[ 1 -0 -0 1 -51 214 ] concat
X155 306 227 338 Rect
XEnd
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 1 0 0 1 112 541 ] concat
X[
X(generate)
X] Text
XEnd
X
XEnd %I eop
X
XBegin %I Line
X1 1 0 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0 SetP
X[ 1 -0 -0 1 -51 214 ] concat
X307 210 307 170 Line
XEnd
X
XBegin %I Rect
X1 0 0 [12 4] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
Xnone SetP %I p n
X[ 1 -0 -0 1 -51 214 ] concat
X139 58 371 186 Rect
XEnd
X
XBegin %I Text
X0 0 0 SetCFg
XHelvetica 14 SetF
X[ 1 0 0 1 128 301 ] concat
X[
X(Files residing on system)
X] Text
XEnd
X
XBegin %I Line
X1 0 1 [] 0 SetB
X0 0 0 SetCFg
X1 1 1 SetCBg
X0 SetP
X[ 1 -0 -0 1 -51 214 ] concat
X187 162 187 282 Line
XEnd
X
XEnd %I eop
X
Xshowpage
X
X
Xend
X%%EndDocument
X @endspecial 376 1596 a(Figure)e(1:)20 b(Diagram)14 b(of)h(high)h(lev)o(el)g
X(op)q(eration)g(mo)q(del)g(of)f(T)l(rip)o(wire)0 1767 y Fg(4.1)56
Xb(Administrativ)n(e)16 b(mo)r(del)0 1872 y Ff(4.1.1)52 b(P)o(ortabilit)o(y)0
X1978 y Fp(Because)17 b(of)f(the)g(heterogeneous)h(nature)f(of)g(computer)g
X(equipmen)o(t)h(at)f(most)f(sites,)i(the)f(design)h(of)f(T)l(rip)o(wire)0
X2034 y(emphasized)j(program)d(and)i(database)e(p)q(ortabilit)o(y)l(.)28
Xb(The)18 b(co)q(de)g(is)f(written)h(in)g(the)f(standard)g(K&R)i(C)e(pro-)0
X2091 y(gramming)e(language,[12)o(])g(adhering)h(to)f(POSIX)i(standards)e
X(wherev)o(er)g(p)q(ossible.)22 b(The)16 b(result)g(is)g(a)f(program)0
X2147 y(that)g(compiles)i(and)f(runs)f(on)h(at)f(least)g(28)g(BSD)h(and)g
X(System-V)g(v)m(arian)o(ts)f(of)g Fl(UNIX)p Fp(,)h(including)i(Xenix)f(and)0
X2204 y(Unicos.)71 2280 y(T)l(rip)o(wire)g(database)e(\014les)j(are)e(enco)q
X(ded)h(in)g(standard)f(ASCI)q(I)i(and)e(are)g(mostly)g(h)o(uman)h(readable.)
X24 b(They)0 2336 y(are)17 b(completely)h(in)o(terop)q(erable)h(\(i.e.,)e
X(\014les)h(generated)f(on)h(one)f(platform)g(can)g(b)q(e)h(read)f(and)g(used)
Xh(on)f(other)0 2393 y(platforms\).)24 b(This)18 b(allo)o(ws)f(the)g(database)
Xf(\014les)i(to)f(b)q(e)g(prin)o(ted)h(using)g(standard)e(soft)o(w)o(are,)f
X(compared)i(using)0 2449 y(standard)e(text)f(to)q(ols,)h(and)h(examined)g
X(using)g(other)f(standard)f(to)q(ols.)71 2525 y(Generating)h(correct)h
X(signatures)g(is)g(complicated)h(b)o(y)f(arc)o(hitectural)g(di\013erences)h
X(in)f(b)o(yte-ordering)h(\(i.e.,)0 2582 y(big-endian)k(vs.)d(little)h
X(endian\).)31 b(An)19 b(automated)f(installation)i(pro)q(cedure)f(generates)f
X(macros)g(and)h(header)0 2638 y(\014les)c(so)e(that)g(the)g(signatures)h
X(generated)f(are)h(uniform;)g(the)f(standard)g(\\net)o(w)o(ork-order")f(b)o
X(yte)i(order)f(used)h(in)952 2790 y(10)p eop
X%%Page: 11 11
X10 bop 0 307 a Fp(the)17 b(IP)g(proto)q(col)g(suite)h(is)f(our)g(underlying)i
X(mo)q(del.)26 b(This)17 b(allo)o(ws)h(database)e(\014les)i(to)e(b)q(e)i(used)
Xf(on)g(mac)o(hines)0 364 y(di\013eren)o(t)h(from)f(those)h(on)f(whic)o(h)i
X(they)f(are)g(generated,)g(if)g(this)g(should)h(b)q(e)g(desired)g(\(and)e(as)
Xh(migh)o(t)f(b)q(e)i(the)0 420 y(case)c(with)h(some)f(net)o(w)o(ork)o(ed)f
X(\014le)i(systems)f(and)g(soft)o(w)o(are)f(distributions\).)71
X496 y(A)g(comprehensiv)o(e)h(test)f(suite)h(is)f(included)j(in)e(the)f(T)l
X(rip)o(wire)h(distribution)h(to)e(con\014rm)g(correct)g(signature)0
X553 y(generation.)19 b(The)11 b(test)g(suite)h(also)g(c)o(hec)o(ks)f(eac)o(h)
Xh(\014le)g(in)h(the)e(distribution)i(against)e(those)h(stored)e(in)j(a)e
X(database,)0 609 y(ascertaining)k(eac)o(h)g(\014le's)g(in)o(tegrit)o(y)l(.)20
Xb(This)15 b(serv)o(es)f(b)q(oth)h(to)f(c)o(hec)o(k)h(the)g(consistency)g(of)f
X(the)h(distribution,)h(and)0 665 y(to)f(ensure)g(that)g(all)h(features)f(of)g
X(the)g(T)l(rip)o(wire)h(program)e(are)h(w)o(orking)g(as)g(exp)q(ected.)0
X805 y Ff(4.1.2)52 b(Scalabilit)o(y)0 910 y Fp(T)l(rip)o(wire)17
Xb(includes)i(an)d(M4-lik)o(e)h(prepro)q(cessing)h(language)e([11])g(to)f
X(help)j(system)e(administrators)g(maximize)0 967 y(reuse)f(of)f
X(con\014guration)g(\014les.)21 b(By)14 b(including)j(directiv)o(es)f(suc)o(h)
Xe(as)g(\\)p Fb(@@include)p Fp(",)e(\\)p Fb(@@ifdef)p Fp(",)h(\\)p
XFb(@@ifhost)p Fp(",)0 1023 y(and)18 b(\\)p Fb(@@define)p Fp(",)e(system)h
X(administrators)h(can)g(write)f(a)h(core)f(con\014guration)h(\014le)h
X(describing)g(p)q(ortions)f(of)0 1080 y(the)g(\014le)h(system)e(shared)h(b)o
X(y)g(man)o(y)f(mac)o(hines.)28 b(These)19 b(core)e(\014les)i(can)f(then)g(b)q
X(e)h(conditionally)h(included)g(in)0 1136 y(the)15 b(con\014guration)h
X(\014le)g(for)e(eac)o(h)i(mac)o(hine.)71 1212 y(T)l(o)d(allo)o(w)h(the)g(p)q
X(ossible)h(use)f(of)f(T)l(rip)o(wire)i(at)e(sites)h(consisting)g(of)g
X(thousands)f(of)g(mac)o(hines,)i(con\014guration)0 1269 y(and)23
Xb(database)e(\014les)j(do)e(not)g(need)h(to)f(reside)h(on)f(the)h(actual)f
X(mac)o(hine.)42 b(Input)24 b(can)e(b)q(e)h(read)f(from)g(\014le)0
X1325 y(descriptors,)d(op)q(en)h(at)e(the)g(time)h(of)f(T)l(rip)o(wire)i(in)o
X(v)o(o)q(cation.)30 b(These)19 b(\014le)h(descriptors)f(can)g(b)q(e)g
X(connected)h(to)0 1382 y Fl(UNIX)g Fp(pip)q(es)h(or)d(net)o(w)o(ork)h
X(connections.)33 b(Th)o(us,)20 b(a)f(remote)g(serv)o(er)g(or)g(a)g(lo)q(cal)h
X(program)f(can)g(supply)i(the)0 1438 y(necessary)d(\014le)g(con)o(ten)o(ts.)
X26 b(Supp)q(orting)19 b Fl(UNIX)f Fp(st)o(yle)f(pip)q(es)i(also)f(allo)o(ws)g
X(for)e(outside)j(programs)d(to)h(supply)0 1495 y(encryption)f(and)g
X(compression)g(services)g(|)f(services)i(that)d(w)o(e)h(do)g(not)g(an)o
X(ticipate)h(including)i(as)d(a)g(standard)0 1551 y(part)g(of)f(the)i(core)f
X(T)l(rip)o(wire)h(pac)o(k)m(age.)71 1627 y(T)l(rip)o(wire)h(do)q(es)g(not)f
X(encrypt)h(the)f(database)g(\014le)i(so)e(as)g(to)g(ensure)h(that)f(runs)h
X(can)f(b)q(e)i(completely)f(auto-)0 1684 y(mated)d(\(i.e.,)g(no)h(one)f(has)h
X(to)f(t)o(yp)q(e)g(in)i(the)e(encryption)i(k)o(ey)e(ev)o(ery)h(nigh)o(t)f(at)
Xg(3)h(a.m.\).)j(Because)d(the)g(database)0 1740 y(con)o(tains)i(nothing)h
X(that)f(w)o(ould)h(aid)f(an)h(in)o(truder)g(in)g(sub)o(v)o(erting)f(T)l(rip)o
X(wire,)i(this)e(do)q(es)h(not)f(undermine)i(the)0 1796 y(securit)o(y)j(of)f
X(the)g(system.)38 b(Ho)o(w)o(ev)o(er,)21 b(if)h(T)l(rip)o(wire)g(is)g(used)g
X(in)g(an)f(en)o(vironmen)o(t)h(where)f(the)h(database)e(is)0
X1853 y(encrypted)c(as)f(a)g(matter)f(of)h(p)q(olicy)l(,)h(the)g(in)o(terface)
Xf(supp)q(orts)g(this,)g(as)g(describ)q(ed)i(ab)q(o)o(v)o(e.)0
X1993 y Ff(4.1.3)52 b(Con\014gurabilit)o(y)18 b(and)g(\015exibilit)o(y)0
X2098 y Fp(T)l(rip)o(wire)h(mak)o(es)e(a)h(distinction)i(b)q(et)o(w)o(een)e
X(the)h(con\014guration)f(\014le)h(and)f(the)g(database)g(\014le.)29
Xb(Eac)o(h)18 b(mac)o(hine)0 2154 y(ma)o(y)11 b(share)h(a)f(con\014guration)i
X(\014le,)g(but)f(eac)o(h)g(generates)f(its)h(o)o(wn)g(database)f(\014le.)20
Xb(Th)o(us,)12 b(iden)o(tically)i(con\014gured)0 2211 y(mac)o(hines)j(can)f
X(share)g(their)g(con\014guration)g(database,)g(but)g(eac)o(h)g(has)g(its)g
X(in)o(tegrit)o(y)g(c)o(hec)o(k)o(ed)g(against)g(a)f(p)q(er-)0
X2267 y(mac)o(hine)h(database.)71 2343 y(Because)j(of)f(the)h(prepro)q(cessor)
Xg(supp)q(ort,)g(system)f(administrators)h(can)f(write)h(T)l(rip)o(wire)h
X(con\014guration)0 2400 y(\014les)13 b(that)f(supp)q(ort)h(n)o(umerous)f
X(con\014gurations)h(of)f(mac)o(hines.)19 b(Uniform)13 b(and)g(unique)h(mac)o
X(hines)f(are)f(similarly)0 2456 y(handled.)21 b(This)16 b(helps)h(supp)q(ort)
Xe(reuse)g(and)h(minimize)h(user)f(o)o(v)o(erhead)e(in)i(installation.)71
X2532 y(The)f(con\014guration)g(\014le)i(for)d(T)l(rip)o(wire,)120
Xb Fb(tw.config)p Fp(,)13 b(con)o(tains)j(a)e(list)i(of)f(en)o(tries,)g(en)o
X(umerating)h(the)0 2589 y(set)d(of)g(directory)h(\(or)e(\014les\))i(to)f(b)q
X(e)h(monitored)g(for)f(c)o(hanges,)g(additions,)h(or)f(deletions.)21
Xb(Asso)q(ciated)14 b(with)g(eac)o(h)0 2645 y(en)o(try)f(is)h(a)f
X(selection-mask)i(\(describ)q(ed)g(in)f(the)f(next)h(section\))g(that)e
X(describ)q(es)j(whic)o(h)g(\014le)f(\(ino)q(de\))g(attributes)952
X2790 y(11)p eop
X%%Page: 12 12
X11 bop 0 307 a Fp(can)15 b(c)o(hange)g(without)f(b)q(eing)i(rep)q(orted)f(as)
Xf(an)h(exception.)21 b(An)15 b(excerpt)g(from)f(a)g(set)h(of)f
XFb(tw.config)f Fp(en)o(tries)i(is)0 364 y(sho)o(wn)g(in)h(Figure)f(2.)0
X504 y Fb(#)24 b(file/dir)142 b(selection-mask)0 560 y(/etc)286
Xb(R)167 b(#)23 b(all)h(files)f(under)g(/etc)0 617 y(@@ifhost)g
X(solaria.cs.purdue.edu)24 673 y(!/etc/lp)357 b(#)47 b(except)23
Xb(for)h(SVR4)f(printer)g(logs)0 729 y(@@endif)0 786 y(/etc/passwd)118
Xb(R+12)95 b(#)23 b(you)h(can't)f(be)h(too)f(careful)0 842 y(/etc/mtab)166
Xb(L)h(#)23 b(dynamic)g(files)0 899 y(/etc/motd)166 b(L)0 955
Xy(/etc/utmp)g(L)0 1012 y(=/var/tmp)g(R)h(#)23 b(only)h(the)f(directory,)g
X(not)g(its)h(contents)541 1160 y Fp(Figure)16 b(2:)j(An)d(excerpt)f(from)g(a)
Xg Fb(tw.config)f Fp(\014le)71 1267 y(Pre\014xes)d(to)g(the)h
XFb(tw.config)e Fp(en)o(tries)i(allo)o(w)g(for)f(pruning)i(\(i.e.,)e(prev)o
X(en)o(ting)h(T)l(rip)o(wire)h(from)e(recursing)h(in)o(to)0
X1324 y(the)17 b(sp)q(eci\014ed)j(directory)d(or)g(recording)h(a)f(database)g
X(en)o(try)f(for)h(a)g(\014le\).)27 b(Both)17 b(inclusiv)o(e)j(and)d
X(non-inclusiv)o(e)0 1380 y(pruning)i(are)e(supp)q(orted;)j(that)d(is,)h(a)g
X(directory's)f(con)o(ten)o(ts)h(only)g(ma)o(y)f(b)q(e)h(excluded)i(from)d
X(monitoring,)h(or)0 1436 y(the)d(directory)h(and)f(its)g(con)o(ten)o(ts)g(ma)
Xo(y)g(b)q(oth)g(b)q(e)h(excluded.)71 1512 y(By)g(default,)h(all)h(en)o(tries)
Xf(within)h(a)e(named)h(directory)g(are)f(included)j(when)e(the)g(database)f
X(is)h(generated.)0 1569 y(Eac)o(h)12 b(en)o(try)g(is)h(recorded)g(in)g(the)f
X(database)g(with)g(the)h(same)f(\015ags)g(and)g(signatures)h(as)e(the)i
X(enclosing,)h(sp)q(eci\014ed)0 1625 y(directory)l(.)20 b(This)14
Xb(allo)o(ws)h(the)f(user)g(to)f(write)h(more)f(compact)h(and)g(inclusiv)o(e)i
X(con\014guration)f(\014les.)20 b(Some)14 b(users)0 1682 y(ha)o(v)o(e)h(rep)q
X(orted)g(using)h(con\014guration)f(\014les)i(of)d(a)h(simple)i
XFb(/)p Fp(,)e(naming)g(all)h(en)o(tries)g(in)g(the)f(\014le)h(system!)0
X1823 y Fg(4.2)56 b(Rep)r(orting)17 b(mo)r(del)0 1928 y Fp(The)d
XFb(tw.config)e Fp(\014le)i(con)o(tains)g(the)g(names)f(of)g(\014les)i(and)e
X(directories)i(with)f(their)g(asso)q(ciated)f(selection-mask.)0
X1985 y(A)k(selection-mask)h(ma)o(y)e(lo)q(ok)g(lik)o(e:)24
Xb Fb(+pinugsm12-a)p Fp(.)f(Flags)17 b(are)f(added)h(\(\\+"\))f(or)g(deleted)i
X(\(\\-"\))e(from)g(the)0 2041 y(set)f(of)g(items)g(to)g(b)q(e)h(examined.)71
X2117 y(T)l(rip)o(wire)j(reads)g(this)h(as,)f(\\Rep)q(ort)g(c)o(hanges)g(in)h
X(p)q(ermission)h(and)e(mo)q(des,)h(ino)q(de)g(n)o(um)o(b)q(er,)g(n)o(um)o(b)q
X(er)f(of)0 2174 y(links,)d(user)f(id,)g(group)g(id,)g(size)h(of)e(the)h
X(\014le,)h(mo)q(di\014cation)g(timestamp,)e(and)h(signatures)g(1)g(and)g(2.)k
X(Disregard)0 2230 y(c)o(hanges)c(to)g(access)g(timestamp.")71
X2306 y(A)g(\015ag)h(exists)g(for)f(ev)o(ery)g(distinct)i(\014eld)g(stored)e
X(in)i(an)e(ino)q(de.)23 b(Pro)o(vided)16 b(is)g(a)f(set)h(of)f(templates)h
X(to)f(allo)o(w)0 2363 y(system)g(administrators)g(to)f(quic)o(kly)j(classify)
Xf(\014les)g(in)o(to)f(categories)g(that)g(use)g(common)g(sets)g(of)g
X(\015ags:)0 2489 y Ff(read-only)j(\014les)23 b Fp(Only)16 b(the)g(access)f
X(timestamp)g(is)h(ignored.)0 2582 y Ff(log)i(\014les)23 b Fp(Changes)15
Xb(to)g(the)g(\014le)h(size,)g(access)f(and)h(mo)q(di\014cation)g(timestamp,)f
X(and)g(signatures)g(are)g(ignored.)952 2790 y(12)p eop
X%%Page: 13 13
X12 bop 0 347 a Fb(changed:)23 b(-rw-r--r--)f(root)262 b(20)24
Xb(Sep)f(17)h(13:46:43)f(1993)g(/.rhosts)0 404 y(###)g(Attr)191
Xb(Observed)23 b(\(what)g(it)g(is\))215 b(Expected)22 b(\(what)i(it)f(should)g
X(be\))0 460 y(###)g(===========)g(=========================)o(====)e
X(========================)o(=====)0 516 y(/.rhosts)0 573 y(st_mtime:)166
Xb(Fri)23 b(Sep)h(17)f(13:46:43)g(1993)143 b(Tue)23 b(Sep)h(14)f(20:05:10)g
X(1993)0 629 y(st_ctime:)166 b(Fri)23 b(Sep)h(17)f(13:46:43)g(1993)143
Xb(Tue)23 b(Sep)h(14)f(20:05:10)g(1993)460 727 y Fp(Figure)15
Xb(3:)20 b(Sample)c(T)l(rip)o(wire)g(output)f(for)g(a)g(c)o(hanged)g(\014le)0
X910 y Ff(gro)o(wing)i(log)h(\014les)23 b Fp(Changes)15 b(to)g(the)g(access)h
X(and)f(mo)q(di\014cation)h(timestamp,)f(and)g(signatures)h(are)114
X967 y(ignored.)k(Increasing)c(\014le)h(sizes)f(are)f(ignored.)0
X1061 y Ff(ignore)j(nothing)24 b Fp(self-explanatory)0 1155
Xy Ff(ignore)18 b(ev)o(erything)k Fp(self-explanatory)71 1280
Xy(An)o(y)14 b(\014les)i(di\013ering)g(from)e(their)h(database)f(en)o(tries)i
X(are)e(then)h(in)o(terpreted)h(according)f(to)f(their)h(selection-)0
X1337 y(masks.)33 b(If)20 b(an)o(y)g(attributes)f(are)h(to)f(b)q(e)i
X(monitored,)f(the)g(\014lename)h(is)f(prin)o(ted,)i(as)d(are)h(the)g(exp)q
X(ected)h(and)0 1393 y(actual)16 b(v)m(alues)g(of)f(the)h(ino)q(de)h
X(attributes.)j(An)c(example)g(of)f(T)l(rip)o(wire)i(output)e(for)g(c)o
X(hanged)h(\014les)g(is)g(sho)o(wn)f(in)0 1450 y(Figure)g(3.)71
X1526 y(A)e(\\quiet)g(option")h(is)f(also)h(a)o(v)m(ailable)g(through)f(a)g
X(command-line)i(option)f(to)e(force)h(T)l(rip)o(wire)h(to)f(giv)o(e)g(terse)0
X1582 y(output.)21 b(The)16 b(output)g(when)g(running)h(in)g(this)f(mo)q(de)g
X(is)h(suitable)g(for)e(use)h(b)o(y)g(\014lter)g(programs.)k(This)d(allo)o(ws)
X0 1639 y(for)12 b(automated)f(actions,)i(similar)h(to)d(those)i(allo)o(w)o
X(ed)f(in)i(A)l(TP)e(if)h(it)g(is)g(really)g(desired.)20 b(One)13
Xb(example)g(w)o(ould)g(b)q(e)0 1695 y(to)h(use)i(the)f(terse)g(output)g(of)f
X(T)l(rip)o(wire)i(after)f(a)g(breakin)g(to)g(quic)o(kly)h(mak)o(e)f(a)g(bac)o
X(kup)g(tap)q(e)g(of)g(only)h(c)o(hanged)0 1752 y(\014les,)g(to)e(b)q(e)i
X(examined)g(later.)71 1828 y(By)f(allo)o(wing)i(rep)q(orting)f(to)f(b)q(e)i
X(dictated)f(b)o(y)g(lo)q(cal)h(p)q(olicy)l(,)g(T)l(rip)o(wire)g(can)f(b)q(e)g
X(used)g(at)g(sites)g(with)g(a)f(v)o(ery)0 1884 y(broad)g(range)g(of)g
X(securit)o(y)g(p)q(olicies.)0 2025 y Fg(4.3)56 b(Database)19
Xb(mo)r(del)0 2131 y Fp(T)l(rip)o(wire)k(uses)f(t)o(w)o(o)e(databases:)32
Xb(the)22 b(con\014guration)g(\014le)h(and)f(the)g(output)f(database.)39
Xb(The)22 b(design)h(and)0 2187 y(in)o(tended)17 b(use)e(of)g(b)q(oth)g(of)g
X(these)g(\014les)i(is)e(describ)q(ed)i(in)f(this)g(section.)0
X2327 y Ff(4.3.1)52 b(In)o(violabilit)o(y)0 2432 y Fp(T)l(rip)o(wire)16
Xb(uses)f(an)g(unencrypted)i(database)d(that)h(can)g(b)q(e)h(w)o
X(orld-readable.)k(T)l(o)15 b(prev)o(en)o(t)g(the)g(database)g(from)0
X2489 y(b)q(eing)h(altered,)e(it)h(should)g(b)q(e)h(stored)e(on)g(some)g(tamp)
Xq(er-pro)q(of)g(media.)20 b(One)15 b(metho)q(d)g(of)f(accomplishing)j(this)0
X2545 y(in)o(v)o(olv)o(es)d(storing)e(the)h(databases)g(on)g(a)g
X(write-protected)g(disk)h(or)e(on)h(a)g(\\secure)g(serv)o(er")g(where)g
X(logins)h(can)f(b)q(e)0 2602 y(strictly)k(con)o(trolled.)26
Xb(The)17 b(database)f(could)i(also)f(b)q(e)h(made)e(a)o(v)m(ailable)j(via)e
X(a)g(read-only)g(remote)g(\014le)g(system)0 2658 y(\(e.g.,)d(read-only)i(NFS)
Xf([23)o(]\).)952 2790 y(13)p eop
X%%Page: 14 14
X13 bop 71 307 a Fp(Installing)15 b(an)e(up)q(dated)i(database)e(is)h
X(problematic)g(b)q(ecause)g(in)o(truders)g(migh)o(t)g(replace)g(the)g
X(database)f(\(or)0 364 y(selected)18 b(en)o(tries\))e(with)h(one)f(of)g
X(their)h(o)o(wn)f(c)o(ho)q(osing)h(during)g(the)g(up)q(date.)24
Xb(Therefore,)16 b(to)g(b)q(est)h(ensure)g(the)0 420 y(securit)o(y)j(of)f(the)
Xg(database,)h(the)g(T)l(rip)o(wire)g(do)q(cumen)o(tation)g(suggests)f(that)g
X(the)g(mac)o(hine)h(b)q(e)h(op)q(erated)e(in)0 477 y(single-user)g(mo)q(de)e
X(to)g(install)i(the)e(database.)26 b(System)17 b(administrators)g(can)g(th)o
X(us)g(c)o(ho)q(ose)g(greater)g(securit)o(y)0 533 y(o)o(v)o(er)d(ease-of-use,)
Xh(allo)o(wing)i(for)d(the)h(p)q(ossible)i(enforcemen)o(t)f(of)e(ev)o(en)i
X(the)f(most)f(sev)o(ere)i(p)q(olicies.)0 672 y Ff(4.3.2)52
Xb(Seman)o(tics)71 778 y Fp(Changes)17 b(to)h(the)g(database)g(can)g(b)q(e)g
X(categorized)h(in)o(to)f(six)g(cases,)h(as)e(sho)o(wn)h(in)h(T)l(able)g(2.)28
Xb(F)l(or)17 b(eac)o(h)h(of)0 834 y(these)g(cases,)h(an)f(appropriate)g
X(action)h(is)f(tak)o(en,)g(based)h(on)f(whether)g(the)h(\014le)g(is)g(a)e
XFb(tw.config)g Fp(en)o(try)l(,)i(and)0 891 y(whether)c(the)h(\014le)g(exists)
Xf(in)h(the)g(old)f(and)h(newly)g(generated)f(databases.)71
X967 y(Up)q(dating)j(or)f(deleting)i(a)f(\014le)g(from)f(the)h(database)f(is)h
X(straigh)o(tfo)o(w)o(ard)e(|)i(the)f(database)h(en)o(try)f(for)g(the)0
X1023 y(\014le)f(is)g(replaced)g(b)o(y)f(a)g(new)g(en)o(try)g(re\015ecting)h
X(the)f(curren)o(t)g(state)g(of)f(the)i(\014le.)k(Adding)d(\014les)f(is)f
END_OF_FILE
if test 18295 -ne `wc -c <'tripwire-1.1/docs/designag'`; then
    echo shar: \"'tripwire-1.1/docs/designag'\" unpacked with wrong size!
fi
# end of 'tripwire-1.1/docs/designag'
fi
if test -f 'tripwire-1.1/src/main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.1/src/main.c'\"
else
echo shar: Extracting \"'tripwire-1.1/src/main.c'\" \(16656 characters\)
sed "s/^X//" >'tripwire-1.1/src/main.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char rcsid[] = "$Id: main.c,v 1.26 1993/12/15 17:35:29 genek Exp $";
X#endif
X
X/************************************************************************
X *
X *   All files in the distribution of Tripwire are Copyright 1992, 1993 by 
X *   the Purdue Research Foundation of Purdue University.  All rights
X *   reserved.  Some individual files in this distribution may be covered
X *   by other copyrights, as noted in their embedded comments.
X *
X *   Redistribution and use in source and binary forms are permitted
X *   provided that this entire copyright notice is duplicated in all such
X *   copies, and that any documentation, announcements, and other
X *   materials related to such distribution and use acknowledge that the
X *   software was developed at Purdue University, W. Lafayette, IN by
X *   Gene Kim and Eugene Spafford.  No charge, other than an "at-cost"
X *   distribution fee, may be charged for copies, derivations, or
X *   distributions of this material without the express written consent
X *   of the copyright holder.  Neither the name of the University nor the
X *   names of the authors may be used to endorse or promote products
X *   derived from this material without specific prior written
X *   permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
X *   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
X *   IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR ANY PARTICULAR
X *   PURPOSE.
X *
X ************************************************************************/
X
X/*
X * main.c
X *
X *	main routines and global variables
X *
X * Gene Kim
X * Purdue University
X */
X
X#include "../include/config.h"
X#include <stdio.h>
X#ifdef STDLIBH
X#include <stdlib.h>
X#include <unistd.h>
X#endif
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <fcntl.h>
X#include <sys/param.h>
X#ifdef STRINGH
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X#ifdef MALLOCH
X# include <malloc.h>
X#endif
X#if (defined(SYSV) && (SYSV < 3))
X# include <limits.h>
X#endif	/* SVR2 */
X#include "../include/list.h"
X#include "../include/tripwire.h"
X#include "../include/patchlevel.h"
X
X#ifndef L_tmpnam
X# define L_tmpnam (unsigned int) MAXPATHLEN
X#endif
X
X/* version information */
X
Xchar *version_num = VERSION_NUM;
Xint db_version_num = DB_VERSION_NUM;
X
X/******* signature functions *****************************************
X *	sig_md5_get		: MD5 by RSA
X *	sig_snefru_get		: Snefru by Xerox
X *	sig_null_get		: null
X *********************************************************************/
X
Xint (*pf_signatures [NUM_SIGS]) () = {
X					SIG0FUNC,
X					SIG1FUNC,
X					SIG2FUNC,
X					SIG3FUNC,
X					SIG4FUNC,
X					SIG5FUNC,
X					SIG6FUNC,
X					SIG7FUNC,
X					SIG8FUNC,
X					SIG9FUNC
X				      };
Xchar *signames[NUM_SIGS] = {
X					SIG0NAME,
X					SIG1NAME,
X					SIG2NAME,
X					SIG3NAME,
X					SIG4NAME,
X					SIG5NAME,
X					SIG6NAME,
X					SIG7NAME,
X					SIG8NAME,
X					SIG9NAME
X				      };
X
Xchar *config_file = CONFIG_FILE;
Xchar *database_file = DATABASE_FILE;
X
Xchar *database_path = DATABASE_PATH;
Xchar *config_path = CONFIG_PATH;
X
Xchar tempdatabase_file[MAXPATHLEN+256];
XFILE *fptempdbase;
X
Xchar *defaultignore = DEFAULTIGNORE;
Xstatic char *defaultignore_parsed;
X
Xchar *db_record_format = DB_RECORD_FORMAT;
X
Xstruct list *olddbase_list = (struct list *) NULL;
X
Xint debuglevel = 1;
Xint verbosity = 0;
Xint loosedir = 0;
Xstatic int dbaseinit = 0;
Xint printhex = 0;
Xstatic char **pp_updateentries = NULL;
Xstatic int numupdateentries = 0;
Xint quietmode = 0;
Xint printpreprocess = 0;
Xchar *specified_dbasefile = NULL;
Xchar *specified_configfile = NULL;
Xint specified_configfd = -1;
Xint specified_dbasefd = -1;
Xint runtimeignore = 0;
Xint interactivemode = 0;
Xint test_interactive = 0;
X
Xchar *progname;
X
Xvoid cleanup();
X
Xstatic void
Xusage()
X{
X    fputs("usage: tripwire [ options ... ]\n", stderr);
X    fputs("\tWhere `options' are:\n", stderr);
X    fputs("\t\t-initialize	Database Generation mode\n", stderr);
X    fputs("\t\t-init		\n", stderr);
X    fputs("\t\t-update entry	update entry (a file, directory, or \n", stderr);
X    fputs("\t\t		    tw.config entry) in the database\n", stderr);
X    fputs("\t\t-interactive	Integrity Checking mode with\n", stderr);
X    fputs("\t\t		    Interactive entry updating\n", stderr);
X    fputs("\t\t-loosedir	use looser checking rules for directories\n", stderr);
X    fputs("\t\t-d dbasefile	read in database from dbasefile\n", stderr);
X    fputs("\t\t		    (use `-d -' to read from stdin)\n", stderr);
X    fputs("\t\t-c configfile	read in config file from configfile\n", stderr);
X    fputs("\t\t		    (use `-c -' to read from stdin)\n", stderr);
X    fputs("\t\t-cfd fd	    read in config file from specified fd\n", stderr);
X    fputs("\t\t-dfd fd	    read in the database file from specified fd\n", stderr);
X    fputs("\t\t-Dvar=value	define a tw.config variable (ala @@define)\n",
X	stderr);
X    fputs("\t\t-Uvar		undefine a tw.config variable (ala @@undef)\n",
X	stderr);
X    fputs("\t\t-i #|all 	ignore the specified signature (to reduce\n", stderr);
X    fputs("\t\t		    execution time)\n", stderr);
X    fputs("\t\t-q		quiet mode\n", stderr);
X    fputs("\t\t-v		verbose mode\n", stderr);
X    fputs("\t\t-preprocess	print out preprocessed configuration file\n",
X	stderr);
X    fputs("\t\t-E		\n", stderr);
X    fputs("\t\t-help		print out interpretation help message\n", stderr);
X    fputs("\t\t-version	print version and patch information\n", stderr);
X    exit(1);
X}
X
X/*
X * void
X * version()
X *
X *	print out version information, with patchlevel information.
X *	currently, there is no real correlation between the two.
X */
X
Xstatic void
Xversion()
X{
X    fprintf(stderr, "\nTripwire version %s (patchlevel %d)\n\n", version_num,
X			    PATCHLEVEL);
X    fprintf(stderr, "Copyright (c) 1992, 1993 Purdue Research Foundation\n");
X    fprintf(stderr, "\tBy Gene Kim, Eugene Spafford\n\n");
X    exit(0);
X}
X
Xint
Xmain(argc, argv)
X    int argc;
X    char *argv[];
X{
X    int i;
X    char *pc;
X    char database[MAXPATHLEN+256];
X    char mask[64];
X    int fd;
X    char *specified_fd;
X    int exitstatus = 0;
X
X    progname = argv[0];
X
X    /* iterate through arguments */
X    for (i = 1; i < argc; i++) {
X	pc = argv[i];
X	/* verbose mode */
X	if (strcmp(pc, "-v") == 0) {
X	    verbosity++;
X	    continue;
X	}
X	/* quiet mode */
X	if (strcmp(pc, "-q") == 0) {
X	    quietmode++;
X	    continue;
X	}
X	/* hex mode */
X	if (strcmp(pc, "-x") == 0) {
X	    printhex++;
X	    continue;
X	}
X	/* database generation mode */
X	if (strcmp(pc, "-initialize") == 0 || strcmp(pc, "-init") == 0 ||
X					      strcmp(pc, "-initialise") == 0) {
X	    dbaseinit++;
X	    continue;
X	}
X	/* print preprocessed configuration file */
X	if ((strcmp(pc, "-preprocess") == 0) || (strcmp(pc, "-E") == 0)) {
X	    printpreprocess++;
X	    continue;
X	}
X	/* update specific database entry */
X	if (strcmp(pc, "-update") == 0) {
X	    /* check to see that there is an argument */
X	    if ((pc = argv[++i]) == NULL) {
X		usage();
X	    }
X	    /* exhaust the argument list */
X	    while (pc) {
X		if (pp_updateentries == NULL) {
X		    if ((pp_updateentries = (char **) malloc(sizeof(char *))) 
X		    			== NULL) {
X		        die_with_err("main: malloc() failed!\n", NULL);
X		    }
X		} else 
X		if ((pp_updateentries = (char **) realloc(pp_updateentries,
X			(numupdateentries+1) * sizeof(char *))) == NULL) {
X		    die_with_err("main: realloc() failed!\n", NULL);
X		}
X		pp_updateentries[numupdateentries++] = pc;
X		pc = argv[++i];
X	    }
X	    continue;
X	}
X	/* specify database file */
X	if (strcmp(pc, "-d") == 0) {
X	    /* check to see that there is an argument */
X	    if ((pc = argv[++i]) == NULL) {
X		usage();
X	    }
X	    specified_dbasefile = pc;
X	    continue;
X	}
X	/* specify configuration file */
X	if (strcmp(pc, "-c") == 0) {
X	    /* check to see that there is an argument */
X	    if ((pc = argv[++i]) == NULL) {
X		usage();
X	    }
X	    specified_configfile = pc;
X	    continue;
X	}
X	/* specify configuration file descriptor */
X	if (strcmp(pc, "-cfd") == 0) {
X	    char err[512];
X
X	    /* check to see that there is an argument */
X	    if ((pc = argv[++i]) == NULL) {
X		usage();
X	    }
X	    specified_fd = pc;
X	    if (!sscanf(specified_fd, "%d", &specified_configfd)) {
X		usage();
X	    }
X	    /* if we try to read stdin, we'll block, so skip read */
X	    if (specified_configfd != 0 &&
X				fcntl(specified_configfd, F_GETFL, 0) < 0) {
X		sprintf(err, "tripwire: Couldn't open fd %d!  fcntl()", 
X			specified_configfd);
X		perror(err);
X		exit(1);
X	    }
X	    continue;
X	}
X	/* specify dbase file descriptor */
X	if (strcmp(pc, "-dfd") == 0) {
X	    char err[512];
X
X	    /* check to see that there is an argument */
X	    if ((pc = argv[++i]) == NULL) {
X		usage();
X	    }
X	    specified_fd = pc;
X	    if (!sscanf(specified_fd, "%d", &specified_dbasefd)) {
X		usage();
X	    }
X	    /* if we try to read stdin, we'll block, so skip read */
X	    if (specified_dbasefd != 0 &&
X				fcntl(specified_dbasefd, F_GETFL, 0) < 0) {
X		sprintf(err, "tripwire: Couldn't open fd %d!  fcntl()", 
X			specified_dbasefd);
X		perror(err);
X		exit(1);
X	    }
X	    continue;
X	}
X	/* ignore specified signatures */
X	if (strcmp(pc, "-i") == 0) {
X	    int tmpflag;
X
X	    /* check to see if there is an argument */
X	    if ((pc = argv[++i]) == NULL) {
X		usage();
X	    }
X	    if (strcmp(pc, "all") == 0) {
X		runtimeignore = IGNORE_0_9;
X		continue;
X	    }
X	    if ((sscanf(pc, "%d", &tmpflag)) != 1)
X		usage();
X	    runtimeignore |= (IGNORE_0 << tmpflag);
X	    continue;
X	}
X	/* ignore specified signatures */
X	if (strcmp(pc, "-debug") == 0) {
X	    /* check to see if there is an argument */
X	    if ((pc = argv[++i]) == NULL) {
X		usage();
X	    }
X	    if ((sscanf(pc, "%d", &debuglevel)) != 1)
X		usage();
X	    continue;
X	}
X	/* print out version information */
X	if (strcmp(pc, "-version") == 0) {
X	    version();
X	}
X	/* loosedir rules */
X	if (strcmp(pc, "-loosedir") == 0) {
X	    loosedir = 1;
X	    continue;
X	}
X	/* print out version information */
X	if (strcmp(pc, "-help") == 0) {
X	    tw_help_print(stderr);
X	    exit(0);
X	}
X	/* interactive mode */
X	if (strcmp(pc, "-interactive") == 0) {
X	    interactivemode++;
X	    continue;
X	}
X	/* define (-Dfoo=bar) */
X	if (strncmp(pc, "-D", 2) == 0) {
X	    char key[512], value[512];
X
X	    if (!pc[2]) {
X		fputs("tripwire: -D requires an argument!\n", stderr);
X		exit(1);
X	    }
X	    (void) string_split_ch(pc+2, key, value, '=');
X	    tw_mac_define(key, value);
X	    continue;
X	}
X	/* undef (-Ufoo) */
X	if (strncmp(pc, "-U", 2) == 0) {
X	    if (!pc[2]) {
X		fputs("tripwire: -U requires an argument!\n", stderr);
X		exit(1);
X	    }
X	    tw_mac_undef(pc+2);
X	    continue;
X	}
X	/* undocumented: test interactive mode */
X	if (strcmp(pc, "-interactivetest_yesimsure") == 0) {
X	    test_interactive = 1;
X	    continue;
X	}
X	usage();
X    }
X
X    /* argument sanity checking */
X    /*		are two files set to read from stdin? */
X    if (specified_configfile != NULL && specified_dbasefile) {
X	if (strcmp(specified_configfile, "-") == 0 &&
X	    strcmp(specified_dbasefile, "-") == 0) {
X	    fprintf(stderr, "%s: specified database and configuration file can't be both be stdin!\n", progname);
X	    exit(1);
X	}
X    }
X    /* interactive mode and update mode? */
X    if (interactivemode && pp_updateentries) {
X        fprintf(stderr, "%s: conflicting mode directives!  Aborting...\n",
X		progname);
X	exit(1);
X    }
X    /* specified configfile and configfd? */
X    if (specified_configfile && (specified_configfd != -1)) {
X	fprintf(stderr, "%s: specified file and file descriptor for configuration file!\n", progname);
X	exit(1);
X    }
X    /* specified dbasefile and dbasefd? */
X    if (specified_dbasefile && (specified_dbasefd != -1)) {
X	fprintf(stderr, "%s: specified file and file descriptor for database file!\n", progname);
X	exit(1);
X    }
X
X    /*** we handle specified dbasefile file descriptors by writing it to
X     *** a file -- converting this case to a specified dbase file.
X     *** plus, it allows us to rewind the input stream properly
X     ***/
X    if (specified_dbasefd >= 0) {
X	char *tmpfilename;
X	FILE *fpin, *fpout;
X	int c;
X
X	/* generate temporary file name */
X	if ((tmpfilename = (char *) malloc(L_tmpnam)) == NULL) {
X	    perror("main: malloc()");
X	    exit(1);
X	};
X	(void) strcpy(tmpfilename, TEMPFILE_TEMPLATE);
X
X	if ((char *) mktemp(tmpfilename) == NULL) {
X	    perror("main: mktemp()");
X	    exit(1);
X	}
X
X	/* copy file descriptor input into temporary file */
X	/*  input */
X	if (!(fpin = fdopen(specified_dbasefd, "r"))) {
X	    fprintf(stderr, "Couldn't open input database file descriptor!\n");
X	    exit(1);
X	}
X	/*  output */
X	if (!(fpout = fopen(tmpfilename, "w"))) {
X	    char err[1024];
X	    sprintf(err, "main: fopen(%s)", tmpfilename);
X	    perror(err);
X	    exit(1);
X	}
X	/*  copy */
X	while ((c = getc(fpin)) != EOF)
X	    putc(c, fpout);
X	fclose(fpin);
X	fclose(fpout);
X
X	/* save the name of the temporary file */
X	specified_dbasefile = tmpfilename;
X    }
X
X    /* initialize lists */
X    list_init();
X
X    /* build hostname specific names */
X    filename_hostname_expand(&config_path);
X    filename_hostname_expand(&config_file);
X    filename_hostname_expand(&database_path);
X    filename_hostname_expand(&database_file);
X
X    /* recompute the default ignore string (old -> new format) */
X    (void) strcpy(mask, defaultignore);
X    ignore_configvec_to_dvec(mask);
X    defaultignore_parsed = mask;
X    
X    /* if we are creating a database, make sure the database troving directory
X     * exist.
X     */
X#define DATABASE_REPOSITORY "./databases"
X
X    if (dbaseinit || interactivemode || numupdateentries > 0) {
X	int fd;
X	if ((fd = open(DATABASE_REPOSITORY, 0)) >= 0) {
X	    close(fd);
X	} else {
X	    if (mkdir(DATABASE_REPOSITORY, 0777) >= 0) {
X		if (!quietmode) {
X		    fprintf(stderr, "### Warning:\tcreating %s directory!\n",
X					DATABASE_REPOSITORY);
X		    fprintf(stderr, "###\n");
X		}
X	    } else {
X		char errstr[1024];
X		sprintf(errstr, "%s: mkdir(%s)", progname, DATABASE_REPOSITORY);
X		perror(errstr);
X		exit(1);
X	    }
X	}
X    }
X
X    /* are we in database generation mode? */
X    if (dbaseinit) {
X	char *oldpath = database_path;
X	char *newpath = database_path = "./databases";
X	struct list *dbase_entry_list = (struct list *) NULL;
X
X	/* place database in ./databases */
X	database_path = newpath;
X
X	/* generate the database */
X	configfile_read(&olddbase_list, &dbase_entry_list);
X	database_build(&olddbase_list, DBASE_PERMANENT, &dbase_entry_list);
X	if (!quietmode) {
X	    fprintf(stderr, "###\n");
X	    fprintf(stderr,
X"### Warning:   Database file placed in %s/%s.\n", database_path,
X							database_file);
X	    fprintf(stderr, "###\n");
X	    fprintf(stderr,
X"###            Make sure to move this file file and the configuration\n");
X	    fprintf(stderr,
X"###            to secure media!\n");
X	    fprintf(stderr, "###\n");
X	    fprintf(stderr,
X"###            (Tripwire expects to find it in '%s'.)\n", oldpath);
X	}
X	cleanup();
X	exit(0);
X    }
X
X    /*
X     * 	make sure that database file is there!
X     * 		(this is meaningless if we specified stdin "-")
X     */
X
X    if (specified_dbasefile == NULL)
X	sprintf(database, "%s/%s", database_path, database_file);
X    else
X	(void) strcpy(database, specified_dbasefile);
X
X    if (!printpreprocess && strcmp(database, "-") != 0) {
X	if ((fd = open(database, O_RDONLY)) < 0) {
X	    fprintf(stderr,
X		    "%s: database file '%s' does not exist!  Aborting...\n",
X		    progname, database);
X	    exit(1);
X	}
X	(void) close(fd);
X    }
X
X    /* are we in database update mode? */
X    if (numupdateentries) {
X	update_mark(pp_updateentries, numupdateentries);
X	cleanup();
X	exit(0);
X    }
X
X    /* we're in integrity checking mode */
X    update_gather(interactivemode, &pp_updateentries);
X    /* do we do the interactive update? */
X    if (interactivemode && pp_updateentries) {
X	list_reset(&olddbase_list);
X	list_reset(&diff_added_list);
X	list_reset(&diff_deleted_list);
X	list_reset(&diff_changed_list);
X
X	/* reset the ignore flags so we scan all signatures */
X	runtimeignore = 0;
X
X	for (i = 0, pc = pp_updateentries[i]; pc; i++, 
X					    pc = pp_updateentries[i]) {
XSPDEBUG(0) 
Xprintf("Updating entry: %s\n", pc);
X	}
X	numupdateentries = i;
X
X	if (!quietmode) {
X	    fprintf(stderr, "### Updating database...\n###\n");
X	}
X	update_mark(pp_updateentries, numupdateentries);
X	cleanup();
X	exit(0);
X    }
X
X    cleanup();
X
X    /* our exit status is based on files added/deleted/changed */
X    if (diff_added_num)
X	exitstatus |= 2;
X    if (diff_deleted_num)
X	exitstatus |= 4;
X    if (diff_unignored_num)
X	exitstatus |= 8;
X    exit(exitstatus);
X    /*NOTREACHED*/
X}
X
Xvoid
Xcleanup()
X{
X    /* delete temporary database file (derived from specified dbasefd) */
X    if (specified_dbasefd >= 0) {
X	unlink(specified_dbasefile);
X    }
X}
X
END_OF_FILE
if test 16656 -ne `wc -c <'tripwire-1.1/src/main.c'`; then
    echo shar: \"'tripwire-1.1/src/main.c'\" unpacked with wrong size!
fi
# end of 'tripwire-1.1/src/main.c'
fi
echo shar: End of archive 18 \(of 25\).
cp /dev/null ark18isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 25 archives.
    echo "Now read tripwire-1.1/README.kits"
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
