bsign-0.4.5/0040775000175000017500000000000007714272757010750 5ustar elfelfbsign-0.4.5/.cvsignore0100660000175000017500000000026606722034044012724 0ustar elfelf*~ bsign o extra sha-gillogy yes *.bin config.h Makefile depend.m data data.asc elf.cxx sha.c config.log config.cache config.status _version.h .version *.out all allfiles .cvsignore bsign-0.4.5/.gdbinit0100660000175000017500000000015407421163102012334 0ustar elfelffile bsign set args -s linear.o set args -s -d -f files -P "--homedir ." set args -i . set args -s -i . foo bsign-0.4.5/.version_major0100660000175000017500000000000206631357462013601 0ustar elfelf0 bsign-0.4.5/.version_minor0100660000175000017500000000000207421417650013607 0ustar elfelf4 bsign-0.4.5/.version_patch0100660000175000017500000000000207714272611013563 0ustar elfelf5 bsign-0.4.5/LSM0100660000175000017500000000153207104573067011307 0ustar elfelfBegin3 Title: bsign - embed hash and signature in elf executables Version: <> Entered-date: <> Description: The purpose of bsign is to verify and authenticate data files, especially executables. It rewrites ELF executables, embedding a segment with a hash and perhaps a signature. The original motive for developing bsign was to discover files corrupted by faulty computer hardware. The authentication feature was an obvious enhancement. Keywords: GPG SHA1 embedded hash digital signature ELF Author: elf@buici.com (Marc Singer) Maintained-by: elf@buici.com (Marc Singer) Primary-site: ftp.buici.com /pub/bsign <> <> Platforms: Any UN*X. Tested on GNU/Linux and Solaris. C++ necessary to build from source. CVS and possibly RCS to use. Copying-policy: GPL End bsign-0.4.5/Makefile.in0100660000175000017500000002172007425064630012774 0ustar elfelf# -*- Makefile -*- # Makefile.in # $Id: Makefile.in,v 1.24 2002/01/27 20:56:56 elf Exp $ # # written by Oscar Levi # 11 December 1998 # # This file is part of the project BSIGN. See the file README for # more information. # # Copyright (C) 1998 The Buici Company. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # in a file called COPYING along with this program; if not, write to # the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA # 02139, USA. # # .PHONY: install clean all version revision patch # # --- Project specification # TARGET=bsign PACKAGE=bsign O=o/ SRC=\ main.cxx options.cxx sha1.c bsign.cxx conversion.cxx ds.cxx \ exec.cxx files.cxx tty.cxx exitstatus.cxx filewalk.cc signal.cc ___OBJ=$(SRC:.cc=.o) __OBJ=$(___OBJ:.c=.o) _OBJ=$(__OBJ:.cxx=.o) OBJ=$(_OBJ:.s=.o) VERSION_HEADER=version.h RELEASE_PATH=${HOME}/release CC=@CC@ CXX=@CXX@ CFLAGS=@CFLAGS@ @DEFS@ #CFLAGS_O=-O2 #CFLAGS_O=-O2 -fomit-frame-pointer #CFLAGS_P=$(CFLAGS) -pg CFLAGS_=-g $(CFLAGS_I)@CFLAGS_W@ $(CFLAGS_O) $(CFLAGS_P) CXXFLAGS=$(CFLAGS) CXXFLAGS_=$(CFLAGS_) LFLAGS=-g -static @LDFLAGS@ @LIBS@ #LFLAGS=-g @LDFLAGS@ @LIBS@ #LFLAGS=-pg ${LFLAGS} DEPEND=depend.m ECHO=@/bin/echo INSTALL=@INSTALL@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ # # --- Autoconf generated symbols # srcdir = @srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ docdir = $(prefix)/share/doc/$(PACKAGE) infodir = @infodir@ mandir = $(prefix)/share/man/ # This is removed because it generates a line in the Makefile.in that # breaks the use of 'make -f Makefile.in distclean' from # debian/rules. Besides, we don't call make on subdirectories. # @SET_MAKE@ # # --- Implicit rules # vpath %.o $O %.o: %.c $(make_o) $(ECHO) $(CC) -c $(CFLAGS) -o $O$@ $< @$(CC) -c $(CFLAGS) $(CFLAGS_) -o $O$@ $< $O%.o: %.c $(make_o) $(ECHO) $(CC) -c $(CFLAGS) -o $@ $< @$(CC) -c $(CFLAGS) $(CFLAGS_) -o $@ $< %.o: %.cxx $(make_o) $(ECHO) $(CXX) -c $(CXXFLAGS) -o $O$@ $< @$(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -o $O$@ $< $O%.o: %.cc $(make_o) $(ECHO) $(CXX) -c $(CFLAGS) -o $@ $< @$(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -o $@ $< %.o: %.cc $(make_o) $(ECHO) $(CXX) -c $(CXXFLAGS) -o $O$@ $< @$(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -o $O$@ $< $O%.o: %.cxx $(make_o) $(ECHO) $(CXX) -c $(CFLAGS) -o $@ $< @$(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -o $@ $< %.o: %.s $(make_o) $(ECHO) $(AS) $(AFLAGS) -o $O$@ $< @$(AS) $(AFLAGS) $(AFLAGS_) -o $O$@ $< $O%.o: %.s $(make_o) $(ECHO) $(AS) $(AFLAGS) -o $@ $< @$(AS) $(AFLAGS) $(AFLAGS_) -o $@ $< %.i: %.cxx $(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -E -o $(notdir $@) $< %.s: %.cxx $(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -S -o $@ $< %.i: %.cc $(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -E -o $(notdir $@) $< %.s: %.cc $(CXX) -c $(CXXFLAGS) $(CXXFLAGS_) -S -o $@ $< %.s: %.c $(CC) -c $(CFLAGS) $(CFLAGS_) -S -o $@ $< # # --- Primary targets # all: check_depend make_o _version.h $O$(TARGET) $(TARGET) .PHONY: make_o make_o: @if test ! -d $O ;\ then echo === Creating \'$O\' output directory ; mkdir $O ; fi $O$(TARGET): $(OBJ) $(CXX) -o $@ $(addprefix $O,$(OBJ)) $(LFLAGS) cp $@ $@-unstripped strip $@ # This is here in case we find a way to prevent linkage against libstdc++ # $(CC) -o $@ $(addprefix $O,$(OBJ)) $(LFLAGS) $(TARGET): $O$(TARGET) @echo -- Linking $(TARGET) to $O$(TARGET) @-ln -s $O$(TARGET) . clean: ifneq "$O" "" -rm -rf $O else -rm $(OBJ) endif -rm *.i -rm build .PHONY: dist_clean distclean dist_clean distclean: clean -rm -f \#* *~ *.sed *.i *.cod -rm -f config.cache config.status config.log -chmod +w Makefile config.h -rm Makefile config.h $(DEPEND) .PHONY: debclean debclean: distclean # # --- Version and Build Engineering # .version: .version_major .version_minor .version_patch @/bin/echo -n `cat .version_major`.`cat .version_minor`.`cat \ .version_patch` > .version _version.h: .version @/bin/echo -e \#define SZ_VERSION \"`cat .version`\" > _version.h .PHONY: transmit transmit: # distribution-archive @distftp.sh ${PACKAGE} \ ${RELEASE_PATH}/${PACKAGE}-`cat .version`.ANNOUNCEMENT \ ${RELEASE_PATH}/${PACKAGE}-`cat .version`.README \ ${RELEASE_PATH}/${PACKAGE}-`cat .version`.lsm \ ${RELEASE_PATH}/${PACKAGE}_`cat .version`_i386.deb \ ${RELEASE_PATH}/${PACKAGE}-`cat .version`.tar.gz version.sed: _version.h @echo Creating version-specific sed script... @/bin/echo s/\<\\>/`cat .version`/ > version.sed @/bin/echo s/\<\\>/`date +"%d%b%y" \ | sed -e y/abceglnoprtuvy/ABCEGLNOPRTUVY/`/ >> version.sed @/bin/echo s/\<\\>/${PACKAGE}-`cat .version`.tar.gz/ \ >> version.sed @/bin/echo s/\<\\>/${PACKAGE}-`cat .version`.lsm/ >> version.sed .PHONY: ${PACKAGE}.lsm ${PACKAGE}.lsm: version.sed LSM @echo Creating LSM file... @if test -f *.lsm ; then rm *.lsm ; fi @sed -f version.sed LSM > ${PACKAGE}-`cat .version`.lsm .PHONY: ${PACKAGE}.ANNOUNCEMENT ${PACKAGE}.ANNOUNCEMENT: version.sed ANNOUNCEMENT @echo Creating ANNOUNCEMENT file... @if test -f *.ANNOUNCEMENT ; then rm *.ANNOUNCEMENT ; fi @sed -f version.sed ANNOUNCEMENT \ > ${PACKAGE}-`cat .version`.ANNOUNCEMENT @cat ${PACKAGE}-`cat .version`.lsm \ >> ${PACKAGE}-`cat .version`.ANNOUNCEMENT .PHONY: ${PACKAGE}.README ${PACKAGE}.README: version.sed README @echo Creating README file... @if test -f *.README ; then rm *.README ; fi @sed -f version.sed README > ${PACKAGE}-`cat .version`.README .PHONY: distribution-archive da distribution-archive da: ${PACKAGE}.lsm ${PACKAGE}.ANNOUNCEMENT ${PACKAGE}.README dist_clean @echo Creating distribution archive... @/bin/sh -c "if test -x ../${PACKAGE}-`cat .version`;\ then rm ../${PACKAGE}-`cat .version` ; fi" @ln -s ${PACKAGE} ../${PACKAGE}-`cat .version` @find . -path CVS -prune\ -o -path o -prune\ -o -regex .\*/${PACKAGE} -prune\ -o -regex .\*/configure -prune\ -o -regex .\*/mkinstalldirs -prune\ -o -regex .\*/rules -prune\ -o -regex .\*/config.status -prune\ -o -regex .\*\.o -prune\ -o -type f -exec chmod 644 \{\} \; @/bin/sh -c 'cd .. ; V=`cat ${PACKAGE}/.version` ;\ tar zcf ${PACKAGE}-$$V.tar.gz\ `find ${PACKAGE}-$$V/\ -regex .\*/CVS -prune\ -regex .\*/debian/package -prune\ -o -regex .\*~ -prune\ -o -regex .\*/o -prune\ -o -regex .\*\\\\.o -prune\ -o -regex .\*\\\\.a -prune\ -o -regex .\*\\\\.m -prune\ -o -regex .\*\\\\.bmp -prune\ -o -regex .\*\\\\.terminfo -prune\ -o -regex .\*\\\\.gpg -prune\ -o -regex .\*\\\\.asc -prune\ -o -regex .\*/${PACKAGE} -prune\ -o -regex .\*/Makefile -prune\ -o -regex .\*/config.cache -prune\ -o -regex .\*/config.h -prune\ -o -regex .\*/config.log -prune\ -o -regex .\*/config.status -prune\ -o -regex .\*/configure.scan -prune\ -o -regex .\*/log -prune\ -o -regex .\*/gmon.out -prune\ -o -regex .\*/\.cvsignore -prune\ -o -regex .\*/\.gdbinit -prune\ -o -regex .\*/NOTES -prune\ -o -regex .\*/patches -prune\ -o -type f -print | sort`' @-rm ../${PACKAGE}-`cat .version` @echo Moving distribution file to ${RELEASE_PATH}... @mv ../${PACKAGE}-`cat .version`.tar.gz ${RELEASE_PATH} @mv ${PACKAGE}-`cat .version`.* ${RELEASE_PATH} #.PHONY: announce #announce: # @echo -n "CurVeS " > _announce # @cat .version >> _announce # @echo " -- console UI for CVS" >> _announce # @echo "Posting to comp.os.linux.announce..." # @cat ${RELEASE_PATH}/${PACKAGE}-`cat .version`.lsm \ # | mail -s "`cat _announce`" linux-announce@news.ornl.gov # @echo "Updating LSM..." # @cat ${RELEASE_PATH}/${PACKAGE}-`cat .version`.lsm \ # | mail -s "add" lsm@execpc.com # @rm _announce # # --- Installation # .PHONY: install installdirs install: installdirs $(TARGET) # hello.info $(INSTALL_PROGRAM) $(TARGET) $(bindir)/$(binprefix) strip $(bindir)/$(binprefix)/$(TARGET) $(INSTALL_DATA) bsign_sign $(docdir)/scripts $(INSTALL_DATA) bsign_verify $(docdir)/scripts $(INSTALL_DATA) bsign_hash $(docdir)/scripts $(INSTALL_DATA) bsign_check $(docdir)/scripts $(INSTALL_DATA) ${PACKAGE}.1 $(mandir)/man1 installdirs: $(srcdir)/mkinstalldirs $(bindir) $(docdir) $(docdir)/scripts $(mandir)/man1 # # --- Dependencies: depend.m # .PHONY: depend check_depend depend: _version.h $(DEPEND) $(DEPEND) depend: _version.h # $(SRC) $(CXX) $(CFLAGS_I) -DHAVE_CONFIG_H -M $(SRC) > $(DEPEND) check_depend: @if test ! -s ${DEPEND} ; then \ echo "-- Use 'make depend' to create dependencies file." \ " Continuing without it." ; fi # # --- Include dependencies always. Configure creates an empty file # ifneq "$(wildcard $(DEPEND))" "" include ${DEPEND} endif bsign-0.4.5/NOTES0100660000175000017500000000750707425630077011555 0ustar elfelf- hash_elf generates a signature section for a ELF file. The algorithm rewrites the file, removing the old signature if there was one, hashes this portion, and appends the new signature to the end. This depends only on us knowning the length of the cert. In theory, we could put our signature section anywhere in the file, but this layout is convenient at the time. The most likely enhancement from here would be the ability to update a signature in place, making this function more efficient, and making the hashing a little more difficult. Note that if we indend to use digital certificates, we can support signature in the middle of the file by setting the signature section to known contents, nulls perhaps. - Signing /sbin/init Due to the way the reboot happens, signing init will prevent the system from a clean reboot. I suspect this is because signing replaces the file on disk in a way that init cannot detect. It (kernel or init) thinks that the filesystem carrying init is busy and won't mark the partition as clean. There are a couple of solution. We can 'telinit -u' to restart init and reload from disk. This is shown to work on Linux. We can also prevent resigning executables with already valid signatures. Thus preventing the problem in the future. - Performance improvements - It may make things faster if we didn't mmap whole files until we are convinced that we are going to rewrite the file. In fact, I am sure this is one of the things that makes the program slow. - It isn't clear that this is the bottleneck. Certainly we could perform signature rewrite in place, but that isn't the critical path. It appears that the performance problem is due to gpg. Hash check seems to be speedy as is hash write. - Bugs - The semantics of the -f switch mean that switches that follow it will not be processed before the files are read. Either eliminate the method (prefering fts), or postpose these arguments until the other arguments have been processed. Or document the dependency well. - Like to handle this with an insert method to FileWalk where we add files from the command line to the object. Also, we can implement the -f flag the same way. Nice. ** fixed - Need ^C protection. Need to unlink temporaries. Need to make sure we don't lose a file due to the small window of opportunity given when we do the rename swap. ** done - Need to detect the unavailability of the gpg program. There is some logic to do this, but it is weak. It would be better to use the libgcrypt library since that solves two problems. - Non-x86 - Need to verify that the bsign code handles other architectures properly. I don't believe so based on the g_fOppositeSex flag set in bsign.cxx. Fortunately, we have debian machines to test against. - Considerations - Consider changing the name of the section from "signature" to "bsignature" so as to prevent confusion. Perhaps. - Check the ramifications of signing kernel modules. Does the signature get loaded. - Replace all of the temp file handling with tmpfile. It will not leave skid-marks. It isn't that easy. We are using temp files during the replace_file process that we need to be able to rename and that we intend to make permanent. *** solved in another way. The warning is gone and we are now using a signal catcher to perform cleanup. - Do we a) require root. or b) check for proper status replication. a) no. We generate an error if we cannot reproduce a file's permissions or cannot write in a given directory. This is the most friendly way. b) I'm not sure that we have a problem here. The dup_status function appears to work now that it is changed to set the owner before the permissions.bsign-0.4.5/README0100660000175000017500000002673007425630077011621 0ustar elfelf ============= Bsign README $Id: README,v 1.10 2002/01/29 23:29:03 elf Exp $ ============= by Marc Singer, elf@buici.com 14 January 2002 (last revision) for version <> This document serves as an orientation guide to bsign, a program for embedding and verifying hash values and digital signatures. 1. Introduction The original motivation for bsign came from experience maintaining GNU/Linux systems that ran continuously for several years, long enough for hardware failure to be a significant impediment to reliable operation. The idea was to augment binary files with information necessary to verify data integrity. The addition of digital signatures is an obvious extension of the same idea and serves the goal of verifying the origin of the hashed file. As of the start of 2002, there are two applications that perform system file integrity verification. Both of them, tripwire and integrit, use a database to store hashes of each file's contents and other information about the file. Bsign stores the integrity check data in the executables themselves. As a result, bsign the gpg public key can be stored on a small, read-only medium such as a floppy, guaranteeing the integrity of the check mechanism. This release of bsign is in use on production systems. Mail questions and comments to the author, elf@buici.com. 1.1. Copyright The bsign program is Copyright (C) 1998,1999,2000,2001,2002 by The Buici Company. It is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 1.2. Sources for related programs o GNUPG, the GNU Privacy Guard is the only supported software for creating digital signatures. o Tripwire is a program that shares some of the attributes of bsign. Last time I looked, it generates a potentially large database of hash values for the files on a host which it kept on a removable medium. I developed bsign after testing tripwire and finding it unsuitable. Version 2.3 of tripwire is available from the Debian package mirrors. apt-get install tripwire o The Integrit project is hosted by sourceforge. While I haven't tried it, integrit shares the database feature of tripwire making it unsuitable for a read-only floppy setup. 1.3 The most current source for Bsign The primary site for Bsign source is Buici. 1.4 Feedback and Bug Reports Bug reports may be sent to the author at . There is a plan to incorporate some form of automatic bug report generation within the application, but until that is available, e-mail is likely to produce a response. 1.5 Disclaimer This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 1.6 Known Issues o Release 1.0.6 of gpg does not permit signature verification using a key on a read-only medium. For the time being, the verification diskette must remain writable. o The ELF-64 format is unsupported. Bsign will fail to sign a ia64 and alpha executables. o Cross-platform signing works as long as the endianness of the host and target are the same. Bsign will fail to sign when the endianness differs. o When gnupg fails, bsign sometimes needs to guess that the reason is that it isn't installed. Error messages indicate this possibility. It would be better if bsign checked for the presence of the program explicitly, or if bsign used libgcrypt. 2. Usage There are two modes for using bsign: verifying program integrity, and verifying program authenticity. In the first mode, bsign embeds a checksum in each executable that is easily verified by bsign. An error in the checksum indicates corruption. In second mode, bsign embeds a checksum and then signs it. The setup for signatures requires a few more steps in order to prevent tampering. 2.1 Signing Executables with Bsign The concept of signing executable programs is simple. Create a gpg key pair. Sign executables on the target host. Physically remove the secret key from the machine and leave the public key available on a read-only medium. Check signatures regularly. The devil is in missing the details. 2.1.1 Prepare Key Diskettes The paranoid operator will want to start as cleanly as possible. For those running Debian, it is sufficient to install the bsign package. Otherwise, download the bsign source archive from ftp.buici.com. Bring the host down to single user mode. telinit s Build bsign. tar zxf bsign_<>.tar.gz cd bsign-<> configure make Format and mount a floppy diskette. Copy the bsign executable to it. Create a gpg key pair using the diskette as home. Note that gpg appears to require a complete UNIX filesystem for the homedir. So, I format the diskette for ext2. superformat /dev/fd0 mke2fs /dev/fd0 mount /dev/fd0 /floppy cp bsign bsign_sign /floppy gpg --homedir /floppy --gen-key Copy the public key to the hard drive and unmount the floppy diskette. mkdir bsignkey cp /floppy/pubring.gpg bsignkey umount /floppy Format and mount another diskette. Copy those files to this floppy as well as bsign and then unmount it. superformat /dev/fd0 mke2fs /dev/fd0 mount /dev/fd0 /floppy cp bsignkey/* bsign bsign_verify /floppy umount /floppy At this point, you have two diskettes. Both have a copy of bsign. One contains only the public key while the other contains both the public and private keys. Label the diskettes appropriately and toggle the read-only tabs to prevent accidental erasure. 2.1.2 Sign Everything Insert the diskette with the secret key into the floppy drive. You may want to edit some of the parameters in the bsign_sign script. It will sign everything on the filesystem while excluding some of the inappropriate directories. When the script is ready, sign everything on the hard drive. /floppy/bsign_sign Bsign will ask key for the passphrase one time when it first signs a file. This whole process may take some time. When it finishes, it has undoubtedly signed /sbin/init. It may be necessary to restart init after the executable has changed to prevent a unclean shutdown. Just in case, restart init. telinit q Unmount the diskette and store it in safe place. You may wish to make a copy of the diskette, though it isn't important since the key itself is only used to verify the identity of the user who signed the executables. 2.1.3 Setup Regular Signature Verification In principle, you will want to leave the public-key-only diskette in the floppy drive and configure a cron job to call the bsign_verify regularly. With a diskette in the floppy drive, you may want to change the system BIOS to avoid attempts to boot the key diskette. This setup will verify the system every night. Insert the public-key diskette into the floppy drive. Check that the command is correct for your system. Make sure the following (or an equivalent) fstab entry exists to mount the floppy on access. /dev/fd0 /floppy auto defaults 0 0 Test the script. /floppy/bsign_verify When it completes, check the mail that it sends. It should not report any failed signatures. Create a crontab entry to check the signatures. Make sure this is added to the root crontab. 10 1 * * * /floppy/bsign_verify You will get an email report every night of the unsigned or invalidly signed programs. 2.2 Hashing Executables Protecting a host by only hashing executables is much simpler than attempting to sign them. The bsign_hash script will hash everything in the filesystem. Then, add the crontab entry to check them automatically. On a Debian system, it might look like this: 10 1 * * * /usr/share/doc/bsign/scripts/bsign_check 3. Security Considerations While the only secure computer is one that is turned off, the need for running systems overwhelms us. The next most secure systems are those that eliminate all but essential services and those where network logins are protected by secure passwords. Still, clear-text passwords will be sniffed by crackers and dissatisfied employees will inveigle backdoor entrances. If a system is cracked and a root-kit installed, standard system utilities are replaced by patched program that conceal the intruder. Bsign will detect these files, alerting the operator that something has changed. Bsign, statically linked and stored on the diskette, depends on gpg as an external program. When Werner Koch finishes with his libgcrypt library, I'll link that in, too, so that bsign requires neither dynamic libraries nor external programs. The validation script depends on cron, and the mail subsystem. Problems with these will only delay discovery of a compromised host. As long as the secret key is intact, a system may be taken off-line and scanned for untrusted software. Once found, corrupted packages on Debian system are easily restored apt-get install --reinstall Without a tool like bsign, it is usually more time efficient to rebuild the host from scratch than to attempt to discover and erradicate untrusted software. Once compromised, it is important to discover the means of entry. Replace software with an known exploits. In addition, the system password file is forfeit as well as the ssh server key. 4. Signature Format Bsign creates an ELF section at the end of the file to contain the hash and optional digital signature. The name of the section is "signature" and the type is the four byte string 0x80, 's', 'i', 'g'. The signature section begins with a newline terminated identification string. The first chacter is a '#' followed by a version number and a semicolon. In version 1, the rest of the line identifies the program, bsign, and its version number. The next twenty bytes are the SHA1 hash of the file contents including a signature section initialized to null bytes. The hash is written as binary data in MSB order. Following the hash is a two byte, MSB ordered length of the digital signature, if there is one. This signature data is in the OpenPGP packet format as generated by GNUPG and PGP. At the moment, only GNUPG is supported. This format is intentionally simple since it is likely to be read many more times by the machine than my humans. Signature date stamps, file permissions, or ownership bits are not included in this version, but may be added by incrementing the version number and restructuring the signature data. It may appear strange that the file is hashed and then the digital signature is made on this hash. While the digital signature is sufficient for verifying the validity of the hash, the original intention of bsign is to detect file corruption. files may be hashed without being digitally signed. By using a separate hash, the file contents may be verified without checking the signature, and therefore, without the need for gpg. ;;; Local Variables: *** ;;; mode: indented-text *** ;;; End: *** bsign-0.4.5/TODO0100660000175000017500000001536107421727040011420 0ustar elfelfTODO ---- - Stream-ify sha code. There is code from Cerberus to do sha that is already streamified. We could use theirs if their license did not prohibit commercial use. * using gnupg code. Already streamified and under GPL. - Craft section contents. I suspect I need to store the original header so it is easy to determine which fields I changed. Or!, I could store a precomputed hash of the original header and use this to initialize the hash for the rest of the file. This means that I'll also want to hash the new header and store that so I can tell if the header was changed *after* me. (SHA) original header (SHA) new header (SHA) original file I think I want an ASCII format so it is easy to extend and maintain. hash_header_original = (SHA) ... hash_header_modified = (SHA) ... hash_file_original = (SHA) ... Also, if we sign this, it is easy to make sense of the signature and maintain readability and extensibility of the hash data. If someone gripes about space, we can always compress it with zlib. We may want to add a few other items to help us detect why a file has changed. For example, timestamps, ownership. * Our present algorithm is simplified to accomodate the signature data and to be able to sign and resign the same program, we have a straightforward hash which is the the hash of the file, rewritten to accomodate a section large enough for the signature initialized to nulls. There is only one entry in the data. - Need to decide if we will use BFD library or if we will simply write the file using our knowledge of the format. I suspect the latter will be acceptably easy. * Presently, we use our own code which is simple and fast and effective. * BFD code means portability. It also means that the statically linked executable is going to be huge. Also, we need to make sure we are portable. - If we compress the data, there is a chicken/egg paradox in that the exact size cannot be known until we compress. So, either we guess, or we attempt to converge. I believe that compression will therefore be unlikely. Also, I suspect that the space saving will be insignificant since disk blocks are allocated on 1K boundaries. * We don't compress. We *do* need to add hooks to estimate the amount of signature data. ** Although this isn't crucial as long as we know that a signature fits in 1/2K. If we every go to recursive signatures, this may need revision. - May be interesting to be able to store the certs external to files, too. I like embedded ones for exe's because we can say for certain that a given binary file is good. Certs embedded in text files? We could establish a method for supporting this. For example, some files have a comment structure that makes it possible to embed our data there. Also, these would be less sensitive to compression because there is no header. Thus, we could sign a text file with a signature only. Or we could continue to use our hash_original and sign just the hash. - Does signing many short messages affect the permeability of a public encryption key? * Apparently we don't need to worry about this as long as the hash collisions are unpredictable. - Need to finish out the command interface to let us rewrite a file and keep the same name, to rewrite to another file, and to verify the signature. I think the latter should be the default. Also, need to check that permissions, ownerships, and timestamps are perserved. Don't forget that we want to store timestamps in the hashed data section so that signing it is interesting. All in all, we are now very close. ** done - Think about other fields we may want to put in the hash. Dates? Who signed? Are these accomodated by the pgp? gpg? * We could, perhaps, grab these from the cert. If not, we can easily extract them at the time of signing. I know that the date, for example, is in the cert. We could probably just extract this. However, if we don't embed a cert, we need to generate this data and store it. - Need to think about return codes: 0: OK, success 1: Signature invalid 2: Hash invalid 3: Unsigned, no hash or signature 4: No digital signature found and its presence is required by command line option. 5: File not elf (or other signable format). ** I think that this is done. - Accept '--output -' - Configure script is VERY inadequate - Need to hide pass phrase. Need to cache pass phrase if this isn't already done. ** done * Need to implement PGP as well as more options for handling the specific signature ID used. ** I think that the ID problem is handled by -P. - Should be able to accept a list of filenames on stdin and only sign those that are elf. This means we can do a find on a drive and sign everything in one pass. **added, -f - It would be cool to write a script to check all of the elf files and generate a list of the unsigned files. ** available with -V and -f options - Would be cool to accept default key ID for selecting the proper key. In fact, it would be good to accept a slew of gpg options, perhaps as a parenthetic option. ** added as --pgoptions - Link resolution appears to be broken. I cannot sign /proc/#/exe which ought to work when we follow links. ** fixed - We leave temporaries around when something goes wrong. It may be because the file isn't ELF. ** fixed - We leave temporaries around when we catch a signal. What do we do here? Perhaps the best method would be to have a list of temporaries available to the kill handler. ** fixed - Option to ignore links **added - ls-2.0.7.so won't sign **fixed * Workflow scripts - Sign or resign everything and 'telinit -u' if init was signed. - Check signatures and report (email) the unsigned ones to root. - Sign unsigned files from a list. - Sign all unsigned files. - *** signature check shouldn't change atime. == 2002.01.16 - Check portability on debian machines. 64 bit as well as other endian. Can we sign other architectures. - 64 bit requires better knowledge of the format. Perhaps we need to augment the I/O away from structures to a programatic form. - Endianness is broken, but this ought to be a simple thing to fix. - Can prevent corruption and release anyway since ia64 isn't that important, and the endian fix isn't necessary, either. - Rewrite the readme to explain the scripts and how to perform setup. - Output when we are signing and we find a file already signed doesn't appear to match the switches. IOW, we see the skip message - **** Release to Debian when above issues are resolved. - Check on performance. Make sure that signature speed is really limited by gnupg. - Check on replacement of gpg with libgcrypt. bsign-0.4.5/aclocal.m40100660000175000017500000000017106631357462012572 0ustar elfelf dnl Our local extensions to standard type and constant search AC_DEFUN(AC_TYPE_UMODE_T, [AC_CHECK_TYPE(umode_t, int)]) bsign-0.4.5/bsign.10100660000175000017500000001445607421442277012126 0ustar elfelf.TH bsign 1 16-Jan-2001 Debian .SH NAME bsign \- embed and verify secure hashes and digital signatures .SH SYNOPSIS \fBbsign\fR [ \fIoptions\fR | \fIFILENAMES\fR ] .SH DESCRIPTION The goal purpose of \fBbsign\fR is to verify and authenticate data files, especially executables and other binaries. The program reads all of the \fIoptions\fR and \FIFILENAMES\fR from the command line and then begins to operate on the input files. In one invocation in can only one of either hash files, sign files, check hashes, or check signatures. At present, it only works with the ELF (Execution and Link Format) files used by several flavors of UN*X including GNU/Linux, and it only supports gpg for creating and verifying signatures. It embeds a secure hash of the file contents in the file and optionally signs this hash value. Any change in the file contents will be easily discovered. Either the hash value does not match the file contents, the hash is absent, the signature (optional) of the hash value is invalid, ir the signature (optional) is absent. .SH COMMANDS One of these commands must be present. Only the last one on the command line will be recognized. .TP \-c, \-\-checkhash Verify the embedded hash value. .TP \-H, \-\-hash Rewrite the input files with a hash. .TP \-s, \-\-sign Rewrite the input files with signed hash data. Note that the while rewriting process will fail if generation of the digital signature fails. If no supported facility for creating signatures is available, only the \-\-hash method will work. .TP \-V, \-\-verify Verify the embedded hash value and digital signature. .TP \-\-version Display program version. .TP \-h, \-\-help Display program options and usage information. .SH OPTIONS .TP \-d, \-\-debug Enable the display of debug messages. .TP \-e, \-\-exclude \fIPATH\fR Add \fIPATH\fR to the list of directories to exclude for input files, it may be used more than once. A trailing path separator ('/') will be ignored. .TP \-f, \-\-files \fIFILE\fR Process filenames in \fIFILE\fR, one per line. Use filename \- for standard input. This options has the same effect as putting each line in FILE on the command line as a distinct word. .TP \-\-force\-resign By default, \fBbsign\fR will not resign a file if there is already a signature section present. Note that this means it won't resign a file that has been hashed without a signature, too. This option will override that behavior, replacing the existing signature block. .TP \-G, \-\-ignore\-good\-sigs Inhibit information messages about finding good signatures. This option is helpful when verifying from a cron script where all files are expected to have good signatures. Messages about missing or broken signatures are unaffected by \-\-ignore-good-sigs. .TP \-i, \-\-include \fIPATH\fR Add \fIPATH\fR to the list of directories to search for input files, it may be used more than once. This method will tend to be faster and simpler than using the \fBfind\fR program to generate a list of filenames. .TP \-I, \-\-ignore\-unsupported Ignore directories and non-ELF files in error messages. This option reduces bsign output. .TP \-\-nosymlinks Treat symlinks as an unsupported file type. This prevents some files from being signed redundantly. .TP \-o, \-\-output \fIFILE\fR Write signed, rewritten version of the input file to \fIFILE\fR. Without this option, the input file is replaced by the rewritten version. The --output option only works when there is a single input filename on the command line. .TP \-P, \-\-pgoptions \fIOPTS\fR Pass \fIOPTS\fR to gpg as command lines options. This is helpful for telling gpg where to find keys. .TP \-q, \-\-quiet Inhibit informational messages. With this option, the result of executing \fBbsign\fR is known only by checking the return status. .TP \-S, \-\-summary Print a summary after processing the last input file. At the moment, it only tracks the total number of input files reviewed. .TP \-v, \-\-verbose Report details about program progress. .SH RETURN VALUE The program return value reflects the result from the last file processed. Therefore, it is most useful when processing a single file. It returns zero when successfully signing or hashing a file, or when the signature or hash is found to be present and valid. Return codes less than 64 are errno values. .IP 0 no error .br 1 permission denied .br 2 file not found .br 12 no memory .br 21 is directory .br 22 invalid argument .br 24 too many open files .br 26 file busy .br 28 no space on device .br 36 name too long .br 64 no hash found .br 65 no signature found .br 66 bad hash found .br 67 bad signature found .br 68 unsupported file type .br 69 bad pass phrase .br 70 rewrite failed .SH USAGE you intend to use bsign only to protect the contents of the filesystem against corruption, there is little that must be done aside from hashing the files and performing periodic checks for correct hash values. Refer to the \fBEXAMPLES\fR section for some possible invocations. If you intend to use bsign to detect intrusion, the way is less clear. First, the usual reminder: the security of a system is only as strong as the weakest link. More detailed instructions on how to use \fBbsign\fR in this mode may be found in the \fB/usr/share/doc/bsign/README\fR file. .SH EXAMPLES .TP bsign --hash \fBfile\fR rewrite \fBfile\fR with a hash .TP bsign --check-hash \fBfile\fR verify the hash in \fBfile\fR .TP bsign --sign \fBfile\fR -P "--homedir \fBkeydir\fR" rewrite \fBfile\fR with a hash and sign it with the default secret key in \fBkeydir\fR .TP bsign --verify \fBfile\fR -P "--homedir \fBkeydir\fR" verify the hash and signature in \fBfile\fR using the key in \fBkeydir\fR .TP bsign --sign -i / -e /proc -I -s --P "--homedir \fBkeydir\fR" sign the unsigned files in the whole filesystem .TP bsign --verify -i / -e /proc -I -G --P "--homedir \fBkeydir\fR" verify signatures for all files in the filesystem and only report those that have been tampered or are unsigned. .SH ENVIRONMENT VARIABLES .B bsign should use environment variables to select the method for generating digital signatures. It doesn't. .SH BUGS It supports only one hash algorithm, an insignificant bug if one at all. It supports only GNU Privacy Guard for creating and verifying digital signatures. It can embed only in ELF format files, others would be helpful. .SH AUTHOR Marc Singer bsign-0.4.5/bsign.cxx0100660000175000017500000007116507714272611012566 0ustar elfelf/* bsign.cxx $Id: bsign.cxx,v 1.26 2003/08/06 21:39:21 elf Exp $ written by Marc Singer 1 December 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998,2003 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- Routines to check the signature and hash for a file. Note that we must do some shenanigans to checksum a binary file and put that checksum in the file. Text files are easier since we don't have a header to change. See NOTES for more information about this. */ #include "standard.h" #include #include #include #include "version.h" extern "C" { #include "sha1.h" } #include "conversion.h" #include "bsign.h" #include "ds.h" typedef enum { ELF_BITCLASS_NUL = 0, ELF_BITCLASS_32 = 1, ELF_BITCLASS_64 = 2, } E_ELF_BITCLASS; typedef enum { ELF_BYTEORDER_NUL = 0, ELF_BYTEORDER_LSB = 1, ELF_BYTEORDER_MSB = 2, } E_ELF_BYTEORDER; typedef enum { ELF_FILETYPE_MASK = 0xff, ELF_FILETYPE_NUL = 0, ELF_FILETYPE_RELOCATABLE = 1, ELF_FILETYPE_EXECUTABLE = 2, ELF_FILETYPE_SHAREDOBJECT = 3, ELF_FILETYPE_CORE = 4, } E_ELF_FILETYPE; typedef enum { ELF_CPU_MASK = 0xff, ELF_CPU_NUL = 0, ELF_CPU_WE32K = 1, // AT&T WE32100 (MSB) ELF_CPU_SPARC = 2, // SPARC (MSB) ELF_CPU_I386 = 3, // Intel 80386 (LSB) ELF_CPU_M68K = 4, // Motorola 68x000 (MSB) ELF_CPU_M88K = 5, // Motorola 88000 (LSB) ELF_CPU_I486 = 6, // Intel 80486 (LSB) ELF_CPU_I860 = 7, // Intel 80860 (LSB) ELF_CPU_R3000 = 8, // MIPS RS3000 (MSB) ELF_CPU_AMDAHL = 9, // Amdahl (LSB) ELF_CPU_R4000 = 10, // MIPS RS4000 (MSB) ELF_CPU_SPARC64 = 11, // SPARC v9 (64 bit) ELF_CPU_HPPA = 15, // HP PA RISC ELF_CPU_SPARC32P = 18, // SPARC v8 plus (32 bit) ELF_CPU_PPC = 20, // IBM PowerPC ELF_CPU_IA64 = 50, // Intel Itanium (ia64) ELF_CPU_PPC_CYG = 0x9025, // IBM PowerPC by Cygnus Support } E_ELF_CPU; typedef enum { ELF_SECTION_NUL = 0, ELF_SECTION_PROGBITS = 1, // Program specific (private) ELF_SECTION_SYMBOLS = 2, // Symbol table ELF_SECTION_STRINGS = 3, // String table ELF_SECTION_RELOC_A = 4, // Relocation entries with addends ELF_SECTION_HASH = 5, // Hash table for symbols ELF_SECTION_DYNAMIC = 6, // Dynamic linking information ELF_SECTION_NOTE = 7, ELF_SECTION_NOBITS = 8, // Empty section ELF_SECTION_RELOC = 9, // Relocation entries, no addends ELF_SECTION_SHLIB = 10, // ELF_SECTION_SYMBOLS_D = 11, // Dynamic linking symbols ELF_SECTION_SIGNATURE = ((0x80 << 24)|('s' << 16)|('i' << 8)|'g'), } E_ELF_SECTION; typedef enum { ELF_SECTION_F_WRITABLE = 0x0001, ELF_SECTION_F_ALLOCATE = 0x0002, ELF_SECTION_F_EXECUTABLE = 0x0004, } E_ELF_SECTION_F; typedef enum { ELF_PROGRAM_NULL = 0, ELF_PROGRAM_LOAD = 1, // Loadable segment ELF_PROGRAM_DYNAMIC = 2, // Dynamic linking information ELF_PROGRAM_INTERP = 3, // Program interpreter information ELF_PROGRAM_NOTE = 4, // Auxiliary information ELF_PROGRAM_SHLIB = 5, // Unspecified semantics (v1.1) ELF_PROGRAM_PHDR = 6, // Program header table, if loaded } E_ELF_PROGRAM; typedef unsigned32 elf32; typedef unsigned64 elf64; typedef struct { char rgbID[4]; // ID for ELF file "\177ELF" unsigned8 bitclass; // 1, 32 bit; 2, 64 bit unsigned8 byteorder; // 1, LSB; 2, MSB char rgbMagic[10]; // Part of the magic number unsigned16 filetype; // 1, reloc; 2, exec; 3, shared; 4, core unsigned16 cpu; unsigned32 version; elf32 addrEntry; // Virtual address entry point elf32 ibHdrProgram; // Offset to program header elf32 ibHdrSection; // Offset to section header unsigned32 flags; // CPU specific flags unsigned16 cbHeader; // Size of header unsigned16 cbEntryProgram; // Length of each program header entry unsigned16 cEntryProgram; // Count of program header entries unsigned16 cbEntrySection; // Length of each section header entry unsigned16 cEntrySection; // Count of section header entries unsigned16 iSectionNames; // Section with section names } HDR_ELF32; typedef struct { char rgbID[4]; // ID for ELF file "\177ELF" unsigned8 bitclass; // 1, 32 bit; 2, 64 bit unsigned8 byteorder; // 1, LSB; 2, MSB char rgbMagic[10]; // Part of the magic number unsigned16 filetype; // 1, reloc; 2, exec; 3, shared; 4, core unsigned16 cpu; unsigned32 version; elf64 addrEntry; // Virtual address entry point elf64 ibHdrProgram; // Offset to program header elf64 ibHdrSection; // Offset to section header unsigned32 flags; // CPU specific flags unsigned16 cbHeader; // Size of header unsigned16 cbEntryProgram; // Length of each program header entry unsigned16 cEntryProgram; // Count of program header entries unsigned16 cbEntrySection; // Length of each section header entry unsigned16 cEntrySection; // Count of section header entries unsigned16 iSectionNames; // Section with section names } HDR_ELF64; typedef struct { unsigned32 programtype; unsigned32 ib; unsigned32 addrVirtual; unsigned32 addrPhysical; unsigned32 cbFile; unsigned32 cbMemory; unsigned32 flags; unsigned32 alignment; } PROGRAM_ELF32; typedef struct { unsigned32 ibName; // Index to name of section unsigned32 sectiontype; unsigned32 flags; unsigned32 addr; // Virtual address during execution unsigned32 ib; // Offset to section data unsigned32 cb; // Length of section data unsigned32 iLink; // Index of another section (link?) unsigned32 info; unsigned32 alignment; unsigned32 cbEntry; // Section table entry size, if applicable } SECTION_ELF32; typedef struct { unsigned32 ibName; // Index of symbol name unsigned32 value; // Symbol value unsigned32 cb; // Size of symbol unsigned8 info; // Symbol binding info unsigned8 other; // unsigned16 iSection; // Section associated with symbol } SYMBOL_ELF32; // -- FIXUP -- description of change to a file region typedef struct _FIXUP { struct _FIXUP* pNext; // Link to next fixup unsigned32 ib; // Original location unsigned32 cb; // Original size unsigned32 ibNew; // New location unsigned32 cbNew; // New size void* pv; // Pointer to the new data for this range const char* szDescription; // Debug diagnostic } FIXUP32; const char g_szSectionSig[] = "signature"; // Perhaps not the best // name, but it is descriptive #define CB_SIGNATURE (512) // *** FIXME: hard coded, for now size_t rewrite_elf32 (char* pb, size_t cb, int fh, FIXUP32& fixup); void check_byte_sex (const void* pv) { #if defined (WORDS_BIGENDIAN) g_fOppositeSex = (((HDR_ELF32*)pv)->byteorder != ELF_BYTEORDER_MSB); #else g_fOppositeSex = (((HDR_ELF32*)pv)->byteorder != ELF_BYTEORDER_LSB); #endif } /* sign_file generates a hash with or without a digital signature. The return value is a pointer to the data. In this implementation, the signature block is of a fixed length. If the return value is NULL, the digital signature could not be created. */ char* sign_file (char* pb, size_t cb, size_t ibSignature, size_t cbSignature, bool fCreateCert) { void* pv = malloc (cbSignature); memset (pv, 0, cbSignature); size_t cbContext; void (*pfn_init)(void*); void (*pfn_write)(void*, byte*, size_t); void (*pfn_final)(void*); byte* (*pfn_read)(void*); byte* r_asnoid; // ? int r_asnlen; // ? int r_mdlen; // Digest length? sha1_get_info (2, &cbContext, &r_asnoid, &r_asnlen, &r_mdlen, &pfn_init, &pfn_write, &pfn_final, &pfn_read); void* hd = malloc (cbContext); (*pfn_init) (hd); (*pfn_write) (hd, (byte*) pb, ibSignature); (*pfn_write) (hd, (byte*) pv, cbSignature); (*pfn_write) (hd, (byte*) pb + ibSignature + cbSignature, cb - ibSignature - cbSignature); (*pfn_final) (hd); unsigned8* rgb = (*pfn_read) (hd); char* rgbSignature = (char*) malloc (CB_SIGNATURE); memset (rgbSignature, 0, CB_SIGNATURE); char* pbHash = rgbSignature + sprintf (rgbSignature, "#1; bsign v%s\n", g_szVersion); size_t cbHeader = pbHash - rgbSignature; memcpy (pbHash, rgb, 20); free (hd); // *** generating cert every time if (fCreateCert) { char* rgbCert = create_digital_signature (rgbSignature, cbHeader + 20); if (rgbCert) { size_t cbCert = ((unsigned char*)rgbCert)[0]*256 + ((unsigned char*)rgbCert)[1] + 2; memcpy (pbHash + 20, rgbCert, cbCert); free (rgbCert); } else { delete rgbSignature; return NULL; } } return rgbSignature; } int size_elf_header (void) { return sizeof (HDR_ELF64); // Largest header size } /* is_elf returns whether or not we believe we will be successful in rewriting the file. This may require a somewhat indepth examination of the elf headers to make sure that all appears well. Remember that we expect to find corrupt executables and these may be corrupted in subtle ways. The key, though, is our success is rewriting the file. It is also important to recognize that an file with a superficial appearance of being elf that has deeper problems is the goal of this project. Either those problems are simple changes to the contents of the file, or the malicious surgery of a hacker. We find it all. */ bool is_elf (char* pb, size_t cb) { if (cb < sizeof (HDR_ELF32)) return false; check_byte_sex (pb); HDR_ELF32& header = *(HDR_ELF32*) pb; if (memcmp (header.rgbID, "\177ELF", 4) != 0 || header.bitclass < 1 || header.bitclass > 2 || header.byteorder < 1 || header.byteorder > 2 || _v (header.filetype) < 1 || _v (header.filetype) > 4 || ( _v (header.ibHdrProgram) && _v (header.ibHdrProgram) < sizeof (header)) || _v (header.ibHdrProgram) >= cb || _v (header.ibHdrSection) < sizeof (header) || _v (header.ibHdrSection) >= cb || _v (header.cbHeader) != sizeof (header) || ( _v (header.cbEntryProgram) && _v (header.cbEntryProgram) != sizeof (PROGRAM_ELF32)) || _v (header.cbEntrySection) != sizeof (SECTION_ELF32) || _v (header.iSectionNames) >= _v (header.cEntrySection)) return false; // *** FIXME: I don't recall why we need more than a header test. const PROGRAM_ELF32* rgProgram = (PROGRAM_ELF32*) (pb + _v (header.ibHdrProgram)); for (int i = 0; i < _v (header.cEntryProgram); ++i) if ( _v (rgProgram[i].ib) >= cb || _v (rgProgram[i].ib) + _v (rgProgram[i].cbFile) > cb) return false; const SECTION_ELF32* rgSection = (SECTION_ELF32*) (pb + _v (header.ibHdrSection)); for (int i = 1; i < _v (header.cEntrySection); ++i) if (_v (rgSection[i].sectiontype) != ELF_SECTION_NOBITS && (_v (rgSection[i].ib) >= cb || _v (rgSection[i].ib) + _v (rgSection[i].cb) > cb)) return false; return true; } /* is_elf */ bool is_elf_header (const char* pb, size_t cb) { if (cb < sizeof (HDR_ELF32)) return false; check_byte_sex (pb); HDR_ELF32& header = *(HDR_ELF32*) pb; if (memcmp (header.rgbID, "\177ELF", 4) != 0 || header.bitclass < 1 || header.bitclass > 2 || header.byteorder < 1 || header.byteorder > 2 || _v (header.filetype) < 1 || _v (header.filetype) > 4 || ( _v (header.ibHdrProgram) && _v (header.ibHdrProgram) < sizeof (header)) || _v (header.ibHdrSection) < sizeof (header) || _v (header.cbHeader) != sizeof (header) || ( _v (header.cbEntryProgram) && _v (header.cbEntryProgram) != sizeof (PROGRAM_ELF32)) || _v (header.cbEntrySection) != sizeof (SECTION_ELF32) || _v (header.iSectionNames) >= _v (header.cEntrySection)) return false; return true; } /* is_elf_signed returns true if this file is an elf file and if it is signed. The pibSignature and pcbSignature parameters are set with the position and length of the signature block if there is a signature. Note that another call must be made to compute the hash of the file and verify the signature. This function does not distinguish between non-elf files and unsigned elf files. */ bool is_elf_signed (char* pb, size_t cb, size_t* pibSignature, size_t* pcbSignature) { if (!is_elf (pb, cb)) return false; const HDR_ELF32& hdr = *(HDR_ELF32*) pb; const SECTION_ELF32* rgSection = (SECTION_ELF32*) (pb + _v (hdr.ibHdrSection)); for (int i = 0; i < _v (hdr.cEntrySection); ++i) { if (_v (rgSection[i].sectiontype) == unsigned32 (ELF_SECTION_SIGNATURE)) { if (pibSignature) *pibSignature = _v (rgSection[i].ib); if (pcbSignature) *pcbSignature = _v (rgSection[i].cb); return true; } } return false; } /* check_elf returns an eAppResult code indicating the success of the hash/signature verification. */ eExitStatus check_elf (char* pb, size_t cb, bool fExpectSignature) { if (!is_elf (pb, cb)) return unsupportedfiletype; size_t ibSignature; size_t cbSignature; if (!is_elf_signed (pb, cb, &ibSignature, &cbSignature)) return fExpectSignature ? nosignature : nohash; size_t ibHash = ibSignature; for (ibHash = ibSignature; ibHash < ibSignature + cbSignature - 20; ++ibHash) if (pb[ibHash] == '\n') { ++ibHash; break; } if (fExpectSignature && ibHash == ibSignature + cbSignature - 20) return nosignature; char* rgbSignature = sign_file (pb, cb, ibSignature, cbSignature, false); char* pbSignature; for (pbSignature = rgbSignature; pbSignature < rgbSignature + CB_SIGNATURE; ++pbSignature) if (*pbSignature == '\n') { ++pbSignature; break; } eExitStatus result = ((memcmp (pbSignature, pb + ibHash, 20) != 0) ? badhash : noerror); free (rgbSignature); if (result || !fExpectSignature) return result; // Check digital signature if hash OK size_t cbCert = (((unsigned char*)pb)[ibHash + 20] << 8) | ((unsigned char*)pb)[ibHash + 21]; if (cbCert == 0 || cbCert > cbSignature - (ibHash - ibSignature + 20)) return badsignature; return verify_digital_signature (pb + ibSignature, ibHash - ibSignature + 20, pb + ibHash + 22, cbCert); } /* hash_elf generates a signature section for a ELF file. The algorithm rewrites the file, removing the old signature if there was one, hashes this portion, and appends the new signature to the end. This depends only on us knowning the length of the cert. In theory, we could put our signature section anywhere in the file, but this layout is convenient at the time. The most likely enhancement from here would be the ability to update a signature in place, making this function more efficient, and making the hashing a little more difficult. *** FIXME: the return value is an error code. We need to establish a set of these so we can determine the cause of failures. We don't want to appears foolish like Microsoft. */ eExitStatus hash_elf (char* pb, size_t cb, int fhNew, bool fSign) { check_byte_sex (pb); FIXUP32 fixupSignature; memset (&fixupSignature, 0, sizeof (fixupSignature)); fixupSignature.cb = CB_SIGNATURE; // Perform rewrite size_t cbRewrite = rewrite_elf32 (pb, cb, fhNew, fixupSignature); if (cbRewrite == (size_t) -1) return rewritefailed; char* pbMap = (char*) mmap (NULL, cbRewrite, PROT_READ, MAP_FILE | MAP_PRIVATE, fhNew, 0); assert (pbMap); char* rgbSignature = sign_file (pbMap, cbRewrite, fixupSignature.ibNew, fixupSignature.cbNew, fSign); munmap (pbMap, cbRewrite); if (rgbSignature) { lseek (fhNew, fixupSignature.ibNew, SEEK_SET); write (fhNew, rgbSignature, CB_SIGNATURE); delete rgbSignature; return noerror; } return badpassphrase; } /* new_sectionnames returns a buffer containing sections names with the name of the signature buffer added to the end. The first parameter is a pointer to the file in memory. */ char* new_sectionnames32 (char* pb, size_t cb, SECTION_ELF32& sectionNames, SECTION_ELF32& sectionSig) { const HDR_ELF32& hdr = *(HDR_ELF32*) pb; sectionSig.ibName = sectionNames.cb; sectionSig.alignment = _v (unsigned32 (1)); sectionSig.sectiontype = _v (unsigned32 (ELF_SECTION_SIGNATURE)); unsigned32 cbSectionNamesNew = _v (sectionNames.cb) + sizeof (g_szSectionSig); cbSectionNamesNew = (cbSectionNamesNew + 3) & ~3; // Round to words char* sz = (char*) malloc (cbSectionNamesNew); memcpy (sz, pb + _v (sectionNames.ib), _v (sectionNames.cb)); memcpy (sz + _v (sectionNames.cb), g_szSectionSig, sizeof (g_szSectionSig)); sectionNames.cb = _v (cbSectionNamesNew); return sz; } void fixup_range32 (const unsigned32& ibOld, const unsigned32& cbOld, unsigned32& ib, unsigned32& cb, const FIXUP32& fixup) { // Fixup occurs after this range if (fixup.ib >= _v (ibOld) + _v (cbOld)) return; // Fixup preceeds this range if (_v (ibOld) >= fixup.ib + fixup.cb) { ib += fixup.cbNew - fixup.cb; return; } // *** FIXME: weak sanity check assert (fixup.ib >= _v (ibOld)); // elf: in fact, this next check is so // weak it is wrong. In rereading // this line, I cannot tell WHAT I was // thinking. // assert (fixup.ib + fixup.cb <= _v (ibOld) + _v (cbOld)); // Fixup within this program cb += fixup.cbNew - fixup.cb; } /* fixup_fixups fills the ibNew fields so we can write the output file conveniently. The *best* algorithm would sort the list before computing the ibNew fields. Instead, we implement an O(n^2) routine that checks every fixup with every other fixup. With anything less than a dozen, this is certainly OK. We make the reasonable assumption that the fixups don't overlap. The return value is the number of bytes added to the file due to these fixups. */ unsigned32 fixup_fixups32 (FIXUP32* pFixupHead) { unsigned32 cb = 0; for (FIXUP32* pFixupOuter = pFixupHead; pFixupOuter; pFixupOuter = pFixupOuter->pNext) { pFixupOuter->ibNew = pFixupOuter->ib; cb += pFixupOuter->cbNew - pFixupOuter->cb; for (FIXUP32* pFixupInner = pFixupHead; pFixupInner; pFixupInner = pFixupInner->pNext) if (pFixupInner->ib < pFixupOuter->ib) pFixupOuter->ibNew += pFixupInner->cbNew - pFixupInner->cb; } return cb; } void fixup_elf32_programs (const HDR_ELF32& hdr, PROGRAM_ELF32* rgProgram, const PROGRAM_ELF32* rgProgramOld, const FIXUP32* rgFixup) { for (int iProgram = 0; iProgram < _v (hdr.cEntryProgram); ++iProgram) for (const FIXUP32* pFixup = rgFixup; pFixup; pFixup = pFixup->pNext) fixup_range32 (rgProgramOld[iProgram].ib, rgProgramOld[iProgram].cbFile, rgProgram[iProgram].ib, rgProgram[iProgram].cbFile, *pFixup); } void fixup_elf32_sections (const HDR_ELF32& hdr, SECTION_ELF32* rgSection, const SECTION_ELF32* rgSectionOld, const FIXUP32* rgFixup) { for (int iSection = 0; iSection < _v (hdr.cEntrySection); ++iSection) for (const FIXUP32* pFixup = rgFixup; pFixup; pFixup = pFixup->pNext) fixup_range32 (rgSectionOld[iSection].ib, rgSectionOld[iSection].cb, rgSection[iSection].ib, rgSection[iSection].cb, *pFixup); } void fixup_elf32_header (HDR_ELF32& hdr, const HDR_ELF32& hdrOld, const FIXUP32* rgFixup) { for (const FIXUP32* pFixup = rgFixup; pFixup; pFixup = pFixup->pNext) { unsigned32 cbOld; unsigned32 cb; if (_v (hdrOld.cEntryProgram)) { cbOld = _v (unsigned32 (_v (hdrOld.cbEntryProgram) *_v (hdrOld.cEntryProgram))); cb = _v (unsigned32 (_v (hdr.cbEntryProgram)*_v (hdr.cEntryProgram))); fixup_range32 (hdrOld.ibHdrProgram, cbOld, hdr.ibHdrProgram, cb, *pFixup); } cbOld = _v (unsigned32 (_v (hdrOld.cbEntrySection) *_v (hdrOld.cEntrySection))); cb = _v (unsigned32 (_v (hdr.cbEntrySection)*_v (hdr.cEntrySection))); fixup_range32 (hdrOld.ibHdrSection, cbOld, hdr.ibHdrSection, cb, *pFixup); } } void report_elf32 (const HDR_ELF32& hdr, const SECTION_ELF32* rgSection) { fprintf (stderr, "%08x %08x header\n", 0, sizeof (hdr)); fprintf (stderr, "%08x %08x program header\n", _v (hdr.ibHdrProgram), _v (hdr.cbEntryProgram)*_v (hdr.cEntryProgram)); fprintf (stderr, "%08x %08x section header\n", _v (hdr.ibHdrSection), _v (hdr.cbEntrySection)*_v (hdr.cEntrySection)); for (int i = 0; i < _v (hdr.cEntrySection); ++i) { fprintf (stderr, "%08x %08x section %d\n", _v (rgSection[i].ib), _v (rgSection[i].cb), i); } } void report_fixup (const FIXUP32* pFixup) { fprintf (stderr, "%8d l%8d->%8d %8d l%8d->%8d %s\n", pFixup->ib, pFixup->cb, pFixup->ib + pFixup->cb, pFixup->ibNew, pFixup->cbNew, pFixup->ibNew + pFixup->cbNew, pFixup->szDescription); } void report_fixups (const FIXUP32* pFixup) { for (; pFixup; pFixup = pFixup->pNext) report_fixup (pFixup); } /* rewrite_elf rewrites an elf file making the appropriate changes to support a signature section. The fixupSignature section must contain a cb value large enough to contain the signature data. The fixupSignature ibNew and cbNew will point to the place in the new file where the signature is written. If the file already has a signature section and if that section is at least as large as requested, the file will be copied. The portion of the file to hold the signature is *always* initialized to nulls. Note, we count on the first fixup being the new signature space when we do the complex rewrite. This is done to make it easy to free the blank buffer and to recover the new signature location. We return -1 when there's an error during rewrite. */ size_t rewrite_elf32 (char* pb, size_t cb, int fh, FIXUP32& fixupSignature) { const HDR_ELF32 hdrOld = *(HDR_ELF32*) pb; if (sizeof (hdrOld) != _v (hdrOld.cbHeader)) // We must have this return 0; if (_v (hdrOld.cEntryProgram) && sizeof (PROGRAM_ELF32) != _v (hdrOld.cbEntryProgram)) // We must have this return 0; if (_v (hdrOld.cEntrySection) && sizeof (SECTION_ELF32) != _v (hdrOld.cbEntrySection)) // We must have this return 0; const SECTION_ELF32* rgSectionOld = (SECTION_ELF32*) (pb + _v (hdrOld.ibHdrSection)); FIXUP32 fixupOldSignature; int iSectionOldSignature = 0; memset (&fixupOldSignature, 0, sizeof (fixupOldSignature)); // Check to see if the file has a // sufficiently large signature section for (int i = 0; i < _v (hdrOld.cEntrySection); ++i) { if (_v (rgSectionOld[i].sectiontype) == unsigned32 (ELF_SECTION_SIGNATURE)) { fixupOldSignature.ib = _v (rgSectionOld[i].ib); fixupOldSignature.cb = _v (rgSectionOld[i].cb); iSectionOldSignature = i; break; } } // Data block for initializing signature fixupOldSignature.ibNew = fixupOldSignature.ib; // Old signature sufficient, easiest solution if (fixupOldSignature.cb >= fixupSignature.cb) { void* pv = malloc (fixupOldSignature.cb); memset (pv, 0, fixupOldSignature.cb); write (fh, pb, fixupOldSignature.ib); write (fh, pv, fixupOldSignature.cb); write (fh, pb + fixupOldSignature.ib + fixupOldSignature.cb, cb - fixupOldSignature.ib - fixupOldSignature.cb); free (pv); fixupSignature = fixupOldSignature; fixupSignature.cbNew = fixupOldSignature.cb; return cb; } // Make new program and section headers HDR_ELF32 hdr = *(HDR_ELF32*) pb; const PROGRAM_ELF32* rgProgramOld = (PROGRAM_ELF32*) (pb + _v (hdr.ibHdrProgram)); PROGRAM_ELF32* rgProgram = hdr.ibHdrProgram ? new PROGRAM_ELF32[_v (hdr.ibHdrProgram)] : NULL; if (rgProgram) memcpy (rgProgram, rgProgramOld, _v (hdr.cEntryProgram)*_v (hdr.cbEntryProgram)); SECTION_ELF32* rgSection = new SECTION_ELF32[_v (hdr.cEntrySection) + (iSectionOldSignature ? 0 : 1)]; memcpy (rgSection, rgSectionOld, _v (hdr.cEntrySection)*_v (hdr.cbEntrySection)); // report_elf (hdr, rgSectionOld); SECTION_ELF32& sectionSig = rgSection[_v (hdr.cEntrySection)]; SECTION_ELF32& sectionNames = rgSection[iSectionOldSignature ? iSectionOldSignature : _v (hdr.iSectionNames)]; memset (§ionSig, 0, sizeof (sectionSig)); char* rgbSectionNames = new_sectionnames32 (pb, cb, sectionNames, sectionSig); if (!iSectionOldSignature) hdr.cEntrySection = _v (_v (hdr.cEntrySection) + (unsigned32) 1); // Generate fixup lists FIXUP32* pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->ib = _v (rgSectionOld[_v (hdr.iSectionNames)].ib); pFixup->cb = _v (rgSectionOld[_v (hdr.iSectionNames)].cb); pFixup->cbNew = _v (rgSection[_v (hdr.iSectionNames)].cb); pFixup->pv = rgbSectionNames; pFixup->szDescription = "section names"; FIXUP32* pFixupHead = pFixup; pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = _v (hdrOld.ibHdrSection); pFixup->cb = _v (hdrOld.cEntrySection)*_v (hdrOld.cbEntrySection); pFixup->cbNew = _v (hdr.cEntrySection)*_v (hdr.cbEntrySection); pFixup->pv = rgSection; pFixup->szDescription = "entry section"; if (_v (hdrOld.cEntryProgram)) { pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = _v (hdrOld.ibHdrProgram); pFixup->cb = _v (hdrOld.cEntryProgram)*_v (hdrOld.cbEntryProgram); pFixup->cbNew = _v (hdr.cEntryProgram)*_v (hdr.cbEntryProgram); pFixup->pv = rgProgram; pFixup->szDescription = "entry program"; } pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = 0; pFixup->cb = sizeof (hdr); pFixup->cbNew = sizeof (hdr); pFixup->pv = &hdr; pFixup->szDescription = "header"; // Clobber old signature if (fixupOldSignature.cb) { pFixup = new FIXUP32; memcpy (pFixup, &fixupOldSignature, sizeof (FIXUP32)); pFixup->szDescription = "old signature"; pFixup->pNext = pFixupHead; pFixupHead = pFixup; } // Make room for new signature pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = cb; pFixup->cb = 0; pFixup->cbNew = fixupSignature.cb; pFixup->pv = malloc (pFixup->cbNew); pFixup->szDescription = "signature"; memset (pFixup->pv, 0, pFixup->cbNew); // printf ("@perform fixups\n"); report_fixups (pFixupHead); // Perform fixups unsigned32 cbNew = fixup_fixups32 (pFixupHead) + cb; fixup_elf32_header (hdr, hdrOld, pFixupHead); if (_v (hdr.cEntryProgram)) fixup_elf32_programs (hdrOld, rgProgram, rgProgramOld, pFixupHead); fixup_elf32_sections (hdrOld, rgSection, rgSectionOld, pFixupHead); // report_fixups (pFixupHead); sectionSig.ib = pFixupHead->ibNew; sectionSig.cb = pFixupHead->cbNew; // printf ("@rewrite\n"); report_fixups (pFixupHead); // Rewrite size_t cbWritten = 0; unsigned32 ib = 0; unsigned32 ibFile = 0; while (ib < cbNew) { FIXUP32* pFixupNext = NULL; for (pFixup = pFixupHead; pFixup; pFixup = pFixup->pNext) if (pFixup->ibNew >= ib && (pFixupNext == NULL || pFixup->ibNew < pFixupNext->ibNew)) pFixupNext = pFixup; unsigned32 cbWrite; if (pFixupNext && pFixupNext->ibNew == ib) { // report_fixup (pFixupNext); cbWrite = write (fh, pFixupNext->pv, pFixupNext->cbNew); if (cbWrite != pFixupNext->cbNew) { cbWritten = (size_t) -1; break; } ibFile += pFixupNext->cb; } else { size_t cb = (pFixupNext ? pFixupNext->ibNew : cbNew) - ib; // printf ("%8ld l%8d->%8ld from file\n", ibFile, cb, ib + cb); cbWrite = write (fh, pb + ibFile, cb); if (cbWrite != cb) { cbWritten = (size_t) -1; break; } ibFile += cb; } cbWritten += cbWrite; ib += cbWrite; } // Cleanup free (rgbSectionNames); // *** FIXME: release fixups and sections and program fixupSignature = *pFixupHead; fixupSignature.pv = 0; assert (pFixupHead && pFixupHead->pv); free (pFixupHead->pv); while (pFixupHead) { pFixup = pFixupHead; pFixupHead = pFixup->pNext; delete pFixup; } return cbWritten; } bsign-0.4.5/bsign.h0100660000175000017500000000274107421400213012167 0ustar elfelf/* bsign.h -*- C++ -*- $Id: bsign.h,v 1.8 2002/01/16 22:36:59 elf Exp $ written by Oscar Levi 1 Dec 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- */ #if !defined (__BSIGN_H__) # define __BSIGN_H__ /* ----- Includes */ #include "exitstatus.h" /* ----- Globals */ bool is_elf (char* pb, size_t cb); bool is_elf_header (const char* pb, size_t cb); bool is_elf_signed (char* pb, size_t cb, size_t* pibSignature, size_t* pcbSignature); eExitStatus hash_elf (char* pb, size_t cb, int fhNew, bool fSign); eExitStatus check_elf (char* pb, size_t cb, bool fExpectSignature); int size_elf_header (void); #endif /* __BSIGN_H__ */ bsign-0.4.5/bsign_check0100660000175000017500000000136607425063700013112 0ustar elfelf#!/bin/sh # $Id: bsign_check,v 1.1 2002/01/27 20:49:04 elf Exp $ # # Verify hashes. Send results by email. # # --- Start of customization macros # LOCATIONS gives the path includes and excludes that guide where # bsign looks for input files. LOCATIONS=-i / -e /boot -e /cdrom -e /dev -e /proc -e $BASE_PATH # MAIL_TO is the list of email addresses that will receive email when # this script terminates. The mail will contain the output of # bsign. MAIL_TO=root # MAIL_PROG is the program to call to send mail MAIL_PROG=mailx # --- End of customization macros # Prevent library loading tricks LD_LIBRARY_PATH= export LD_LIBRARY_PATH # Perform $BASE_PATH/bsign -c -I -G $LOCATIONS \ | $MAIL_PROG -s "`hostname -f` bsign log" $MAIL_TO bsign-0.4.5/bsign_hash0100660000175000017500000000067507425063700012762 0ustar elfelf#!/bin/sh # $Id: bsign_hash,v 1.1 2002/01/27 20:49:04 elf Exp $ # # Add hashes to unhashed executables. # # --- Start of customization macros # LOCATIONS gives the path includes and excludes that guide where # bsign looks for input files. LOCATIONS=-i / -e /boot -e /cdrom -e /dev -e /proc # --- End of customization macros # Prevent library loading tricks LD_LIBRARY_PATH= export LD_LIBRARY_PATH # Perform bsign -H -I -v $LOCATIONS bsign-0.4.5/bsign_sign0100660000175000017500000000161407425045171012773 0ustar elfelf#!/bin/sh # $Id: bsign_sign,v 1.4 2002/01/27 18:44:09 elf Exp $ # # Add hashes and signatures to unsigned executables. # # This script is intented to be put onto a floppy diskette along with # the secret key used to sign the system ELF files. # # --- Start of customization macros # BASE_PATH is the absolute pathname where this script and bsign will # be found. BASE_PATH=/floppy # KEY_PATH is the absolute pathname where the public key will be # found. Note that the default key from the pubring.gpg file will # be used. KEY_PATH=$BASE_PATH # LOCATIONS gives the path includes and excludes that guide where # bsign looks for input files. LOCATIONS=-i / -e /boot -e /cdrom -e /dev -e /proc -e $BASE_PATH # --- End of customization macros # Prevent library loading tricks LD_LIBRARY_PATH= export LD_LIBRARY_PATH # Perform $BASE_PATH/bsign -s -I -v $LOCATIONS -P "--homedir $KEY_PATH" bsign-0.4.5/bsign_verify0100660000175000017500000000234207425045171013336 0ustar elfelf#!/bin/sh # $Id: bsign_verify,v 1.6 2002/01/27 18:44:09 elf Exp $ # # Verify hashes and signatures. Send results by email. # # This script is intented to be put onto a floppy diskette along with # the public key used to sign the system ELF files. # # --- Start of customization macros # BASE_PATH is the absolute pathname where this script and bsign will # be found. BASE_PATH=/floppy # KEY_PATH is the absolute pathname where the public key will be # found. Note that the default key from the pubring.gpg file will # be used. KEY_PATH=$BASE_PATH # LOCATIONS gives the path includes and excludes that guide where # bsign looks for input files. LOCATIONS=-i / -e /boot -e /cdrom -e /dev -e /proc -e $BASE_PATH #LOCATIONS=-i /bin -i /sbin -i /usr/bin -i /usr/sbin # MAIL_TO is the list of email addresses that will receive email when # this script terminates. The mail will contain the output of # bsign. MAIL_TO=root # MAIL_PROG is the program to call to send mail MAIL_PROG=mailx # --- End of customization macros # Prevent library loading tricks LD_LIBRARY_PATH= export LD_LIBRARY_PATH # Perform $BASE_PATH/bsign -V -I -G $LOCATIONS -P "--homedir $KEY_PATH" \ | $MAIL_PROG -s "`hostname -f` bsign log" $MAIL_TO bsign-0.4.5/config.h.in0100660000175000017500000000705307421673574012766 0ustar elfelf/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define to empty if the keyword does not work. */ #undef const /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT /* Define if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define if your struct tm has tm_zone. */ #undef HAVE_TM_ZONE /* Define if you don't have tm_zone but do have the external array tzname. */ #undef HAVE_TZNAME /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF /* Define if you have the vsprintf function. */ #undef HAVE_VSPRINTF /* Define if you have the vsnprintf function. */ #undef HAVE_VSNPRINTF /* Define if you have the rindex function. */ #undef HAVE_RINDEX /* Define if you have the strrchr function. */ #undef HAVE_STRRCHR /* Define as __inline if that's what the C compiler calls it. */ #undef inline /* Define to `long' if doesn't define. */ #undef off_t /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if your declares struct tm. */ #undef TM_IN_SYS_TIME /* Define to empty if the keyword does not work. */ #undef const /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT /* Define if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define if your struct tm has tm_zone. */ #undef HAVE_TM_ZONE /* Define if you don't have tm_zone but do have the external array tzname. */ #undef HAVE_TZNAME /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF /* Define as __inline if that's what the C compiler calls it. */ #undef inline /* Define to `long' if doesn't define. */ #undef off_t /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if your declares struct tm. */ #undef TM_IN_SYS_TIME /* The number of bytes in a int. */ #undef SIZEOF_INT /* The number of bytes in a long. */ #undef SIZEOF_LONG /* The number of bytes in a long long. */ #undef SIZEOF_LONG_LONG /* The native machine is bigendian, 0x12345678 stored 0x12345678 */ #undef WORDS_BIGENDIAN /* Define if you have the bcopy function. */ #undef HAVE_BCOPY /* Define if you have the getpagesize function. */ #undef HAVE_GETPAGESIZE /* Define if you have the memcpy function. */ #undef HAVE_MEMCPY /* Define if you have the strcspn function. */ #undef HAVE_STRCSPN /* Define if you have the strncasecmp function. */ #undef HAVE_STRNCASECMP /* Define if you have the strncpy function. */ #undef HAVE_STRNCPY /* Define if you have the cfmakeraw function. */ #undef HAVE_CFMAKERAW /* Define if you have the valloc function. */ #undef HAVE_VALLOC /* Define if you have the header file. */ #undef HAVE_DIRENT_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_GPM_H /* Define if you have the header file. */ #undef HAVE_NDIR_H /* Define if you have the header file. */ #undef HAVE_SYS_DIR_H /* Define if you have the header file. */ #undef HAVE_SYS_NDIR_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the header file. */ #undef HAVE_MALLOC_H /* Define if you have the header file. */ #undef HAVE_STRING_H /* Define if you have the header file. */ #undef HAVE_STRINGS_H bsign-0.4.5/configure0100770000175000017500000023004407421673574012647 0ustar elfelf#! /bin/sh # From configure.in Id: configure.in,v 1.4 2002/01/18 01:06:46 elf Exp # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=bsign.cxx # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:542: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:572: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:623: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:655: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 666 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:697: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:702: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:730: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:766: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CXX="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi CXX="$ac_cv_prog_CXX" if test -n "$CXX"; then echo "$ac_t""$CXX" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$CXX" && break done test -n "$CXX" || CXX="gcc" echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:798: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext << EOF #line 809 "configure" #include "confdefs.h" int main(){return(0);} EOF if { (eval echo configure:814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cxx_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cxx_cross=no else ac_cv_prog_cxx_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cxx_works=no fi rm -fr conftest* ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 if test $ac_cv_prog_cxx_works = no; then { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:840: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 cross_compiling=$ac_cv_prog_cxx_cross echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 echo "configure:845: checking whether we are using GNU C++" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gxx=yes else ac_cv_prog_gxx=no fi fi echo "$ac_t""$ac_cv_prog_gxx" 1>&6 if test $ac_cv_prog_gxx = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS="${CXXFLAGS+set}" ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS= echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 echo "configure:873: checking whether ${CXX-g++} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.cc if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then ac_cv_prog_cxx_g=yes else ac_cv_prog_cxx_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS="$ac_save_CXXFLAGS" elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 echo "configure:905: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else rm -f conftestdata if ln -s X conftestdata 2>/dev/null then rm -f conftestdata ac_cv_prog_LN_S="ln -s" else ac_cv_prog_LN_S=ln fi fi LN_S="$ac_cv_prog_LN_S" if test "$ac_cv_prog_LN_S" = "ln -s"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:926: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:983: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' CFLAGS=-g CXXFLAGS=-g if test "${GXX}" = "yes" ; then CFLAGS_W=" -Wall -Wno-parentheses -Wno-unused" CFLAGS="${CFLAGS}" fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 echo "configure:1049: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> int main() { DIR *dirp = 0; ; return 0; } EOF if { (eval echo configure:1062: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 echo "configure:1087: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -ldir" else echo "$ac_t""no" 1>&6 fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 echo "configure:1131: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lx" else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 echo "configure:1176: checking how to run the C++ preprocessor" >&5 if test -z "$CXXCPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross CXXCPP="${CXX-g++} -E" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1194: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CXXCPP=/lib/cpp fi rm -f conftest* ac_cv_prog_CXXCPP="$CXXCPP" ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross fi fi CXXCPP="$ac_cv_prog_CXXCPP" echo "$ac_t""$CXXCPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1219: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1232: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi for ac_func in strncasecmp memcpy bcopy strcspn strncpy cfmakeraw do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1328: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done for ac_func in vsnprintf vsprintf rindex strrchr do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1386: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done for ac_hdr in fcntl.h unistd.h gpm.h malloc.h string.h strings.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1445: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1455: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for off_t""... $ac_c" 1>&6 echo "configure:1483: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_off_t=yes else rm -rf conftest* ac_cv_type_off_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_off_t" 1>&6 if test $ac_cv_type_off_t = no; then cat >> confdefs.h <<\EOF #define off_t long EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:1516: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 echo "configure:1549: checking whether struct tm is in sys/time.h or time.h" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include int main() { struct tm *tp; tp->tm_sec; ; return 0; } EOF if { (eval echo configure:1562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm=time.h else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_struct_tm=sys/time.h fi rm -f conftest* fi echo "$ac_t""$ac_cv_struct_tm" 1>&6 if test $ac_cv_struct_tm = sys/time.h; then cat >> confdefs.h <<\EOF #define TM_IN_SYS_TIME 1 EOF fi echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6 echo "configure:1583: checking for tm_zone in struct tm" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_cv_struct_tm> int main() { struct tm tm; tm.tm_zone; ; return 0; } EOF if { (eval echo configure:1596: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm_zone=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_struct_tm_zone=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_struct_tm_zone" 1>&6 if test "$ac_cv_struct_tm_zone" = yes; then cat >> confdefs.h <<\EOF #define HAVE_TM_ZONE 1 EOF else echo $ac_n "checking for tzname""... $ac_c" 1>&6 echo "configure:1616: checking for tzname" >&5 if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #ifndef tzname /* For SGI. */ extern char *tzname[]; /* RS6000 and others reject char **tzname. */ #endif int main() { atoi(*tzname); ; return 0; } EOF if { (eval echo configure:1631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_var_tzname=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_var_tzname=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_var_tzname" 1>&6 if test $ac_cv_var_tzname = yes; then cat >> confdefs.h <<\EOF #define HAVE_TZNAME 1 EOF fi fi echo $ac_n "checking size of long""... $ac_c" 1>&6 echo "configure:1653: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_long=4 else cat > conftest.$ac_ext < #include main() { FILE *f=fopen("conftestval", "w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(long)); exit(0); } EOF if { (eval echo configure:1676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_sizeof_long=0 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_sizeof_long" 1>&6 cat >> confdefs.h <&6 echo "configure:1695: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_int=4 else cat > conftest.$ac_ext < #include main() { FILE *f=fopen("conftestval", "w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(int)); exit(0); } EOF if { (eval echo configure:1718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_sizeof_int=0 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_sizeof_int" 1>&6 cat >> confdefs.h <&6 echo "configure:1737: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_long_long=8 else cat > conftest.$ac_ext < #include main() { FILE *f=fopen("conftestval", "w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(long long)); exit(0); } EOF if { (eval echo configure:1760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_sizeof_long_long=0 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6 cat >> confdefs.h <&6 echo "configure:1779: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < #include int main() { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } EOF if { (eval echo configure:1797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < #include int main() { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } EOF if { (eval echo configure:1812: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_bigendian=no fi rm -f conftest* else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* if test $ac_cv_c_bigendian = unknown; then if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_bigendian=yes fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_c_bigendian" 1>&6 if test $ac_cv_c_bigendian = yes; then cat >> confdefs.h <<\EOF #define WORDS_BIGENDIAN 1 EOF fi for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1876: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1886: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1915: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 echo "configure:1971: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext < #include #include /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef HAVE_UNISTD_H # include # endif /* Assume that all systems that can run configure have sys/param.h. */ # ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ #ifdef __cplusplus extern "C" { void *malloc(unsigned); } #else char *malloc(); #endif int main() { char *data, *data2, *data3; int i, pagesize; int fd; pagesize = getpagesize(); /* * First, make a file with some known garbage in it. */ data = malloc(pagesize); if (!data) exit(1); for (i = 0; i < pagesize; ++i) *(data + i) = rand(); umask(0); fd = creat("conftestmmap", 0600); if (fd < 0) exit(1); if (write(fd, data, pagesize) != pagesize) exit(1); close(fd); /* * Next, try to mmap the file at a fixed address which * already has something else allocated at it. If we can, * also make sure that we see the same garbage. */ fd = open("conftestmmap", O_RDWR); if (fd < 0) exit(1); data2 = malloc(2 * pagesize); if (!data2) exit(1); data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) exit(1); /* * Finally, make sure that changes to the mapped area * do not percolate back to the file as seen by read(). * (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = malloc(pagesize); if (!data3) exit(1); if (read(fd, data3, pagesize) != pagesize) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) exit(1); close(fd); unlink("conftestmmap"); exit(0); } EOF if { (eval echo configure:2122: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_mmap_fixed_mapped=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 if test $ac_cv_func_mmap_fixed_mapped = yes; then cat >> confdefs.h <<\EOF #define HAVE_MMAP 1 EOF fi echo $ac_n "checking for vprintf""... $ac_c" 1>&6 echo "configure:2145: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vprintf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vprintf) || defined (__stub___vprintf) choke me #else vprintf(); #endif ; return 0; } EOF if { (eval echo configure:2176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vprintf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VPRINTF 1 EOF else echo "$ac_t""no" 1>&6 fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 echo "configure:2200: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char _doprnt(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub__doprnt) || defined (__stub____doprnt) choke me #else _doprnt(); #endif ; return 0; } EOF if { (eval echo configure:2231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func__doprnt=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_DOPRNT 1 EOF else echo "$ac_t""no" 1>&6 fi fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@CXX@%$CXX%g s%@LN_S@%$LN_S%g s%@SET_MAKE@%$SET_MAKE%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@CXXCPP@%$CXXCPP%g s%@CFLAGS_W@%$CFLAGS_W%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 chmod -w Makefile chmod -w config.h if test ! -f depend.m ; then touch depend.m ; fi echo echo "Run 'make' to build the application." echo bsign-0.4.5/configure.in0100660000175000017500000000302407421673574013246 0ustar elfelfdnl Process this file with autoconf to produce a configure script. AC_REVISION([$Id: configure.in,v 1.5 2002/01/18 01:16:44 elf Exp $]) AC_PREREQ(2.10)dnl dnl Minimum Autoconf version required. AC_INIT(bsign.cxx) AC_CONFIG_HEADER(config.h) AC_LANG_CPLUSPLUS dnl Default to c++ cause that what we done. dnl Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_INSTALL CFLAGS=-g CXXFLAGS=-g if test "${GXX}" = "yes" ; then CFLAGS_W=" -Wall -Wno-parentheses -Wno-unused" CFLAGS="${CFLAGS}" fi dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_FUNCS(strncasecmp memcpy bcopy strcspn strncpy cfmakeraw) AC_CHECK_FUNCS(vsnprintf vsprintf rindex strrchr) AC_CHECK_HEADERS(fcntl.h unistd.h gpm.h malloc.h string.h strings.h) dnl Checks for typedefs, structures, and compiler characteristics. dnl -- Removed because it is a bother dnl AC_C_CONST dnl -- Removed because it is a bother dnl AC_C_INLINE AC_TYPE_OFF_T AC_TYPE_SIZE_T AC_STRUCT_TM AC_STRUCT_TIMEZONE AC_CHECK_SIZEOF(long, 4) dnl -- Make sure to warn user AC_CHECK_SIZEOF(int, 4) dnl -- about these defaults. AC_CHECK_SIZEOF(long long, 8) dnl -- about these defaults. AC_C_BIGENDIAN dnl Checks for library functions. AC_FUNC_MMAP AC_FUNC_VPRINTF dnl -- We use vsprintf AC_SUBST(CFLAGS_W) AC_OUTPUT(Makefile) chmod -w Makefile chmod -w config.h dnl -- Create empty dependency file so that Make can include it if test ! -f depend.m ; then touch depend.m ; fi echo echo "Run 'make' to build the application." echo bsign-0.4.5/conversion.cxx0100660000175000017500000001352706634411316013644 0ustar elfelf/* conversion.cxx $Id: conversion.cxx,v 1.2 1998/12/12 06:53:02 elf Exp $ written by Oscar Levi 21 November 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- Inlines for converting between little endian-ness and big endian-ness. */ /* ----- Includes */ #include "standard.h" /* ----- Class Globals/Statics */ bool g_fOppositeSex; // Host and current input file use // other byte ordering. /* ----- Methods */ unsigned32 _v (unsigned32 l) { if (!g_fOppositeSex) return l; return ( ((l & 0xff) << 24) | ((l >> 24) & 0xff) | ((l & 0xff00) << 8) | ((l & 0xff0000) >> 8)); } /* _v */ unsigned32 _vl (unsigned32 l) { #if defined (HOST_LSB) return l; #else return ( ((l & 0xff) << 24) | ((l >> 24) & 0xff) | ((l & 0xff00) << 8) | ((l & 0xff0000) >> 8)); #endif } /* _vl */ unsigned32 _vm (unsigned32 l) { #if !defined (HOST_LSB) return l; #else return ( ((l & 0xff) << 24) | ((l >> 24) & 0xff) | ((l & 0xff00) << 8) | ((l & 0xff0000) >> 8)); #endif } /* _vm */ unsigned16 _v (unsigned16 s) { if (!g_fOppositeSex) return s; return ((s & 0xff) << 8) | ((s >> 8) & 0xff); } /* _v */ unsigned16 _vl (unsigned16 s) { #if defined HOST_LSB return s; #else return ((s & 0xff) << 8) | ((s >> 8) & 0xff); #endif } /* _vl */ unsigned16 _vm (unsigned16 s) { #if !defined HOST_LSB return s; #else return ((s & 0xff) << 8) | ((s >> 8) & 0xff); #endif } /* _vm */ int32 _v (int32 l) { if (!g_fOppositeSex) return l; return ( ((l & 0xff) << 24) | ((l >> 24) & 0xff) | ((l & 0xff00) << 8) | ((l & 0xff0000) >> 8)); } /* _v */ int32 _vl (int32 l) { #if defined HOST_LSB return l; #else return ( ((l & 0xff) << 24) | ((l >> 24) & 0xff) | ((l & 0xff00) << 8) | ((l & 0xff0000) >> 8)); #endif } /* _vl */ int32 _vm (int32 l) { #if !defined HOST_LSB return l; #else return ( ((l & 0xff) << 24) | ((l >> 24) & 0xff) | ((l & 0xff00) << 8) | ((l & 0xff0000) >> 8)); #endif } /* _vm */ int16 _v (int16 s) { if (!g_fOppositeSex) return s; return ((s & 0xff) << 8) | ((s >> 8) & 0xff); } /* _v */ int16 _vl (int16 s) { #if defined HOST_LSB return s; #else return ((s & 0xff) << 8) | ((s >> 8) & 0xff); #endif } /* _vl */ int16 _vm (int16 s) { #if !defined HOST_LSB return s; #else return ((s & 0xff) << 8) | ((s >> 8) & 0xff); #endif } /* _vm */ /* -------------------------------------------------- */ const char* _xd (unsigned long l) { static char sz[80]; if (l > 15) sprintf (sz, "0x%lx (%ld)", l, l); else if (l) sprintf (sz, "%ld", l); else sprintf (sz, "-"); return sz; } /* _xd */ const char* _x_d (unsigned long l) { static char sz[80]; if (l) sprintf (sz, "0x%lx (%ld)", l, l); else sprintf (sz, "-"); return sz; } /* _x_d */ const char* _d (unsigned long l) { static char sz[80]; if (l) sprintf (sz, "%ld", l); else sprintf (sz, "-"); return sz; } /* _d */ const char* _x (unsigned long l) { static char sz[80]; if (l) sprintf (sz, "0x%lx", l); else sprintf (sz, "-"); return sz; } /* _x */ const char* _b (unsigned long l, int bits) { static char sz[80]; unsigned long mask = 1 << (bits - 1); char* pch = sz; for (int bit = 0; bit < bits; ++bit, mask >>= 1) { if (bit && (bit % 4) == 0) *pch++ = ' '; *pch++ = ((l & mask) ? '1' : '0'); } *pch = 0; return sz; } /* _b */ int _print_hex (FILE* fp, int cb) { char szAscii[16]; int ib; for (ib = 0; cb; ++ib, --cb) { unsigned char b; fread (&b, 1, 1, fp); if ((ib % 16) == 0) printf ("%04x: ", ib); szAscii[ib%16] = isprint (b) ? b : '.'; printf ("%02x ", b); switch (ib%16) { case 7: printf (" "); break; case 15: printf ("%8.8s %8.8s\n", &szAscii[0], &szAscii[8]); break; } } if (ib % 16) { int cchOffset = 16 - (ib % 16); memset (szAscii + (ib % 16), ' ', cchOffset); cchOffset = cchOffset*3 + ((ib % 16) < 8 ? 1 : 0); printf ("%*.*s%8.8s %8.8s\n", cchOffset, cchOffset, "", &szAscii[0], &szAscii[8]); } return 0; } int _print_hex (const unsigned char* pb, int cb) { char szAscii[16]; int ib; for (ib = 0; cb; ++ib, --cb) { unsigned char b; b = *pb++; if ((ib % 16) == 0) printf ("%04x: ", ib); szAscii[ib%16] = isprint (b) ? b : '.'; printf ("%02x ", b); switch (ib%16) { case 7: printf (" "); break; case 15: printf ("%8.8s %8.8s\n", &szAscii[0], &szAscii[8]); break; } } if (ib % 16) { int cchOffset = 16 - (ib % 16); memset (szAscii + (ib % 16), ' ', cchOffset); cchOffset = cchOffset*3 + ((ib % 16) < 8 ? 1 : 0); printf ("%*.*s%8.8s %8.8s\n", cchOffset, cchOffset, "", &szAscii[0], &szAscii[8]); } return 0; } #if 0 const char* _name_id (int value, ID_SEARCH* rgids) { for (; rgids->sz; ++rgids) if (rgids->value == value) return rgids->sz; static char sz[80]; sprintf (sz, "unknown id 0x%x %d", value, value); return sz; } #endif bsign-0.4.5/conversion.h0100660000175000017500000000272006634411316013262 0ustar elfelf/* conversion.h $Id: conversion.h,v 1.2 1998/12/12 06:53:02 elf Exp $ written by Oscar Levi 21 Nov 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- */ #if !defined (__CONVERSION_H__) # define __CONVERSION_H__ /* ----- Includes */ /* ----- Globals */ extern bool g_fOppositeSex; unsigned32 _v (unsigned32 l); unsigned16 _v (unsigned16 s); int32 _v (int32 l); int16 _v (int16 s); unsigned32 _vl (unsigned32 l); unsigned16 _vl (unsigned16 s); int32 _vl (int32 l); int16 _vl (int16 s); unsigned32 _vm (unsigned32 l); unsigned16 _vm (unsigned16 s); int32 _vm (int32 l); int16 _vm (int16 s); #endif /* __CONVERSION_H__ */ bsign-0.4.5/ds.cxx0100660000175000017500000001366307425630077012074 0ustar elfelf/* ds.cxx $Id: ds.cxx,v 1.16 2002/01/29 23:29:03 elf Exp $ written by Oscar Levi 6 December 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- Interface for generating digital signature certificates. The first round uses gpg for generating signatures. */ #define USE_BATCHMODE // Silent operation of gpg #include "standard.h" #include "exec.h" #include "ds.h" #include "exitstatus.h" #include "tty.h" extern int g_fDebug; extern const char* g_szApplication; extern const char* g_szPGOptions; extern int g_fVerbose; const char* fetch_passphrase (void); #define TEMPLATE_VERIFY "/tmp/bsignv-XXXXXX" char g_szPathTempVerify[] = TEMPLATE_VERIFY; #define PG_PROGRAM "gpg" /* cleanup_temp_verify function to remove the temporary used during verification. Until we can verify without writing the data to disk, this is the best we can do. This function is so declared because it is called from the signal handlers. */ void cleanup_temp_verify (bool fSignal) { if (g_szPathTempVerify[0]) { int result = unlink (g_szPathTempVerify); // if (result == 0 && fSignal) // fprintf (stderr, "unlinked temp %s\n", g_szPathTempVerify); } if (!fSignal) g_szPathTempVerify[0] = 0; } /* create_digital_signature takes the cb byte data block at pb, writes it to a temporary file invokes the appropriate software to sign it, and returns the data in a memory block. The first two bytes of the data block are the MSB ordered length of the signature. The return value is NULL if the signature could not be created. */ char* create_digital_signature (const char* pb, size_t cb) { // if (g_fDebug) // fprintf (stderr, "options: '%s'\n", g_szPGOptions); // Create control streams char rgbSignature[512]; char rgbErr[1024]; // *** FIXME: we need a ring buffer maybe? const char* szPass = fetch_passphrase (); if (!szPass) return NULL; ExStream exsIn, exsOut, exsPassPhrase, exsErr; if ( !exsIn.for_stdin (pb, cb) || !exsOut.for_stdout (rgbSignature, sizeof (rgbSignature)) || !exsPassPhrase.for_writing (szPass, strlen (szPass)) || !exsErr.for_stderr (rgbErr, sizeof (rgbErr)) ) return NULL; char sz[256]; sprintf (sz, PG_PROGRAM " --no-greeting " #if defined (USE_BATCHMODE) "--batch " #endif "-sb -o - --passphrase-fd %d %s", exsPassPhrase.fd_write (), g_szPGOptions ? g_szPGOptions : ""); ExStream* rgexs[] = { &exsIn, &exsOut, &exsPassPhrase, &exsErr }; int result = ExStream::exec (sz, rgexs, sizeof (rgexs)/sizeof (ExStream*)); if (result) { if (g_fVerbose) fprintf (stderr, "%s\n", rgbErr); return NULL; } cb = exsOut.used (); char* pbReturn = (char*) malloc (cb + 2); pbReturn[0] = ((cb >> 8) & 0xff); pbReturn[1] = (cb & 0xff); memcpy (pbReturn + 2, rgbSignature, cb); return pbReturn; } eExitStatus verify_digital_signature (const char* pbData, size_t cbData, const char* pbCert, size_t cbCert) { if (cbCert == 0) // Kind of a sanity check. We also return badsignature; // verify this at the next layer up. // This is here in case we call from // some other place. // Create control streams char rgbErr[1024]; ExStream exsIn, exsErr; if ( !exsIn.for_stdin (pbCert, cbCert) || !exsErr.for_stderr (rgbErr, sizeof (rgbErr))) return toomanyopenfiles; #if 1 strcpy (g_szPathTempVerify, TEMPLATE_VERIFY); int fh = mkstemp (g_szPathTempVerify); // *** FIXME, more error handling? if (g_fDebug) fprintf (stderr, "%s: creating temporary '%s' for data on verify\n", g_szApplication, g_szPathTempVerify); write (fh, pbData, cbData); close (fh); #endif char sz[256]; sprintf (sz, PG_PROGRAM " --no-greeting " #if defined (USE_BATCHMODE) "--batch " #endif "%s --verify - %s", g_szPGOptions ? g_szPGOptions : "", g_szPathTempVerify); ExStream* rgexs[] = { &exsIn, &exsErr }; int result = ExStream::exec (sz, rgexs, sizeof (rgexs)/sizeof (ExStream*)); cleanup_temp_verify (false); if (result && g_fVerbose) fprintf (stderr, "error result %d\n%s\n", result, rgbErr); if (!result) return noerror; switch (result) { default: return badsignature; case 127: return programnotfound; } } /* fetch_passphrase ask the user for the passphrase. We cache this phrase and return it for every subsequenct call. This is fine, for now. It is possible that we'll do something more sophisticated later, but it is probably not necessary. */ const char* fetch_passphrase (void) { static char* g_szPassPhrase; if (g_szPassPhrase) return g_szPassPhrase; g_szPassPhrase = (char*) malloc (512); // *** FIXME make this raw or // something so we don't ECHO. We do // want to continue to input until we // receive a newline, though. int fh = open_user_tty (); if (fh == -1) return NULL; disable_echo (fh); char szMessage[] = "\nEnter pass phrase: "; write (fh, szMessage, strlen (szMessage)); // fflush (stdout); size_t cb = read (fh, g_szPassPhrase, 511); restore_echo (fh); write (fh, "\n", 1); close (fh); g_szPassPhrase[cb] = 0; return g_szPassPhrase; } bsign-0.4.5/ds.h0100660000175000017500000000246706634541376011525 0ustar elfelf/* ds.h -*- C++ -*- $Id: ds.h,v 1.4 1998/12/12 19:24:46 elf Exp $ written by Oscar Levi 21 Nov 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- */ #if !defined (__DS_H__) # define __DS_H__ /* ----- Includes */ #include "exitstatus.h" /* ----- Globals */ char* create_digital_signature (const char* pb, size_t cb); eExitStatus verify_digital_signature (const char* pbData, size_t cbData, const char* pbCert, size_t cbCert); #endif /* __DS_H__ */ bsign-0.4.5/elf.cc0100660000175000017500000007572107422673350012020 0ustar elfelf/* elf.cc $Id: elf.cc,v 1.1 2002/01/21 02:03:20 elf Exp $ written by Oscar Levi 20 January 2002 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- Interface to the ELF file format. It copes with endian differences as well as pointer width differences. */ #include "standard.h" #include #include "conversion.h" typedef enum { ELF_BITCLASS_NUL = 0, ELF_BITCLASS_32 = 1, ELF_BITCLASS_64 = 2, } E_ELF_BITCLASS; typedef enum { ELF_BYTEORDER_NUL = 0, ELF_BYTEORDER_LSB = 1, ELF_BYTEORDER_MSB = 2, } E_ELF_BYTEORDER; typedef enum { ELF_FILETYPE_MASK = 0xff, ELF_FILETYPE_NUL = 0, ELF_FILETYPE_RELOCATABLE = 1, ELF_FILETYPE_EXECUTABLE = 2, ELF_FILETYPE_SHAREDOBJECT = 3, ELF_FILETYPE_CORE = 4, } E_ELF_FILETYPE; typedef enum { ELF_CPU_MASK = 0xff, ELF_CPU_NUL = 0, ELF_CPU_WE32K = 1, // AT&T WE32100 (MSB) ELF_CPU_SPARC = 2, // SPARC (MSB) ELF_CPU_I386 = 3, // Intel 80386 (LSB) ELF_CPU_M68K = 4, // Motorola 68x000 (MSB) ELF_CPU_M88K = 5, // Motorola 88000 (LSB) ELF_CPU_I486 = 6, // Intel 80486 (LSB) ELF_CPU_I860 = 7, // Intel 80860 (LSB) ELF_CPU_R3000 = 8, // MIPS RS3000 (MSB) ELF_CPU_AMDAHL = 9, // Amdahl (LSB) ELF_CPU_R4000 = 10, // MIPS RS4000 (MSB) ELF_CPU_SPARC64 = 11, // SPARC v9 (64 bit) ELF_CPU_HPPA = 15, // HP PA RISC ELF_CPU_SPARC32P = 18, // SPARC v8 plus (32 bit) ELF_CPU_PPC = 20, // IBM PowerPC ELF_CPU_IA64 = 50, // Intel Itanium (ia64) ELF_CPU_PPC_CYG = 0x9025, // IBM PowerPC by Cygnus Support } E_ELF_CPU; typedef enum { elf_header = 0x10000, elf_program = 0x20000, elf_section = 0x30000, elf_symbol = 0x40000, elf_fixup = 0x50000, } ELF_STRUCTURE; typedef enum { addr = 1, addrEntry, addrPhysical, addrVirtual, alignment, bitclass, byteorder, cEntryProgram, cEntrySection, cb, cbEntry, cbEntryProgram, cbEntrySection, cbFile, cbHeader, cbMemory, cpu, filetype, flags, flags, flags, iLink, iSection, iSectionNames, ib, ibHdrProgram, ibHdrSection, ibName, info, other, programtype, rgbID, rgbMagic, sectiontype, value, version, } ELF_FIELD; typedef enum { byte_4 = 1, // Four bytes byte_10, // Ten bytes unsigned_8, // Unsigned 8 bit unsigned_16, // Unsigned 16 bit unsigned_32, // Unsigned 32 bit address, // Address pointer for bitcass index, // Counter (word sized) for bitclass } ELF_FIELD_SIZE; typedef enum { ELF_SECTION_NUL = 0, ELF_SECTION_PROGBITS = 1, // Program specific (private) ELF_SECTION_SYMBOLS = 2, // Symbol table ELF_SECTION_STRINGS = 3, // String table ELF_SECTION_RELOC_A = 4, // Relocation entries with addends ELF_SECTION_HASH = 5, // Hash table for symbols ELF_SECTION_DYNAMIC = 6, // Dynamic linking information ELF_SECTION_NOTE = 7, ELF_SECTION_NOBITS = 8, // Empty section ELF_SECTION_RELOC = 9, // Relocation entries, no addends ELF_SECTION_SHLIB = 10, // ELF_SECTION_SYMBOLS_D = 11, // Dynamic linking symbols ELF_SECTION_SIGNATURE = ((0x80 << 24)|('s' << 16)|('i' << 8)|'g'), } E_ELF_SECTION; typedef enum { ELF_SECTION_F_WRITABLE = 0x0001, ELF_SECTION_F_ALLOCATE = 0x0002, ELF_SECTION_F_EXECUTABLE = 0x0004, } E_ELF_SECTION_F; typedef enum { ELF_PROGRAM_NULL = 0, ELF_PROGRAM_LOAD = 1, // Loadable segment ELF_PROGRAM_DYNAMIC = 2, // Dynamic linking information ELF_PROGRAM_INTERP = 3, // Program interpreter information ELF_PROGRAM_NOTE = 4, // Auxiliary information ELF_PROGRAM_SHLIB = 5, // Unspecified semantics (v1.1) ELF_PROGRAM_PHDR = 6, // Program header table, if loaded } E_ELF_PROGRAM; typedef unsigned32 elf32; typedef unsigned64 elf64; typedef struct { unsigned32 field; int width; int ib; // Computed offset and width int cb; // for this field } FIELD; FIELD rgField[] = { // Header { elf_header | rgbID, byte_4 }, { elf_header | bitclass, unsigned8 }, { elf_header | byteorder, unsigned8 }, { elf_header | rgbMagic, byte_10 }, { elf_header | filetype, unsigned16 }, { elf_header | cpu, unsigned16 }, { elf_header | version, unsigned32 }, { elf_header | addrEntry, address }, { elf_header | ibHdrProgram, index }, { elf_header | ibHdrSection, index }, { elf_header | flags, unsigned32 }, { elf_header | cbHeader, unsigned16 }, { elf_header | cbEntryProgram, unsigned16 }, { elf_header | cEntryProgram, unsigned16 }, { elf_header | cbEntrySection, unsigned16 }, { elf_header | cEntrySection, unsigned16 }, { elf_header | iSectionNames, unsigned16 }, { elf_program | programtype, unsigned32 }, { elf_program | ib, index }, { elf_program | addrVirtual, address }, { elf_program | addrPhysical, address }, { elf_program | cbFile, index }, { elf_program | cbMemory, index }, { elf_program | flags, unsigned32 }, { elf_program | alignment, unsigned32 }, { elf_section | ibName, unsigned32 }, { elf_section | sectiontype, unsigned32 }, { elf_section | flags, unsigned32 }, { elf_section | addr, address }, { elf_section | ib, index }, { elf_section | cb, index }, { elf_section | iLink, unsigned32 }, { elf_section | info, unsigned32 }, { elf_section | alignment, unsigned32 }, { elf_section | cbEntry, unsigned32 }, { elf_symbol | ibName, unsigned32 }, { elf_symbol | value, unsigned32 }, { elf_symbol | cb, index }, { elf_symbol | info, unsigned8 }, { elf_symbol | other, unsigned8 }, { elf_symbol | iSection, unsigned16 }, { 0 } }; typedef struct { char rgbID[4]; // ID for ELF file "\177ELF" unsigned8 bitclass; // 1, 32 bit; 2, 64 bit unsigned8 byteorder; // 1, LSB; 2, MSB char rgbMagic[10]; // Part of the magic number unsigned16 filetype; // 1, reloc; 2, exec; 3, shared; 4, core unsigned16 cpu; unsigned32 version; elf32 addrEntry; // Virtual address entry point elf32 ibHdrProgram; // Offset to program header elf32 ibHdrSection; // Offset to section header unsigned32 flags; // CPU specific flags unsigned16 cbHeader; // Size of header unsigned16 cbEntryProgram; // Length of each program header entry unsigned16 cEntryProgram; // Count of program header entries unsigned16 cbEntrySection; // Length of each section header entry unsigned16 cEntrySection; // Count of section header entries unsigned16 iSectionNames; // Section with section names } HDR_ELF32; typedef struct { char rgbID[4]; // ID for ELF file "\177ELF" unsigned8 bitclass; // 1, 32 bit; 2, 64 bit unsigned8 byteorder; // 1, LSB; 2, MSB char rgbMagic[10]; // Part of the magic number unsigned16 filetype; // 1, reloc; 2, exec; 3, shared; 4, core unsigned16 cpu; unsigned32 version; elf64 addrEntry; // Virtual address entry point elf64 ibHdrProgram; // Offset to program header elf64 ibHdrSection; // Offset to section header unsigned32 flags; // CPU specific flags unsigned16 cbHeader; // Size of header unsigned16 cbEntryProgram; // Length of each program header entry unsigned16 cEntryProgram; // Count of program header entries unsigned16 cbEntrySection; // Length of each section header entry unsigned16 cEntrySection; // Count of section header entries unsigned16 iSectionNames; // Section with section names } HDR_ELF64; typedef struct { unsigned32 programtype; unsigned32 ib; unsigned32 addrVirtual; unsigned32 addrPhysical; unsigned32 cbFile; unsigned32 cbMemory; unsigned32 flags; unsigned32 alignment; } PROGRAM_ELF32; typedef struct { unsigned32 ibName; // Index to name of section unsigned32 sectiontype; unsigned32 flags; unsigned32 addr; // Virtual address during execution unsigned32 ib; // Offset to section data unsigned32 cb; // Length of section data unsigned32 iLink; // Index of another section (link?) unsigned32 info; unsigned32 alignment; unsigned32 cbEntry; // Section table entry size, if applicable } SECTION_ELF32; typedef struct { unsigned32 ibName; // Index of symbol name unsigned32 value; // Symbol value unsigned32 cb; // Size of symbol unsigned8 info; // Symbol binding info unsigned8 other; // unsigned16 iSection; // Section associated with symbol } SYMBOL_ELF32; // -- FIXUP -- description of change to a file region typedef struct _FIXUP { struct _FIXUP* pNext; // Link to next fixup unsigned32 ib; // Original location unsigned32 cb; // Original size unsigned32 ibNew; // New location unsigned32 cbNew; // New size void* pv; // Pointer to the new data for this range const char* szDescription; // Debug diagnostic } FIXUP32; const char g_szSectionSig[] = "signature"; // Perhaps not the best // name, but it is descriptive #define CB_SIGNATURE (512) // *** FIXME: hard coded, for now size_t rewrite_elf32 (char* pb, size_t cb, int fh, FIXUP32& fixup); void check_byte_sex (const void* pv) { #if defined (WORDS_BIGENDIAN) g_fOppositeSex = (((HDR_ELF32*)pv)->byteorder != ELF_BYTEORDER_MSB); #else g_fOppositeSex = (((HDR_ELF32*)pv)->byteorder != ELF_BYTEORDER_LSB); #endif } /* sign_file generates a hash with or without a digital signature. The return value is a pointer to the data. In this implementation, the signature block is of a fixed length. If the return value is NULL, the digital signature could not be created. */ char* sign_file (char* pb, size_t cb, size_t ibSignature, size_t cbSignature, bool fCreateCert) { void* pv = malloc (cbSignature); memset (pv, 0, cbSignature); size_t cbContext; void (*pfn_init)(void*); void (*pfn_write)(void*, byte*, size_t); void (*pfn_final)(void*); byte* (*pfn_read)(void*); byte* r_asnoid; // ? int r_asnlen; // ? int r_mdlen; // Digest length? sha1_get_info (2, &cbContext, &r_asnoid, &r_asnlen, &r_mdlen, &pfn_init, &pfn_write, &pfn_final, &pfn_read); void* hd = malloc (cbContext); (*pfn_init) (hd); (*pfn_write) (hd, (byte*) pb, ibSignature); (*pfn_write) (hd, (byte*) pv, cbSignature); (*pfn_write) (hd, (byte*) pb + ibSignature + cbSignature, cb - ibSignature - cbSignature); (*pfn_final) (hd); unsigned8* rgb = (*pfn_read) (hd); char* rgbSignature = (char*) malloc (CB_SIGNATURE); memset (rgbSignature, 0, CB_SIGNATURE); char* pbHash = rgbSignature + sprintf (rgbSignature, "#1; bsign v%s\n", g_szVersion); size_t cbHeader = pbHash - rgbSignature; memcpy (pbHash, rgb, 20); free (hd); // *** generating cert every time if (fCreateCert) { char* rgbCert = create_digital_signature (rgbSignature, cbHeader + 20); if (rgbCert) { size_t cbCert = rgbCert[0]*256 + rgbCert[1] + 2; memcpy (pbHash + 20, rgbCert, cbCert); free (rgbCert); } else { delete rgbSignature; return NULL; } } return rgbSignature; } int size_elf_header (void) { return sizeof (HDR_ELF64); // Largest header size } /* is_elf returns whether or not we believe we will be successful in rewriting the file. This may require a somewhat indepth examination of the elf headers to make sure that all appears well. Remember that we expect to find corrupt executables and these may be corrupted in subtle ways. The key, though, is our success is rewriting the file. It is also important to recognize that an file with a superficial appearance of being elf that has deeper problems is the goal of this project. Either those problems are simple changes to the contents of the file, or the malicious surgery of a hacker. We find it all. */ bool is_elf (char* pb, size_t cb) { if (cb < sizeof (HDR_ELF32)) return false; check_byte_sex (pb); HDR_ELF32& header = *(HDR_ELF32*) pb; if (memcmp (header.rgbID, "\177ELF", 4) != 0 || header.bitclass < 1 || header.bitclass > 2 || header.byteorder < 1 || header.byteorder > 2 || _v (header.filetype) < 1 || _v (header.filetype) > 4 || ( _v (header.ibHdrProgram) && _v (header.ibHdrProgram) < sizeof (header)) || _v (header.ibHdrProgram) >= cb || _v (header.ibHdrSection) < sizeof (header) || _v (header.ibHdrSection) >= cb || _v (header.cbHeader) != sizeof (header) || ( _v (header.cbEntryProgram) && _v (header.cbEntryProgram) != sizeof (PROGRAM_ELF32)) || _v (header.cbEntrySection) != sizeof (SECTION_ELF32) || _v (header.iSectionNames) >= _v (header.cEntrySection)) return false; // *** FIXME: I don't recall why we need more than a header test. const PROGRAM_ELF32* rgProgram = (PROGRAM_ELF32*) (pb + _v (header.ibHdrProgram)); for (int i = 0; i < _v (header.cEntryProgram); ++i) if ( _v (rgProgram[i].ib) >= cb || _v (rgProgram[i].ib) + _v (rgProgram[i].cbFile) > cb) return false; const SECTION_ELF32* rgSection = (SECTION_ELF32*) (pb + _v (header.ibHdrSection)); for (int i = 1; i < _v (header.cEntrySection); ++i) if (_v (rgSection[i].sectiontype) != ELF_SECTION_NOBITS && (_v (rgSection[i].ib) >= cb || _v (rgSection[i].ib) + _v (rgSection[i].cb) > cb)) return false; return true; } /* is_elf */ bool is_elf_header (const char* pb, size_t cb) { if (cb < sizeof (HDR_ELF32)) return false; check_byte_sex (pb); HDR_ELF32& header = *(HDR_ELF32*) pb; if (memcmp (header.rgbID, "\177ELF", 4) != 0 || header.bitclass < 1 || header.bitclass > 2 || header.byteorder < 1 || header.byteorder > 2 || _v (header.filetype) < 1 || _v (header.filetype) > 4 || ( _v (header.ibHdrProgram) && _v (header.ibHdrProgram) < sizeof (header)) || _v (header.ibHdrSection) < sizeof (header) || _v (header.cbHeader) != sizeof (header) || ( _v (header.cbEntryProgram) && _v (header.cbEntryProgram) != sizeof (PROGRAM_ELF32)) || _v (header.cbEntrySection) != sizeof (SECTION_ELF32) || _v (header.iSectionNames) >= _v (header.cEntrySection)) return false; return true; } /* is_elf_signed returns true if this file is an elf file and if it is signed. The pibSignature and pcbSignature parameters are set with the position and length of the signature block if there is a signature. Note that another call must be made to compute the hash of the file and verify the signature. This function does not distinguish between non-elf files and unsigned elf files. */ bool is_elf_signed (char* pb, size_t cb, size_t* pibSignature, size_t* pcbSignature) { if (!is_elf (pb, cb)) return false; const HDR_ELF32& hdr = *(HDR_ELF32*) pb; const SECTION_ELF32* rgSection = (SECTION_ELF32*) (pb + _v (hdr.ibHdrSection)); for (int i = 0; i < _v (hdr.cEntrySection); ++i) { if (_v (rgSection[i].sectiontype) == unsigned32 (ELF_SECTION_SIGNATURE)) { if (pibSignature) *pibSignature = _v (rgSection[i].ib); if (pcbSignature) *pcbSignature = _v (rgSection[i].cb); return true; } } return false; } /* check_elf returns an eAppResult code indicating the success of the hash/signature verification. */ eExitStatus check_elf (char* pb, size_t cb, bool fExpectSignature) { if (!is_elf (pb, cb)) return unsupportedfiletype; size_t ibSignature; size_t cbSignature; if (!is_elf_signed (pb, cb, &ibSignature, &cbSignature)) return fExpectSignature ? nosignature : nohash; size_t ibHash = ibSignature; for (ibHash = ibSignature; ibHash < ibSignature + cbSignature - 20; ++ibHash) if (pb[ibHash] == '\n') { ++ibHash; break; } if (fExpectSignature && ibHash == ibSignature + cbSignature - 20) return nosignature; char* rgbSignature = sign_file (pb, cb, ibSignature, cbSignature, false); char* pbSignature; for (pbSignature = rgbSignature; pbSignature < rgbSignature + CB_SIGNATURE; ++pbSignature) if (*pbSignature == '\n') { ++pbSignature; break; } eExitStatus result = ((memcmp (pbSignature, pb + ibHash, 20) != 0) ? badhash : noerror); free (rgbSignature); if (result || !fExpectSignature) return result; // Check digital signature if hash OK size_t cbCert = (pb[ibHash + 20] << 8) | pb[ibHash + 21]; if (cbCert == 0 || cbCert > cbSignature - (ibHash - ibSignature + 20)) return badsignature; return verify_digital_signature (pb + ibSignature, ibHash - ibSignature + 20, pb + ibHash + 22, cbCert); } /* hash_elf generates a signature section for a ELF file. The algorithm rewrites the file, removing the old signature if there was one, hashes this portion, and appends the new signature to the end. This depends only on us knowning the length of the cert. In theory, we could put our signature section anywhere in the file, but this layout is convenient at the time. The most likely enhancement from here would be the ability to update a signature in place, making this function more efficient, and making the hashing a little more difficult. *** FIXME: the return value is an error code. We need to establish a set of these so we can determine the cause of failures. We don't want to appears foolish like Microsoft. */ eExitStatus hash_elf (char* pb, size_t cb, int fhNew, bool fSign) { check_byte_sex (pb); FIXUP32 fixupSignature; memset (&fixupSignature, 0, sizeof (fixupSignature)); fixupSignature.cb = CB_SIGNATURE; // Perform rewrite size_t cbRewrite = rewrite_elf32 (pb, cb, fhNew, fixupSignature); if (cbRewrite == (size_t) -1) return rewritefailed; char* pbMap = (char*) mmap (NULL, cbRewrite, PROT_READ, MAP_FILE | MAP_PRIVATE, fhNew, 0); assert (pbMap); char* rgbSignature = sign_file (pbMap, cbRewrite, fixupSignature.ibNew, fixupSignature.cbNew, fSign); munmap (pbMap, cbRewrite); if (rgbSignature) { lseek (fhNew, fixupSignature.ibNew, SEEK_SET); write (fhNew, rgbSignature, CB_SIGNATURE); delete rgbSignature; return noerror; } return badpassphrase; } /* new_sectionnames returns a buffer containing sections names with the name of the signature buffer added to the end. The first parameter is a pointer to the file in memory. */ char* new_sectionnames32 (char* pb, size_t cb, SECTION_ELF32& sectionNames, SECTION_ELF32& sectionSig) { const HDR_ELF32& hdr = *(HDR_ELF32*) pb; sectionSig.ibName = sectionNames.cb; sectionSig.alignment = _v (unsigned32 (1)); sectionSig.sectiontype = _v (unsigned32 (ELF_SECTION_SIGNATURE)); unsigned32 cbSectionNamesNew = _v (sectionNames.cb) + sizeof (g_szSectionSig); cbSectionNamesNew = (cbSectionNamesNew + 3) & ~3; // Round to words char* sz = (char*) malloc (cbSectionNamesNew); memcpy (sz, pb + _v (sectionNames.ib), _v (sectionNames.cb)); memcpy (sz + _v (sectionNames.cb), g_szSectionSig, sizeof (g_szSectionSig)); sectionNames.cb = _v (cbSectionNamesNew); return sz; } void fixup_range32 (const unsigned32& ibOld, const unsigned32& cbOld, unsigned32& ib, unsigned32& cb, const FIXUP32& fixup) { // Fixup occurs after this range if (fixup.ib >= _v (ibOld) + _v (cbOld)) return; // Fixup preceeds this range if (_v (ibOld) >= fixup.ib + fixup.cb) { ib += fixup.cbNew - fixup.cb; return; } // *** FIXME: weak sanity check assert (fixup.ib >= _v (ibOld)); // elf: in fact, this next check is so // weak it is wrong. In rereading // this line, I cannot tell WHAT I was // thinking. // assert (fixup.ib + fixup.cb <= _v (ibOld) + _v (cbOld)); // Fixup within this program cb += fixup.cbNew - fixup.cb; } /* fixup_fixups fills the ibNew fields so we can write the output file conveniently. The *best* algorithm would sort the list before computing the ibNew fields. Instead, we implement an O(n^2) routine that checks every fixup with every other fixup. With anything less than a dozen, this is certainly OK. We make the reasonable assumption that the fixups don't overlap. The return value is the number of bytes added to the file due to these fixups. */ unsigned32 fixup_fixups32 (FIXUP32* pFixupHead) { unsigned32 cb = 0; for (FIXUP32* pFixupOuter = pFixupHead; pFixupOuter; pFixupOuter = pFixupOuter->pNext) { pFixupOuter->ibNew = pFixupOuter->ib; cb += pFixupOuter->cbNew - pFixupOuter->cb; for (FIXUP32* pFixupInner = pFixupHead; pFixupInner; pFixupInner = pFixupInner->pNext) if (pFixupInner->ib < pFixupOuter->ib) pFixupOuter->ibNew += pFixupInner->cbNew - pFixupInner->cb; } return cb; } void fixup_elf32_programs (const HDR_ELF32& hdr, PROGRAM_ELF32* rgProgram, const PROGRAM_ELF32* rgProgramOld, const FIXUP32* rgFixup) { for (int iProgram = 0; iProgram < _v (hdr.cEntryProgram); ++iProgram) for (const FIXUP32* pFixup = rgFixup; pFixup; pFixup = pFixup->pNext) fixup_range32 (rgProgramOld[iProgram].ib, rgProgramOld[iProgram].cbFile, rgProgram[iProgram].ib, rgProgram[iProgram].cbFile, *pFixup); } void fixup_elf32_sections (const HDR_ELF32& hdr, SECTION_ELF32* rgSection, const SECTION_ELF32* rgSectionOld, const FIXUP32* rgFixup) { for (int iSection = 0; iSection < _v (hdr.cEntrySection); ++iSection) for (const FIXUP32* pFixup = rgFixup; pFixup; pFixup = pFixup->pNext) fixup_range32 (rgSectionOld[iSection].ib, rgSectionOld[iSection].cb, rgSection[iSection].ib, rgSection[iSection].cb, *pFixup); } void fixup_elf32_header (HDR_ELF32& hdr, const HDR_ELF32& hdrOld, const FIXUP32* rgFixup) { for (const FIXUP32* pFixup = rgFixup; pFixup; pFixup = pFixup->pNext) { unsigned32 cbOld; unsigned32 cb; if (_v (hdrOld.cEntryProgram)) { cbOld = _v (unsigned32 (_v (hdrOld.cbEntryProgram) *_v (hdrOld.cEntryProgram))); cb = _v (unsigned32 (_v (hdr.cbEntryProgram)*_v (hdr.cEntryProgram))); fixup_range32 (hdrOld.ibHdrProgram, cbOld, hdr.ibHdrProgram, cb, *pFixup); } cbOld = _v (unsigned32 (_v (hdrOld.cbEntrySection) *_v (hdrOld.cEntrySection))); cb = _v (unsigned32 (_v (hdr.cbEntrySection)*_v (hdr.cEntrySection))); fixup_range32 (hdrOld.ibHdrSection, cbOld, hdr.ibHdrSection, cb, *pFixup); } } void report_elf32 (const HDR_ELF32& hdr, const SECTION_ELF32* rgSection) { fprintf (stderr, "%08x %08x header\n", 0, sizeof (hdr)); fprintf (stderr, "%08x %08x program header\n", _v (hdr.ibHdrProgram), _v (hdr.cbEntryProgram)*_v (hdr.cEntryProgram)); fprintf (stderr, "%08x %08x section header\n", _v (hdr.ibHdrSection), _v (hdr.cbEntrySection)*_v (hdr.cEntrySection)); for (int i = 0; i < _v (hdr.cEntrySection); ++i) { fprintf (stderr, "%08x %08x section %d\n", _v (rgSection[i].ib), _v (rgSection[i].cb), i); } } void report_fixup (const FIXUP32* pFixup) { fprintf (stderr, "%8d l%8d->%8d %8d l%8d->%8d %s\n", pFixup->ib, pFixup->cb, pFixup->ib + pFixup->cb, pFixup->ibNew, pFixup->cbNew, pFixup->ibNew + pFixup->cbNew, pFixup->szDescription); } void report_fixups (const FIXUP32* pFixup) { for (; pFixup; pFixup = pFixup->pNext) report_fixup (pFixup); } /* rewrite_elf rewrites an elf file making the appropriate changes to support a signature section. The fixupSignature section must contain a cb value large enough to contain the signature data. The fixupSignature ibNew and cbNew will point to the place in the new file where the signature is written. If the file already has a signature section and if that section is at least as large as requested, the file will be copied. The portion of the file to hold the signature is *always* initialized to nulls. Note, we count on the first fixup being the new signature space when we do the complex rewrite. This is done to make it easy to free the blank buffer and to recover the new signature location. We return -1 when there's an error during rewrite. */ size_t rewrite_elf32 (char* pb, size_t cb, int fh, FIXUP32& fixupSignature) { const HDR_ELF32 hdrOld = *(HDR_ELF32*) pb; if (sizeof (hdrOld) != _v (hdrOld.cbHeader)) // We must have this return 0; if (_v (hdrOld.cEntryProgram) && sizeof (PROGRAM_ELF32) != _v (hdrOld.cbEntryProgram)) // We must have this return 0; if (_v (hdrOld.cEntrySection) && sizeof (SECTION_ELF32) != _v (hdrOld.cbEntrySection)) // We must have this return 0; const SECTION_ELF32* rgSectionOld = (SECTION_ELF32*) (pb + _v (hdrOld.ibHdrSection)); FIXUP32 fixupOldSignature; int iSectionOldSignature = 0; memset (&fixupOldSignature, 0, sizeof (fixupOldSignature)); // Check to see if the file has a // sufficiently large signature section for (int i = 0; i < _v (hdrOld.cEntrySection); ++i) { if (_v (rgSectionOld[i].sectiontype) == unsigned32 (ELF_SECTION_SIGNATURE)) { fixupOldSignature.ib = _v (rgSectionOld[i].ib); fixupOldSignature.cb = _v (rgSectionOld[i].cb); iSectionOldSignature = i; break; } } // Data block for initializing signature fixupOldSignature.ibNew = fixupOldSignature.ib; // Old signature sufficient, easiest solution if (fixupOldSignature.cb >= fixupSignature.cb) { void* pv = malloc (fixupOldSignature.cb); memset (pv, 0, fixupOldSignature.cb); write (fh, pb, fixupOldSignature.ib); write (fh, pv, fixupOldSignature.cb); write (fh, pb + fixupOldSignature.ib + fixupOldSignature.cb, cb - fixupOldSignature.ib - fixupOldSignature.cb); free (pv); fixupSignature = fixupOldSignature; fixupSignature.cbNew = fixupOldSignature.cb; return cb; } // Make new program and section headers HDR_ELF32 hdr = *(HDR_ELF32*) pb; const PROGRAM_ELF32* rgProgramOld = (PROGRAM_ELF32*) (pb + _v (hdr.ibHdrProgram)); PROGRAM_ELF32* rgProgram = hdr.ibHdrProgram ? new PROGRAM_ELF32[_v (hdr.ibHdrProgram)] : NULL; if (rgProgram) memcpy (rgProgram, rgProgramOld, _v (hdr.cEntryProgram)*_v (hdr.cbEntryProgram)); SECTION_ELF32* rgSection = new SECTION_ELF32[_v (hdr.cEntrySection) + (iSectionOldSignature ? 0 : 1)]; memcpy (rgSection, rgSectionOld, _v (hdr.cEntrySection)*_v (hdr.cbEntrySection)); // report_elf (hdr, rgSectionOld); SECTION_ELF32& sectionSig = rgSection[_v (hdr.cEntrySection)]; SECTION_ELF32& sectionNames = rgSection[iSectionOldSignature ? iSectionOldSignature : _v (hdr.iSectionNames)]; memset (§ionSig, 0, sizeof (sectionSig)); char* rgbSectionNames = new_sectionnames32 (pb, cb, sectionNames, sectionSig); if (!iSectionOldSignature) hdr.cEntrySection = _v (_v (hdr.cEntrySection) + (unsigned32) 1); // Generate fixup lists FIXUP32* pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->ib = _v (rgSectionOld[_v (hdr.iSectionNames)].ib); pFixup->cb = _v (rgSectionOld[_v (hdr.iSectionNames)].cb); pFixup->cbNew = _v (rgSection[_v (hdr.iSectionNames)].cb); pFixup->pv = rgbSectionNames; pFixup->szDescription = "section names"; FIXUP32* pFixupHead = pFixup; pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = _v (hdrOld.ibHdrSection); pFixup->cb = _v (hdrOld.cEntrySection)*_v (hdrOld.cbEntrySection); pFixup->cbNew = _v (hdr.cEntrySection)*_v (hdr.cbEntrySection); pFixup->pv = rgSection; pFixup->szDescription = "entry section"; if (_v (hdrOld.cEntryProgram)) { pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = _v (hdrOld.ibHdrProgram); pFixup->cb = _v (hdrOld.cEntryProgram)*_v (hdrOld.cbEntryProgram); pFixup->cbNew = _v (hdr.cEntryProgram)*_v (hdr.cbEntryProgram); pFixup->pv = rgProgram; pFixup->szDescription = "entry program"; } pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = 0; pFixup->cb = sizeof (hdr); pFixup->cbNew = sizeof (hdr); pFixup->pv = &hdr; pFixup->szDescription = "header"; // Clobber old signature if (fixupOldSignature.cb) { pFixup = new FIXUP32; memcpy (pFixup, &fixupOldSignature, sizeof (FIXUP32)); pFixup->szDescription = "old signature"; pFixup->pNext = pFixupHead; pFixupHead = pFixup; } // Make room for new signature pFixup = new FIXUP32; memset (pFixup, 0, sizeof (*pFixup)); pFixup->pNext = pFixupHead; pFixupHead = pFixup; pFixup->ib = cb; pFixup->cb = 0; pFixup->cbNew = fixupSignature.cb; pFixup->pv = malloc (pFixup->cbNew); pFixup->szDescription = "signature"; memset (pFixup->pv, 0, pFixup->cbNew); // printf ("@perform fixups\n"); report_fixups (pFixupHead); // Perform fixups unsigned32 cbNew = fixup_fixups32 (pFixupHead) + cb; fixup_elf32_header (hdr, hdrOld, pFixupHead); if (_v (hdr.cEntryProgram)) fixup_elf32_programs (hdrOld, rgProgram, rgProgramOld, pFixupHead); fixup_elf32_sections (hdrOld, rgSection, rgSectionOld, pFixupHead); // report_fixups (pFixupHead); sectionSig.ib = pFixupHead->ibNew; sectionSig.cb = pFixupHead->cbNew; // printf ("@rewrite\n"); report_fixups (pFixupHead); // Rewrite size_t cbWritten = 0; unsigned32 ib = 0; unsigned32 ibFile = 0; while (ib < cbNew) { FIXUP32* pFixupNext = NULL; for (pFixup = pFixupHead; pFixup; pFixup = pFixup->pNext) if (pFixup->ibNew >= ib && (pFixupNext == NULL || pFixup->ibNew < pFixupNext->ibNew)) pFixupNext = pFixup; unsigned32 cbWrite; if (pFixupNext && pFixupNext->ibNew == ib) { // report_fixup (pFixupNext); cbWrite = write (fh, pFixupNext->pv, pFixupNext->cbNew); if (cbWrite != pFixupNext->cbNew) { cbWritten = (size_t) -1; break; } ibFile += pFixupNext->cb; } else { size_t cb = (pFixupNext ? pFixupNext->ibNew : cbNew) - ib; // printf ("%8ld l%8d->%8ld from file\n", ibFile, cb, ib + cb); cbWrite = write (fh, pb + ibFile, cb); if (cbWrite != cb) { cbWritten = (size_t) -1; break; } ibFile += cb; } cbWritten += cbWrite; ib += cbWrite; } // Cleanup free (rgbSectionNames); // *** FIXME: release fixups and sections and program fixupSignature = *pFixupHead; fixupSignature.pv = 0; assert (pFixupHead && pFixupHead->pv); free (pFixupHead->pv); while (pFixupHead) { pFixup = pFixupHead; pFixupHead = pFixup->pNext; delete pFixup; } return cbWritten; } bsign-0.4.5/exec.cxx0100660000175000017500000001166707420747134012412 0ustar elfelf/* exec.cxx $Id: exec.cxx,v 1.7 2002/01/15 06:38:20 elf Exp $ written by Oscar Levi 8 December 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (C) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- Support for executing a child process and managing IO streams for that child. */ #include "standard.h" #include "exec.h" #include "sys/types.h" #include "sys/wait.h" #include "sys/time.h" #include "errno.h" int ExStream::exec (const char* szCommand, ExStream** rgpexs, int cStream) { // extern bool g_fDebug; // if (g_fDebug) // fprintf (stderr, "execute: '%s'\n", szCommand); #if 0 for (int i = 0; i < cStream; ++i) { ExStream& exs = *rgpexs[i]; fprintf (stderr, "%sing %d %d\n", exs.m_fWrite ? "writ" : "read", exs.m_rgfd[0], exs.m_rgfd[1]); } #endif int pid = fork (); int status = 0; // Child's exit status if (pid == 0) { // Child for (int i = 0; i < cStream; ++i) { // Perform redirection ExStream& exs = *rgpexs[i]; if (exs.m_fdTarget != -1) { // fprintf (stderr, "%d: child closing %d\n", i, exs.m_fdTarget); close (exs.m_fdTarget); // fprintf (stderr, "%d: child duping %d to %d\n", i, // exs.fd_child (), exs.m_fdTarget); int result = dup2 (exs.fd_child (), exs.m_fdTarget); // if (result == -1) // fprintf (stderr, "dup2 failed %d %d\n", result, errno); // fprintf (stderr, "%d: child closing %d\n", i, exs.fd_child ()); close (exs.fd_child ()); } // fprintf (stderr, "%d: child closing parent's %d\n", i, exs.fd_parent ()); close (exs.fd_parent ()); } // sleep (1); // fprintf (stderr, "child command '%s'\n", szCommand); int result = execl ("/bin/sh", "sh", "-c", szCommand, NULL); fprintf (stderr, "child terminated unexpectedly result %d errno %d\n", result, errno); _exit (127); // *** FIXME, why this constant? } else { // Parent // sleep (1); for (int i = 0; i < cStream; ++i) { // Make everything non-block ExStream& exs = *rgpexs[i]; // fprintf (stderr, "parent O_NONBLOCKING %d\n", exs.fd_parent ()); fcntl (exs.fd_parent (), F_SETFL, O_NONBLOCK); // fprintf (stderr, "parent closing %d\n", exs.fd_child ()); close (exs.fd_child ()); } bool fQuitChild = false; bool fQuitIO = false; while (!fQuitChild || !fQuitIO) { fd_set fdsetRead; FD_ZERO (&fdsetRead); fd_set fdsetWrite; FD_ZERO (&fdsetWrite); int n = 0; // Highest numbered descriptor for select for (int i = 0; i < cStream; ++i) { // Make everything non-block ExStream& exs = *rgpexs[i]; if (!exs.is_active ()) continue; FD_SET (exs.fd_parent (), exs.m_fWrite ? &fdsetWrite : &fdsetRead); if (exs.fd_parent () > n) n = exs.fd_parent (); } // Work the fd's until we kenna do it no more struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; // 1/10th of a second int result = select (n + 1, &fdsetRead, &fdsetWrite, NULL, &tv); if (result == 0 && fQuitChild) fQuitIO = true; for (int i = 0; i < cStream; ++i) { // Make everything non-block ExStream& exs = *rgpexs[i]; if (FD_ISSET (exs.fd_parent (), exs.m_fWrite ? &fdsetWrite : &fdsetRead)) { if (exs.m_fWrite) { int cb = write (exs.fd_parent (), exs.m_pb + exs.m_cbUsed, exs.m_cb - exs.m_cbUsed); // fprintf (stderr, "parent writing to %d (%d bytes)\n", // exs.fd_parent (), cb); exs.m_cbUsed += cb; if (exs.m_cb == exs.m_cbUsed) { // fprintf (stderr, "parent closing to %d (EOF)\n", // exs.fd_parent ()); close (exs.fd_parent ()); } } else { int cb = read (exs.fd_parent (), exs.m_pb + exs.m_cbUsed, exs.m_cb - exs.m_cbUsed); // fprintf (stderr, "parent reading from %d (%d bytes, %d total)\n", // exs.fd_parent (), cb, exs.m_cbUsed + cb); exs.m_cbUsed += cb; if (cb == 0) exs.m_fClosed = true; } } } if (waitpid (pid, &status, WNOHANG) == pid) { fQuitChild = true; // fprintf (stderr, "child exited with status 0x%x (%d)\n", // status, status); status = WEXITSTATUS (status); } } // while } return status; } bsign-0.4.5/exec.h0100660000175000017500000000562106634411316012024 0ustar elfelf/* exec.h -*- C++ -*- $Id: exec.h,v 1.3 1998/12/12 06:53:02 elf Exp $ written by Oscar Levi 8 Dec 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- */ #if !defined (__EXEC_H__) # define __EXEC_H__ /* ----- Includes */ /* ----- Globals */ class ExStream { protected: int m_rgfd[2]; // File descriptors for stream read/write bool m_fWrite; // true: parent will use write fd int m_fdTarget; // Target fd for application, -1 for none char* m_pb; // Pointer to read/write data size_t m_cb; // Length of pb buffer size_t m_cbUsed; // Bytes read or written on stream bool m_fClosed; // Closed on other end public: ExStream () { zero (); } void zero (void) { memset (this, 0, sizeof (*this)); m_fdTarget = -1; } ~ExStream () { release_this (); } void release_this (void) { if (m_rgfd[0]) close (m_rgfd[0]); m_rgfd[0] = 0; if (m_rgfd[1]) close (m_rgfd[1]); m_rgfd[1] = 0; } bool is_active (void) { return !m_fClosed && m_cbUsed < m_cb; } size_t used (void) { return m_cbUsed; } bool for_reading (char* pb, size_t cb) { // From parent perspective if (pipe (m_rgfd)) return false; m_pb = pb; m_cb = cb; m_fWrite = false; return true; } bool for_writing (const char* pb, size_t cb) { // From parent perspective if (pipe (m_rgfd)) return false; m_pb = (char*) pb; m_cb = cb; m_fWrite = true; return true; } bool for_stdin (const char* pb, size_t cb) { return for_writing (pb, cb) && (m_fdTarget = 0, true); } bool for_stdout (char* pb, size_t cb) { return for_reading (pb, cb) && (m_fdTarget = 1, true); } bool for_stderr (char* pb, size_t cb) { return for_reading (pb, cb) && (m_fdTarget = 2, true); } int fd_read (void) { return m_rgfd[0]; } int fd_write (void) { return m_rgfd[0]; } int fd_child (void) { return m_rgfd[m_fWrite ? 0 : 1]; } int fd_parent (void) { return m_rgfd[m_fWrite ? 1 : 0]; } static int exec (const char* szCommand, ExStream** rgpexs, int cStream); }; #endif /* __EXEC_H__ */ bsign-0.4.5/exitstatus.cxx0100660000175000017500000000127507421163102013661 0ustar elfelf/* exitstatus.cxx $Id: exitstatus.cxx,v 1.2 2002/01/16 02:32:34 elf Exp $ written by Oscar Levi 23 May 1999 Copyright (C) 1999 The Buici Company ----------- DESCRIPTION ----------- */ #include "standard.h" #include "exitstatus.h" #include char g_szExitStatus[256]; eExitStatus g_exitStatus; // Return code for the program void set_exitstatus (eExitStatus exitStatus, const char* sz, ...) { g_exitStatus = exitStatus; if (sz) { va_list ap; va_start (ap, sz); vsnprintf (g_szExitStatus, sizeof (g_szExitStatus), sz, ap); va_end (ap); } else g_szExitStatus[0] = 0; } void set_exitstatus_reported (void) { g_szExitStatus[0] = 0; } bsign-0.4.5/exitstatus.h0100660000175000017500000000372007425630077013321 0ustar elfelf/* exitstatus.h $Id: exitstatus.h,v 1.8 2002/01/29 23:29:03 elf Exp $ written by Oscar Levi 12 Dec 1998 */ #if !defined (__EXITSTATUS_H__) # define __EXITSTATUS_H__ /* ----- Includes */ /* ----- Globals */ // Application result codes. Note that I will use // errno values for the codes that coincide with that // set, but I cannot reserve all of them since the // result code for a program is only one byte and I'd // like to keep these numbers in the low-half of the range. typedef enum { noerror = 0, // success; expected result permissiondenied = 1, // insufficient priviledge for operation filenotfound = 2, // specified file not found nomemory = 12, // memory allocation failed (may never be used) isdirectory = 21, // argument is a directory and must not be invalidargument = 22, // invalid command line argument toomanyopenfiles = 24, // pipe call failed filebusy = 26, // unable to rewrite file as it is in use nospace = 28, // output device full, no space for new file nametoolong = 36, // pathname too long nohash = 64, // hash missing and was expected nosignature = 65, // signature missing and was expected badhash = 66, // hash failed verification badsignature = 67, // signature failed verification unsupportedfiletype = 68, // type of file not (yet) supported badpassphrase = 69, // passphrase given to gpg was incorrect rewritefailed = 70, // error rewriting quit = 71, // premature application termination programnotfound = 72, // exec failed because program wasn't found } eExitStatus; extern eExitStatus g_exitStatus; extern char g_szExitStatus[256]; /* Exit status error message */ inline bool is_exitstatus (void) { return g_exitStatus || g_szExitStatus[0] != 0; } inline bool is_exitstatus_reported (void) { return g_szExitStatus[0] == 0; } void set_exitstatus (eExitStatus, const char* sz = NULL, ...); void set_exitstatus_reported (void); #endif /* __EXITSTATUS_H__ */ bsign-0.4.5/files.cxx0100660000175000017500000001061307421467035012556 0ustar elfelf/* files.cxx $Id: files.cxx,v 1.11 2002/01/17 06:24:29 elf Exp $ written by Oscar Levi 10 December 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (C) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- Simple routines for manipulating files in the filesystem. */ #include "standard.h" #include "sys/stat.h" #include "sys/types.h" #include "limits.h" #include "utime.h" #include "errno.h" #include "files.h" /* dup_status copies the status of one file to another. This is meant to replicate the ownership and permissions of the file. When chmod is before chown and we are attempting to set the setuid bit, the chown call clears that bit. Transposing these calls makes it work properly. */ bool dup_status (const char* szFileNew, const char* szFile) { struct stat st; if (::stat (szFile, &st)) return false; struct utimbuf t; t.actime = st.st_atime; t.modtime = st.st_mtime; if (utime (szFileNew, &t)) return false; if (chown (szFileNew, st.st_uid, st.st_gid)) return false; if (chmod (szFileNew, st.st_mode)) return false; return true; } #if 0 /* is_file returns true if the named file is a regular file or a link to a regular file. */ bool is_file (const char* szPath) { struct stat st; memset (&st, 0, sizeof (struct stat)); if (stat (szPath, &st)) return false; return S_ISREG (st.st_mode); } /* is_symlink returns true of the last component of szPath is a symbolic link. Directory components that are symbolic links are not detected. */ bool is_symlink (const char* szPath) { struct stat st; memset (&st, 0, sizeof (struct stat)); if (lstat (szPath, &st)) return false; return S_ISLNK (st.st_mode); } #endif char* path_of (const char* szPathOriginal) { char* sz = resolve_link (szPathOriginal); if (!sz) { // No link to resolve sz = new char [strlen (szPathOriginal) + 3]; strcpy (sz, szPathOriginal); } char* pch = rindex (sz, '/'); if (!pch) { strcpy (sz, "."); return sz; } *pch = 0; return sz; } char* resolve_link (const char* szPathOriginal) { if (!szPathOriginal || !*szPathOriginal || strlen (szPathOriginal) >= PATH_MAX) return NULL; static char szPath[PATH_MAX]; strcpy (szPath, szPathOriginal); struct stat st; // Find where the link really points do { memset (&st, 0, sizeof (struct stat)); if (lstat (szPath, &st)) return NULL; if (S_ISLNK (st.st_mode)) { static char sz[PATH_MAX + 1]; int cb = readlink (szPath, sz, sizeof (sz) - 1); if (cb == -1) return NULL; sz[cb] = 0; if (*sz == '/') // Absolute path link strcpy (szPath, sz); else { // Relative path link if (strlen (szPath) + strlen (sz) >= PATH_MAX) return NULL; char* pch = rindex (szPath, '/'); strcpy (pch ? (pch + 1) : szPath, sz); } } } while (S_ISLNK (st.st_mode)); char* sz = new char[strlen (szPath) + 1]; strcpy (sz, szPath); return sz; } /* replace_file function for replacing the old file with the new one. Because we create our temporary output file in the same directory as the output target, it is extremely improbably that we will not be able to replace the old file with the new. This function guarantees that at no time will the old file be deleted before the new file replaces it. */ bool replace_file (const char* szFileOutputOriginal, const char* szFile) { char* szFileOutput = resolve_link (szFileOutputOriginal); if (!szFileOutput) // Link resolution error return false; int result = rename (szFile, szFileOutput); // One step replacement free (szFileOutput); return result == 0; } bsign-0.4.5/files.h0100660000175000017500000000263207421156317012203 0ustar elfelf/* files.h -*- C++ -*- $Id: files.h,v 1.7 2002/01/16 01:52:15 elf Exp $ written by Oscar Levi 10 Dec 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- */ #if !defined (__FILES_H__) # define __FILES_H__ /* ----- Includes */ /* ----- Globals */ bool dup_status (const char* szFileNew, const char* szFile); //bool is_file (const char* szPath); //bool is_symlink (const char* szPath); char* path_of (const char* szPath); bool replace_file (const char* szFileOutput, const char* szFile); char* resolve_link (const char* szPathOriginal); #endif /* __FILES_H__ */ bsign-0.4.5/filewalk.cc0100660000175000017500000001433307421423524013033 0ustar elfelf/* filewalk.cc $Id: filewalk.cc,v 1.6 2002/01/17 01:22:28 elf Exp $ written by Marc Singer 14 Jan 2002 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 2002 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------- DESCRIPTION ----------- Wrapper for FTS. Memory Allocation ----------------- With respect to memory, there are memory leaks in the code. Before getting excited, think about how this code is used. While we free the memory allocated for FileWalk::rgsz, there is little reason to do so. The memory leak is bounded by the fact that the program processes a single list of files and terminates. On termination, all memory is returned to the operating system. But there is a more compelling reason for the leak. While we could reallocate memory for every string that is passed to FileWalk, nearly every string that is passed in will come from the command line and, therefore, already be available for the duration of the program. In the one case where we allocate memory, there is no efficient way to mark which items were allocated and which were not, so we cannot easily know which to free. In the end, the memory allocation policy is consistent with proper execution of the program. */ #include "standard.h" #include "filewalk.h" /* append_to_list adds the given string to the array (list) of strings. The pointer is stored as it without being copied. Be warned. Callers passing pointers that are volatile will cause unpredictable behavior. */ void append_to_list (FileWalk::List& list, const char* sz) { // Make room, leave a NULL at end if (list.cUsed + 1 >= list.cMax) { int cNew = list.cMax + 20; char** rgsz = new char*[cNew]; bzero (rgsz, sizeof (char*)*cNew); if (list.cUsed) { bcopy (list.rgsz, rgsz, sizeof (char*)*list.cUsed); delete list.rgsz; } list.rgsz = rgsz; list.cMax = cNew; } // Store new string int cch = strlen (sz); char* szNew = new char[cch + 1]; strcpy (szNew, sz); list.rgsz[list.cUsed++] = szNew; } void release_list (FileWalk::List& list) { if (list.cMax) { delete list.rgsz; list.rgsz = 0; list.cMax = 0; } } void FileWalk::exclude (const char* sz) { // Cope with terminating, superfluous trailing / int cch = strlen (sz); if (cch > 1 && sz[cch - 1] == '/') { char* szNew = new char [cch + 1]; strcpy (szNew, sz); szNew[cch - 1] = 0; sz = (const char*) szNew; } append_to_list (m_listExclude, sz); } void FileWalk::include (const char* sz) { append_to_list (m_listInclude, sz); } void FileWalk::insert (const char* sz) { append_to_list (m_listInsert, sz); } /* FileWalk::is_only_one returns true if there is one and only one file to enumerate. Since some of the enumeration methods cannot guarantee that condition a priori, it returns true only when this condition is guaranteed. */ bool FileWalk::is_only_one (void) { return is_ready () && m_listInsert.cUsed == 1; } /* FileWalk::is_ready returns true if this object is ready for enumeration. We permit one and only one method of specifying the files to enumerate. */ bool FileWalk::is_ready (void) { int c = 0; if (m_listInsert.cUsed) ++c; if (m_listInclude.cUsed) ++c; if (m_szPathSource) ++c; return (c == 1); } bool FileWalk::is_excluded (void) { for (int i = 0; i < m_listExclude.cUsed; ++i) if (strcmp (m_pent->fts_path, m_listExclude.rgsz[i]) == 0) return true; return false; } /* FileWalk::next and variants these functions perform the enumeration. There are three variants depending on the way that this object was initialized. */ const char* FileWalk::next (void) { const char* sz = NULL; m_pStat = NULL; if (m_listInsert.cUsed) sz = next_insert (); if (m_listInclude.cUsed) sz = next_fts (); if (m_szPathSource) sz = next_source (); return m_szFileCurrent = sz; } const char* FileWalk::next_insert (void) { if (m_cCurrent + 1 >= m_listInsert.cUsed) return NULL; const char* sz = m_listInsert.rgsz[++m_cCurrent]; if (sz && ::stat (sz, &m_stat) == 0) m_pStat = &m_stat; return sz; } const char* FileWalk::next_fts (void) { if (!m_pfts) m_pfts = fts_open (m_listInclude.rgsz, FTS_PHYSICAL // | FTS_NOSTAT | FTS_NOCHDIR , NULL); if (!m_pfts) return NULL; // *** FIXME: error condition? do { m_pent = fts_read (m_pfts); if (m_pent && m_pent->fts_info == FTS_D && is_excluded ()) fts_set (m_pfts, m_pent, FTS_SKIP); } while (m_pent && m_pent->fts_info != FTS_F); if (m_pent) m_pStat = m_pent->fts_statp; return m_pent ? m_pent->fts_path : NULL; } const char* FileWalk::next_source (void) { if (m_fp) { m_fp = stdin; if (strcmp (m_szPathSource, "-")) m_fp = fopen (m_szPathSource, "r"); } if (m_fp) return NULL; // Read a filename m_szFilename[0] = 0; while (!feof (m_fp)) { fgets (m_szFilename, sizeof (m_szFilename), m_fp); int cch = strlen (m_szFilename); if (cch == 0) continue; if (m_szFilename[cch - 1] == '\n') m_szFilename[cch - 1] = 0; } if (m_szFilename[0] && ::stat (m_szFilename, &m_stat) == 0) m_pStat = &m_stat; return m_szFilename[0] ? m_szFilename : NULL; } void FileWalk::release_this (void) { release_list (m_listInclude); release_list (m_listExclude); release_list (m_listInsert); if (m_pfts) { fts_close (m_pfts); m_pfts = NULL; } if (m_fp) { fclose (m_fp); m_fp = NULL; } } bsign-0.4.5/filewalk.h0100660000175000017500000000616207421662225012701 0ustar elfelf/* filewalk.h -*- C++ -*- $Id: filewalk.h,v 1.6 2002/01/17 23:56:05 elf Exp $ written by Marc Singer 14 Jan 2002 This file is part of the project BSIGN. See the file README for more information. Copyright (C) 2002 The Buici Company This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------- DESCRIPTION ----------- A wrapper around FTS with support for inclusion and exclusion. It is important to note that the include, exclude and insert functions accept and store character pointers without copying the data. This is because the intended use is with parsing command line arguments. Callers that cannot cope with this must copy strings before passing them to FileWalk. */ #if !defined (__FILEWALK_H__) # define __FILEWALK_H__ /* ----- Includes */ #include /* glibc2 header, required */ #include #include /* ----- Types */ class FileWalk { public: typedef struct { int cMax; int cUsed; char** rgsz; } List; protected: const char* m_szFileCurrent; struct stat* m_pStat; struct stat m_stat; // Stat buffer when we need one // --- FTS enumeration FTS* m_pfts; // Pointer to fts object FTSENT* m_pent; // Pointer to last returned file object List m_listInclude; // Funky list used to include roots List m_listExclude; // Funky list used to exclude // --- Explicit enumeration List m_listInsert; // Funky list used to store explicit pathnames int m_cCurrent; // Index of this current item in inserted list // --- File source enumeration const char* m_szPathSource; // Read filenames from a file FILE* m_fp; // Buffered I/O handle for reading filenames char m_szFilename[PATH_MAX + 1]; // Last read filename bool is_excluded (void); void release_this (void); void zero (void) { bzero (this, sizeof (*this)); m_cCurrent = -1; } const char* next_insert (void); const char* next_fts (void); const char* next_source (void); public: FileWalk () { zero (); } ~FileWalk () { release_this (); } void exclude (const char* sz); void include (const char* sz); void insert (const char* sz); void source (const char* szPath) { m_szPathSource = szPath; } bool is_ready (void); bool is_only_one (void); const char* next (void); const char* current (void) { return m_szFileCurrent; } struct stat* stat (void) { return m_pStat; } }; /* ----- Globals */ /* ----- Prototypes */ #endif /* __FILEWALK_H__ */ bsign-0.4.5/install-sh0100660000175000017500000001430206631357462012734 0ustar elfelf#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # 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 M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" # CYGNUS LOCAL: exeext variable exeext="" # END CYGNUS LOCAL while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; # CYGNUS LOCAL: -x option -x=*) exeext=`echo $1 | sed 's/-x=//'` shift continue;; -x) exeext=".exe" shift continue;; # END CYGNUS LOCAL *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # CYGNUS LOCAL noer # Win32-based gcc automatically appends .exe to produced executables, # whether asked for or not. This breaks installs. The following # changes the value of $src to $src.exe if $src is missing if [ -f $src ] then true elif [ -f $src.exe ] then echo "install: $src does not exist, trying with .exe appended" src="$src".exe fi # end CYGNUS LOCAL noer # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi # CYGNUS LOCAL: Use exeext case "`basename $dst`" in *.*) ;; *) dst="$dst$exeext" ;; esac # END CYGNUS LOCAL fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 bsign-0.4.5/main.cxx0100660000175000017500000004333307425630077012407 0ustar elfelf/* main.cxx $Id: main.cxx,v 1.43 2002/01/29 23:29:03 elf Exp $ written by Oscar Levi 1 December 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (c) 1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* ----- Includes */ #include "standard.h" #define DECLARE_VERSION #include "version.h" #include #include //#include #include #include "bsign.h" #include "options.h" #include "files.h" #include "exitstatus.h" #include "filewalk.h" extern "C" void sha_memory(void*, unsigned32, unsigned32*); /* ----- Class Globals/Statics */ int g_fPalette; int g_fSymbols; int g_fSections; int g_fDetail; int g_fSign; // !0: hash & sign files int g_fHash; // !0: hash files instead, 0: check signature bool g_fExpectSignature; // !0: check for signature as well as hash bool g_fProcessedFile; // Set when we do something bool g_fInverseResult; // Negate result for benefit of find program int g_fNoSymLinks; // Treat symlinks as invalid file format int g_fQuiet; // Inhibit messages, return code only int g_fDebug; // Show debug messages int g_fVerbose; // Verbose reports int g_fIgnore; // Ignore directories and non-ELF in error msgs int g_fHideGoodSigs; // Hide files with good signatures from output int g_fSummary; // Show processing summary at end int g_fForceResign; // Resign files that are already signed const char* g_szOutput; // Name of output file const char* g_szFileList; // Name of file containing file list const char* g_szPGOptions; // Options to pass to privacy guard program FileWalk g_filewalk; // Global file walking object char* g_szPathTempHash; // Pointer to temporary filename for hashing int g_cFilesProcessed; // Total files processed int g_cFilesSkipped; // Number of files skipped because irrelevent int g_cFilesInaccessible; // Number of files that could not be read int g_cFilesGood; // Number of files with good hash/signature int g_cFilesBad; // Number of files with bad hash/signature const char* g_szApplication; // Name of application void setup_signals (void); int do_filename (OPTION* pOption, const char* pch); int do_files (OPTION* pOption, const char* pch); int do_unrecognized (OPTION*, const char*); int do_usage (OPTION*, const char*); int do_version (OPTION*, const char*); int do_hash (OPTION*, const char*); int do_sign (OPTION*, const char*); int do_check (OPTION*, const char*); int do_unsigned (OPTION*, const char*); int do_verify (OPTION*, const char*); int do_include (OPTION*, const char*); int do_exclude (OPTION*, const char*); void process_files (void); // the execution routine OPTION rgOptions[] = { { "sign", 0, NULL, do_sign }, { "s", 0, NULL, do_sign }, { "hash", 0, NULL, do_hash }, { "H", 0, NULL, do_hash }, { "unsigned", 0, NULL, do_unsigned }, { "quiet", OPTION_F_SET_INT, &g_fQuiet }, { "q", OPTION_F_SET_INT, &g_fQuiet }, { "debug", OPTION_F_SET_INT, &g_fDebug }, { "d", OPTION_F_SET_INT, &g_fDebug }, { "checkhash", 0, NULL, do_check }, { "c", 0, NULL, do_check }, { "nosymlinks", OPTION_F_SET_INT, &g_fNoSymLinks }, { "verbose", OPTION_F_SET_INT, &g_fVerbose }, { "v", OPTION_F_SET_INT, &g_fVerbose }, { "verify", 0, NULL, do_verify }, { "V", 0, NULL, do_verify }, { "output", OPTION_F_SET_STRING | OPTION_F_ARGUMENT, &g_szOutput }, { "o", OPTION_F_SET_STRING | OPTION_F_ARGUMENT, &g_szOutput }, { "pgoptions", OPTION_F_SET_STRING | OPTION_F_ARGUMENT, &g_szPGOptions }, { "P", OPTION_F_SET_STRING | OPTION_F_ARGUMENT, &g_szPGOptions }, { "files", OPTION_F_ARGUMENT, NULL, do_files }, { "f", OPTION_F_ARGUMENT, NULL, do_files }, { "ignore-unsupported", OPTION_F_SET_INT, &g_fIgnore }, { "I", OPTION_F_SET_INT, &g_fIgnore }, { "include", OPTION_F_ARGUMENT, NULL, do_include }, { "i", OPTION_F_ARGUMENT, NULL, do_include }, { "exclude", OPTION_F_ARGUMENT, NULL, do_exclude }, { "e", OPTION_F_ARGUMENT, NULL, do_exclude }, { "hide-good-sigs", OPTION_F_SET_INT, &g_fHideGoodSigs }, { "G", OPTION_F_SET_INT, &g_fHideGoodSigs }, { "summary", OPTION_F_SET_INT, &g_fSummary }, { "S", OPTION_F_SET_INT, &g_fSummary }, { "force-resign", OPTION_F_SET_INT, &g_fForceResign }, { "help", 0, NULL, do_usage }, { "h", 0, NULL, do_usage }, { "version", 0, NULL, do_version }, { "V", 0, NULL, do_version }, { "", OPTION_F_NONOPTION, NULL, do_filename }, { "", OPTION_F_DEFAULT, NULL, do_unrecognized }, { NULL }, }; /* ----- Methods */ /* cleanup_temp_hash function to remove the temporary used during verification. Until we can verify without writing the data to disk, this is the best we can do. This function is so declared because it is called from the signal handlers. */ void cleanup_temp_hash (bool fSignal) { if (g_szPathTempHash) { int result = unlink (g_szPathTempHash); // if (result == 0 && fSignal) // fprintf (stderr, "unlinked temp %s\n", g_szPathTempHash); } if (!fSignal) { char* sz = g_szPathTempHash; g_szPathTempHash = NULL; // Prevent signal handler conflict delete sz; } } int do_check (OPTION* /* pOption */, const char* /* pch */) { g_fSign = g_fHash = false; g_fExpectSignature = false; g_fInverseResult = false; return 0; } /* do_unsigned exit 0 for signed and !1 for unsigned binaries. */ int do_unsigned (OPTION*, const char*) { g_fSign = g_fHash = false; g_fExpectSignature = true; g_fInverseResult = true; return 0; } int do_verify (OPTION* /* pOption */, const char* /* pch */) { g_fSign = g_fHash = false; g_fExpectSignature = true; g_fInverseResult = false; return 0; } int do_sign (OPTION* /* pOption */, const char* /* pch */) { g_fSign = true; g_fHash = true; g_fInverseResult = false; return 0; } int do_hash (OPTION* /* pOption */, const char* /* pch */) { g_fSign = false; g_fHash = true; g_fInverseResult = false; return 0; } int do_files (OPTION* pOption, const char* pch) { g_filewalk.source (pch); return 0; } int do_filename (OPTION* pOption, const char* pch) { g_filewalk.insert (pch); // Add to list of files to process return 0; } int do_include (OPTION*, const char* pch) { g_filewalk.include (pch); return 0; } int do_exclude (OPTION*, const char* pch) { g_filewalk.exclude (pch); return 0; } int do_unrecognized (OPTION* /* pOption */, const char* pch) { fprintf (stderr, "%s: unrecognized option '%s'\n", g_szApplication, pch); fprintf (stderr, "Try '%s --help' for usage information.\n", g_szApplication); g_exitStatus = invalidargument; return 1; } /* do_unrecognized */ int do_usage (OPTION*, const char*) { fprintf (stderr, "%s version %s\n" "usage: %s [options] [ [options] ... ]\n" " -c, --checkhash Check hash (*)\n" " -d, --debug Show debug messages\n" " -f, --files FILE Process filenames in FILE, one per line. " "- for stdin\n" " -G, --hide-good-sigs Do not report when good signatures are found\n" " -H, --hash Rewrite files with hash only\n" " -I, --ignore-unsupported\n" " Ignore directories and non-ELF files in error " "messages\n" " --nosymlinks Treat symlinks as an unsupported file type\n" " -i, --include PATH add PATH to the list of paths to enumerate\n" " -e, --exclude PATH add PATH to the list of paths to exclude\n" " -o, --output FILE Save new version to FILE\n" " -P, --pgoptions OPTS Pass OPTS string to the privacy guard program\n" " -q, --quiet Inhibit messages, call must rely on exit status\n" " --force-resign Force new signatures for already signed files\n" " -s, --sign Rewrite files with hash and signature\n" " -S, --summary Print processing summary after last input file\n" " -v, --verbose Be verbose in reporting program state\n" " -V, --verify Verifies the signature\n" " --version Display version and copyright\n" " -h, --help Usage message\n" " (*) Default option\n" "\n" "There are three ways to specify files to process. Filenames may appear\n" "on the command line. The --files switch accepts the name of a file\n" "containing a list of files to process. The --include and --exclude\n" "options define paths to enumerate and paths exclude. Only one of these\n" "methods may be used in a single invocation.\n\n" "The simplest invocation that will sign all files and exclude the /proc\n" "directory is this.\n\n" " bsign -s -I -i / -e /proc\n\n" , g_szApplication, g_szVersion, g_szApplication); return 1; } /* do_usage */ int do_version (OPTION*, const char*) { fprintf (stdout, "%s\n", g_szVersion); return 1; } /* do_version */ void process_files (void) { const char* pch; while (pch = g_filewalk.next ()) { int fh = -1; // char* szFileNew = NULL; int fhNew = -1; char* pbMap = (char*) -1; long cb = 0; struct stat& stat = *g_filewalk.stat (); char rgb[size_elf_header ()]; bool fElf = false; if (g_filewalk.stat () == NULL) { set_exitstatus (filenotfound, "unable to stat file '%s'", pch); goto do_filename_done; } set_exitstatus (noerror); g_fProcessedFile = true; ++g_cFilesProcessed; if (!S_ISREG (stat.st_mode)) { set_exitstatus (unsupportedfiletype, "unable to process non-regular file '%s'", pch); goto do_filename_done; } fh = open (pch, O_RDONLY); // printf ("do_filename: '%s'\n", pch); if (fh == -1) { switch (errno) { case EACCES: set_exitstatus (permissiondenied, "insufficient priviledge to open file '%s'", pch); ++g_cFilesInaccessible; break; default: set_exitstatus (filenotfound, "file not found '%s' %d", pch, errno); break; } goto do_filename_done; } // fprintf (stderr, "fh %d\n", fh); if ((g_fSign | g_fHash) && (g_fNoSymLinks && S_ISLNK (stat.st_mode))) { set_exitstatus (unsupportedfiletype, "ignoring symbolic link '%s'", pch); ++g_cFilesSkipped; goto do_filename_done; } if (!(cb = stat.st_size)) { set_exitstatus (unsupportedfiletype, "empty file '%s'", pch); ++g_cFilesSkipped; goto do_filename_done; } if (cb >= size_elf_header ()) { fElf = is_elf_header (rgb, read (fh, rgb, size_elf_header ())); lseek (fh, SEEK_SET, 0); } // *** FIXME: at the moment, we only work with ELF format files. // This test is here in order to avoid mmap'ing the file // unnecessarily. if (!fElf) { set_exitstatus (unsupportedfiletype, "file '%s' is not ELF", pch); ++g_cFilesSkipped; goto do_filename_done; } // Open temporary file if (g_fSign | g_fHash) { char* szPath = path_of (g_szOutput ? g_szOutput : pch); // printf ("path_of '%s'\n", szPath); char* szFileNew = new char [strlen (szPath) + 32]; strcpy (szFileNew, szPath); strcat (szFileNew, "/bsign.XXXXXX"); g_szPathTempHash = szFileNew; // Permit signal cleanup fhNew = mkstemp (szFileNew); delete szPath; // printf ("fhNew %d\n", fhNew); if (fhNew == -1) { szPath = path_of (g_szOutput ? g_szOutput : pch); set_exitstatus (permissiondenied, "unable to create file in '%s' for '%s'", szPath, pch); delete szPath; ++g_cFilesInaccessible; goto do_filename_done; } // printf ("opened '%s'\n", szFileNew); } if ((pbMap = (char*) mmap (NULL, cb, PROT_READ, MAP_FILE | MAP_PRIVATE, fh, 0)) == (caddr_t) -1) { set_exitstatus (permissiondenied, "unable to mmap '%s'", pch); goto do_filename_done; } if (g_fSign && !g_fForceResign && is_elf_signed (pbMap, cb, NULL, NULL)) { set_exitstatus (noerror, "Skipping already signed file"); ++g_cFilesSkipped; goto do_filename_done; } if (g_fSign || g_fHash) { if (is_elf (pbMap, cb)) { if (g_fVerbose) fprintf (stdout, "%s\n", pch); switch (g_exitStatus = hash_elf (pbMap, cb, fhNew, g_fSign)) { case noerror: break; case badpassphrase: set_exitstatus (g_exitStatus, "incorrect passphrase" " or gpg not installed"); goto do_filename_done; default: set_exitstatus (g_exitStatus, "error %d while hashing '%s'", g_exitStatus, pch); goto do_filename_done; } } else { set_exitstatus (unsupportedfiletype, "file '%s' is not ELF", pch); ++g_cFilesSkipped; goto do_filename_done; } } else { // check only if (!is_elf (pbMap, cb)) { set_exitstatus (unsupportedfiletype, "file '%s' is not ELF", pch); ++g_cFilesSkipped; goto do_filename_done; } if (g_fVerbose) fprintf (stdout, "%s\n", pch); switch (g_exitStatus = check_elf (pbMap, cb, g_fExpectSignature)) { case noerror: set_exitstatus (g_exitStatus, "good %s found in '%s'.", g_fExpectSignature ? "signature" : "hash", pch); ++g_cFilesGood; break; case badhash: set_exitstatus (g_exitStatus, "invalid hash in '%s'.", pch); ++g_cFilesBad; break; case badsignature: set_exitstatus (g_exitStatus, "failed to verify signature in '%s'.", pch); ++g_cFilesBad; break; case nohash: set_exitstatus (g_exitStatus, "no hash found in '%s'.", pch); ++g_cFilesBad; break; case nosignature: set_exitstatus (g_exitStatus, "no signature found in '%s'.", pch); ++g_cFilesBad; break; case programnotfound: set_exitstatus (g_exitStatus, "unable to verify signature, " "probably because gpg is not installed"); break; default: set_exitstatus (g_exitStatus, "error %d while verifying '%s'.", pch); ++g_cFilesBad; break; } } if (fhNew != -1) { close (fhNew); fhNew = -1; if (!dup_status (g_szPathTempHash, pch)) { set_exitstatus (permissiondenied, "insufficient priviledge to duplicate '%s'" " ownership", pch); ++g_cFilesInaccessible; goto do_filename_done; } if (!replace_file (g_szOutput ? g_szOutput : pch, g_szPathTempHash)) { // I'd be suprised if I ever get here. // I think that by this time, I have // already written the file in the // same directory and performed chown // to set the permissions. set_exitstatus (permissiondenied, "unable to create output file '%s'", g_szOutput ? g_szOutput : pch); ++g_cFilesInaccessible; goto do_filename_done; } } do_filename_done: if (pbMap != (caddr_t) -1) munmap (pbMap, cb); if (fhNew != -1) close (fhNew); cleanup_temp_hash (false); close (fh); if (!g_fQuiet) { if (g_fIgnore && ( g_exitStatus == isdirectory || g_exitStatus == unsupportedfiletype)) set_exitstatus_reported (); if (g_fHideGoodSigs && g_exitStatus == noerror) set_exitstatus_reported (); if (!is_exitstatus_reported ()) { fprintf (stdout, "%s: %s\n", g_szApplication, g_szExitStatus); set_exitstatus_reported (); } } // if (!g_exitStatus && g_fVerbose && pOption) // fprintf (stderr, "%s\n", pch); // return 0; // Always continue working } } /* main entry point. Note that this main is simplified to an idiom because of the options code we use. Files are processed when non-option command line arguments are found. Refer to OPTION_F_NOPTION. */ int main (int argc, char** argv) { setup_signals (); g_szApplication = parse_application (*argv); int argc_used; int result = parse_options (argc - 1, argv + 1, rgOptions, &argc_used); if (result) { switch (result) { case 1: break; default: fprintf (stderr, "parse error %d at word %d\n", result, argc_used + 1); break; } /* switch */ g_exitStatus = invalidargument; return 1; } /* if */ if (!g_filewalk.is_ready ()) set_exitstatus (invalidargument, "use only one method for specifying input files."); if (g_szOutput && !g_filewalk.is_only_one ()) set_exitstatus (invalidargument, "--output option requires one" " and only one input filename"); if (!is_exitstatus ()) process_files (); // printf ("done with args (%d)\n", result); if (!is_exitstatus () && !g_fProcessedFile) { fprintf (stdout, "No input files specified.\n"); do_usage (NULL, NULL); } // Invert OK codes when asked to do so if (g_fInverseResult) { switch (g_exitStatus) { case noerror: case unsupportedfiletype: default: g_exitStatus = filenotfound; // Anything to say 'no need to sign it' break; case nosignature: case nohash: case badhash: case badsignature: g_exitStatus = noerror; break; } } if (g_fSummary) fprintf (stdout, "Summary processed:%d skipped:%d inaccessible:%d\n" "Results succeeded:%d failed:%d\n", g_cFilesProcessed, g_cFilesSkipped, g_cFilesInaccessible, g_cFilesGood, g_cFilesBad); if (is_exitstatus () && !is_exitstatus_reported () && !g_fQuiet) fprintf (stdout, "%s: %s\n", g_szApplication, g_szExitStatus); // fprintf (stderr, "exit (%d)\n", g_exitStatus); return g_exitStatus; } /* main */ bsign-0.4.5/mkinstalldirs0100770000175000017500000000115006634633732013535 0ustar elfelf#!/bin/sh # Make directory hierarchy. # Written by Noah Friedman # Public domain. defaultIFS=' ' IFS="${IFS-${defaultIFS}}" for file in ${1+"$@"} ; do oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${file} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" test ".${1}" = "." && shift pathcomp='' while test $# -ne 0 ; do pathcomp="${pathcomp}${1}" shift if test ! -d "${pathcomp}"; then echo "mkdir $pathcomp" 1>&2 mkdir "${pathcomp}" fi pathcomp="${pathcomp}/" done done # eof bsign-0.4.5/options.cxx0100660000175000017500000002032406634411316013143 0ustar elfelf/* options.cxx $Id: options.cxx,v 1.3 1998/12/12 06:53:02 elf Exp $ written by Oscar Levi 1 December 1996 This file is part of the project BSIGN. See the file README for more information. Copyright (C) 1996,1998 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. --------------------- ABBREVIATED CHANGELOG --------------------- Option parsing and value storage. Version 0.3 (14 November 1996) Permit option arguments to be prefixed by '='. Version 0.2 (14 May 1996) Long option names prefixed by a period are interpreted without a dash. This allows command parsing as well as option parsing. Version 0.1 Short and long options. Default and error option codes. Long option prefix matching. */ /* ----- Includes */ #include "standard.h" #include "options.h" #define USE_PARTIALS // Permit partial matches for long options /* ----- Class Globals/Statics */ typedef enum { STATE_0 = 0, STATE_FOUND_DASH = 1, STATE_FOUND_DASHDASH = 2, } STATE_PARSE; typedef enum { FETCH_DEFAULT = 0, FETCH_SHORT = 1, FETCH_LONG = 2, FETCH_COMMAND = 3, } FETCH_MODE; static int eval_option (char* pch, int cch, char* pchArgument, OPTION* pOptions); static OPTION* fetch_option (char* pch, FETCH_MODE mode, OPTION* rgOptions); /* ----- Methods */ char* parse_application (char* pch) { char* pchSep = rindex (pch, '\\'); char* pchSepAlt = rindex (pch, '/'); char* pchColon = rindex (pch, ':'); char* pchDot = rindex (pch, '.'); if (pchSepAlt > pchSep) pchSep = pchSepAlt; if (pchColon > pchSep) pchSep = pchColon; pch = pchSep ? pchSep + 1 : pch; if (pchDot && strcasecmp (pch, ".exe")) *pchDot = 0; return pch; } /* parse_applications */ /* parse_options accepts the argument vector for the application and an option description array and parses the command line arguments. The return value is zero if the parse succeeds or non-zero if there was an error. */ int parse_options (int argc, char** argv, OPTION* rgOptions, int* pargc_used) { int argc_used; if (!pargc_used) pargc_used = &argc_used; int result = 0; for (; argc; --argc, ++argv, ++*pargc_used) { char* pch; int state = STATE_0; for (pch = *argv; *pch; ++pch) { OPTION* pOption; char* pchArgument = NULL; int cch; // General purpose length storage switch (state) { case STATE_0: if (*pch == '-') { state = STATE_FOUND_DASH; continue; } /* if */ if ((pOption = fetch_option (pch, FETCH_COMMAND, rgOptions))) { if ((result = eval_option (pch, strlen (pch), NULL, pOption))) return result; } /* if */ else if ((pOption = fetch_option (NULL, FETCH_DEFAULT, rgOptions))) { if ((result = eval_option (NULL, 0, pch, pOption))) return result; } /* else-if */ else return OPTION_ERR_OK; pch += strlen (pch) - 1; break; case STATE_FOUND_DASH: if (*pch == '-') { state = STATE_FOUND_DASHDASH; continue; } /* if */ pOption = fetch_option (pch, FETCH_SHORT, rgOptions); if (!pOption) return OPTION_ERR_UNRECOGNIZED; if (pOption->flags & OPTION_F_ARGUMENT) { if (*(pch + 1)) { pchArgument = pch + 1; if (*pchArgument == '=') ++pchArgument; } else if (argc > 1) { pchArgument = argv[1]; --argc; ++argv; ++*pargc_used; } /* else */ else return OPTION_ERR_NOARGUMENT; } /* if */ if ((result = eval_option (pch, 1, pchArgument, pOption))) return result; if (pchArgument) { pch += strlen (pch) - 1; state = STATE_0; } /* if */ break; case STATE_FOUND_DASHDASH: pOption = fetch_option (pch, FETCH_LONG, rgOptions); if (!pOption) return OPTION_ERR_UNRECOGNIZED; cch = strlen (pch); if (pOption->flags & OPTION_F_ARGUMENT) { int cchOption = strcspn (pch, "="); if (pch[cchOption] == '=') { pchArgument = pch + cchOption + 1; cch = cchOption; } else if (argc > 1) { pchArgument = argv[1]; --argc; ++argv; ++*pargc_used; } /* else */ else return OPTION_ERR_NOARGUMENT; } /* if */ if ((result = eval_option (pch, cch, pchArgument, pOption))) return result; pch += strlen (pch) - 1; state = STATE_0; break; } /* switch */ } /* for */ } /* for */ return OPTION_ERR_OK; } /* parse_options */ /* fetch_option accepts a pointer into a word within the command line, usually after either a single or double dash, and a mode specifier that determines which types of options it can match. It then tries to match that option string in the option data. Long options and command options will match partials if the USE_PARTIALS macro is defined. */ OPTION* fetch_option (char* pch, FETCH_MODE mode, OPTION* rgOptions) { int cch = ((mode == FETCH_SHORT) ? 1 : (pch ? strlen (pch) : 0)); if (cch) { int cchOption = strcspn (pch, "="); if (cchOption < cch) cch = cchOption; } OPTION* pOptionDefault = NULL; OPTION* pOptionPartial = NULL; for (OPTION* pOption = rgOptions; pOption && pOption->sz; ++pOption) { if ( mode == FETCH_DEFAULT && (pOption->flags & OPTION_F_DEFAULT) && !pOptionDefault) pOptionDefault = pOption; if (!pch) { if (pOption->flags & OPTION_F_NONOPTION) return pOption; continue; } /* if */ if (*pOption->sz != *pch) continue; if ( (mode == FETCH_COMMAND && !(pOption->flags & OPTION_F_COMMAND)) || (mode != FETCH_COMMAND && (pOption->flags & OPTION_F_COMMAND))) continue; if (cch == 1 && mode != FETCH_COMMAND) { if (!pOption->sz[1]) return pOption; continue; } /* if */ if (strncmp (pch, pOption->sz, cch)) continue; if (!pOption->sz[cch]) return pOption; #if defined USE_PARTIALS pOptionPartial = pOptionPartial ? (OPTION*) -1 : pOption; #endif } /* for */ return (pOptionPartial && pOptionPartial != (OPTION*) -1) ? pOptionPartial : pOptionDefault; } /* fetch_option */ /* eval_option accepts a pointer to the user's option string, a pointer to the option argument, and the fetched option pointer. */ int eval_option (char* pch, int cch, char* pchArgument, OPTION* pOption) { if (pOption->pfn) { char sz[2]; if (pOption->flags & OPTION_F_DEFAULT) { if (cch == 1) { sz[0] = *pch; sz[1] = 0; pchArgument = sz; } /* if */ else pchArgument = pch; } /* if */ return pOption->pfn (pOption, pchArgument) ? OPTION_ERR_FAIL : OPTION_ERR_OK; } /* if */ if (pOption->flags & OPTION_F_DEFAULT) { printf ("Unrecognized option '%.*s'\n", cch, pch); return OPTION_ERR_UNRECOGNIZED; } if (pOption->flags & OPTION_F_NONOPTION) return OPTION_ERR_EXIT; if ((pOption->flags & OPTION_F_SET_MASK) && pOption->pv) { long value = 1; if (pchArgument && !(pOption->flags & OPTION_F_SET_STRING)) value = strtol (pchArgument, NULL, 0); else if (pOption->flags & OPTION_F_CLEAR) value = 0; switch (pOption->flags & OPTION_F_SET_TYPE) { default: return OPTION_ERR_BADOPTION; case OPTION_F_SET_INT: *(int*) pOption->pv = int (value); break; case OPTION_F_SET_SHORT: *(short*) pOption->pv = short (value); break; case OPTION_F_SET_LONG: *(long*) pOption->pv = long (value); break; case OPTION_F_SET_STRING: *(char**) pOption->pv = pchArgument; break; } /* switch */ return OPTION_ERR_OK; } /* if */ else return OPTION_ERR_BADOPTION; } /* eval_option */ bsign-0.4.5/options.h0100660000175000017500000000453606634411316012577 0ustar elfelf/* options.h $Id: options.h,v 1.2 1998/12/12 06:53:02 elf Exp $ written by Oscar Levi 20 April 1996 This file is part of the project BSIGN. See the file README for more information. Copyright (C) 1996 Oscar Levi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __OPTIONS_H__ #define __OPTIONS_H__ // ----- Inclusions // ----- Constants // ----- Typedefs typedef enum { OPTION_F_NONOPTION = 0x0001, // Option to use for non-options OPTION_F_DEFAULT = 0x0002, // Option to use when no other found OPTION_F_ARGUMENT = 0x0004, // Option has an argument OPTION_F_COMMAND = 0x0008, // Option is a command, no dash prefix OPTION_F_SET_TYPE = 0x0f00, OPTION_F_SET_MASK = 0xff00, OPTION_F_SET_STRING = 0x0100, OPTION_F_SET_INT = 0x0200, OPTION_F_SET_SHORT = 0x0400, OPTION_F_SET_LONG = 0x0800, OPTION_F_CLEAR = 0x8000, } E_OPTION_F; typedef enum { OPTION_ERR_OK = 0, OPTION_ERR_FAIL = 1, // Option function failed OPTION_ERR_UNRECOGNIZED = 2, // Unrecognized option OPTION_ERR_NOARGUMENT = 3, // Argument missing OPTION_ERR_BADOPTION = 4, // Error in option descriptions OPTION_ERR_EXIT = 9, // Used internally for quick exit } E_OPTION_ERR; struct _OPTION; typedef int (*PFN_OPTION) (struct _OPTION* pOption, const char* pch); typedef struct _OPTION { const char* sz; // Text of option unsigned flags; void* pv; // Pointer to option result PFN_OPTION pfn; // Callback function } OPTION; // ----- Classes // ----- Macros // ----- Globals / Externals // ----- Prototypes char* parse_application (char* pch); int parse_options (int argc, char** argv, OPTION* rgOptions, int* argc_used); // ----- Inline #endif // __OPTIONS_H__ bsign-0.4.5/sha1.c0100660000175000017500000002360607421673574011745 0ustar elfelf/* sha1.c - SHA1 hash function * Copyright (C) 1998 Free Software Foundation, Inc. * * Please see below for more legal information! * * This file is part of GNUPG. It is included in BSIGN in accordance * with the licence agreement of GNUPG. It has been modified little, * only to make it compile and link with BSIGN. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Test vectors: * * "abc" * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D * * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1 */ /* elf 1 Dec 1998: slightly modified to fit the linkage model for bsign. */ /* elf 17 Jan 2002: changed test for host endian-ness for autoconf macro. */ #include "standard.h" //#include //#include //#include //#include //#include "util.h" //#include "memory.h" #include "sha1.h" #define u32 unsigned32 #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) typedef struct { u32 h0,h1,h2,h3,h4; u32 nblocks; byte buf[64]; int count; } SHA1_CONTEXT; #if defined(__GNUC__) && defined(__i386__) static inline u32 rol(int n, u32 x) { __asm__("roll %%cl,%0" :"=r" (x) :"0" (x),"c" (n)); return x; } #else #define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) ) #endif void sha1_init( SHA1_CONTEXT *hd ) { hd->h0 = 0x67452301; hd->h1 = 0xefcdab89; hd->h2 = 0x98badcfe; hd->h3 = 0x10325476; hd->h4 = 0xc3d2e1f0; hd->nblocks = 0; hd->count = 0; } /**************** * Transform the message X which consists of 16 32-bit-words */ static void transform( SHA1_CONTEXT *hd, byte *data ) { u32 a,b,c,d,e,tm; u32 x[16]; /* get values from the chaining vars */ a = hd->h0; b = hd->h1; c = hd->h2; d = hd->h3; e = hd->h4; #ifdef WORDS_BIGENDIAN memcpy( x, data, 64 ); #else { int i; byte *p2; for(i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) { p2[3] = *data++; p2[2] = *data++; p2[1] = *data++; p2[0] = *data++; } } #endif #define K1 0x5A827999L #define K2 0x6ED9EBA1L #define K3 0x8F1BBCDCL #define K4 0xCA62C1D6L #define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) #define F2(x,y,z) ( x ^ y ^ z ) #define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) #define F4(x,y,z) ( x ^ y ^ z ) #define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \ ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \ , (x[i&0x0f] = (tm << 1) | (tm >> 31)) ) #define R(a,b,c,d,e,f,k,m) do { e += rol( 5, a ) \ + f( b, c, d ) \ + k \ + m; \ b = rol( 30, b ); \ } while(0) R( a, b, c, d, e, F1, K1, x[ 0] ); R( e, a, b, c, d, F1, K1, x[ 1] ); R( d, e, a, b, c, F1, K1, x[ 2] ); R( c, d, e, a, b, F1, K1, x[ 3] ); R( b, c, d, e, a, F1, K1, x[ 4] ); R( a, b, c, d, e, F1, K1, x[ 5] ); R( e, a, b, c, d, F1, K1, x[ 6] ); R( d, e, a, b, c, F1, K1, x[ 7] ); R( c, d, e, a, b, F1, K1, x[ 8] ); R( b, c, d, e, a, F1, K1, x[ 9] ); R( a, b, c, d, e, F1, K1, x[10] ); R( e, a, b, c, d, F1, K1, x[11] ); R( d, e, a, b, c, F1, K1, x[12] ); R( c, d, e, a, b, F1, K1, x[13] ); R( b, c, d, e, a, F1, K1, x[14] ); R( a, b, c, d, e, F1, K1, x[15] ); R( e, a, b, c, d, F1, K1, M(16) ); R( d, e, a, b, c, F1, K1, M(17) ); R( c, d, e, a, b, F1, K1, M(18) ); R( b, c, d, e, a, F1, K1, M(19) ); R( a, b, c, d, e, F2, K2, M(20) ); R( e, a, b, c, d, F2, K2, M(21) ); R( d, e, a, b, c, F2, K2, M(22) ); R( c, d, e, a, b, F2, K2, M(23) ); R( b, c, d, e, a, F2, K2, M(24) ); R( a, b, c, d, e, F2, K2, M(25) ); R( e, a, b, c, d, F2, K2, M(26) ); R( d, e, a, b, c, F2, K2, M(27) ); R( c, d, e, a, b, F2, K2, M(28) ); R( b, c, d, e, a, F2, K2, M(29) ); R( a, b, c, d, e, F2, K2, M(30) ); R( e, a, b, c, d, F2, K2, M(31) ); R( d, e, a, b, c, F2, K2, M(32) ); R( c, d, e, a, b, F2, K2, M(33) ); R( b, c, d, e, a, F2, K2, M(34) ); R( a, b, c, d, e, F2, K2, M(35) ); R( e, a, b, c, d, F2, K2, M(36) ); R( d, e, a, b, c, F2, K2, M(37) ); R( c, d, e, a, b, F2, K2, M(38) ); R( b, c, d, e, a, F2, K2, M(39) ); R( a, b, c, d, e, F3, K3, M(40) ); R( e, a, b, c, d, F3, K3, M(41) ); R( d, e, a, b, c, F3, K3, M(42) ); R( c, d, e, a, b, F3, K3, M(43) ); R( b, c, d, e, a, F3, K3, M(44) ); R( a, b, c, d, e, F3, K3, M(45) ); R( e, a, b, c, d, F3, K3, M(46) ); R( d, e, a, b, c, F3, K3, M(47) ); R( c, d, e, a, b, F3, K3, M(48) ); R( b, c, d, e, a, F3, K3, M(49) ); R( a, b, c, d, e, F3, K3, M(50) ); R( e, a, b, c, d, F3, K3, M(51) ); R( d, e, a, b, c, F3, K3, M(52) ); R( c, d, e, a, b, F3, K3, M(53) ); R( b, c, d, e, a, F3, K3, M(54) ); R( a, b, c, d, e, F3, K3, M(55) ); R( e, a, b, c, d, F3, K3, M(56) ); R( d, e, a, b, c, F3, K3, M(57) ); R( c, d, e, a, b, F3, K3, M(58) ); R( b, c, d, e, a, F3, K3, M(59) ); R( a, b, c, d, e, F4, K4, M(60) ); R( e, a, b, c, d, F4, K4, M(61) ); R( d, e, a, b, c, F4, K4, M(62) ); R( c, d, e, a, b, F4, K4, M(63) ); R( b, c, d, e, a, F4, K4, M(64) ); R( a, b, c, d, e, F4, K4, M(65) ); R( e, a, b, c, d, F4, K4, M(66) ); R( d, e, a, b, c, F4, K4, M(67) ); R( c, d, e, a, b, F4, K4, M(68) ); R( b, c, d, e, a, F4, K4, M(69) ); R( a, b, c, d, e, F4, K4, M(70) ); R( e, a, b, c, d, F4, K4, M(71) ); R( d, e, a, b, c, F4, K4, M(72) ); R( c, d, e, a, b, F4, K4, M(73) ); R( b, c, d, e, a, F4, K4, M(74) ); R( a, b, c, d, e, F4, K4, M(75) ); R( e, a, b, c, d, F4, K4, M(76) ); R( d, e, a, b, c, F4, K4, M(77) ); R( c, d, e, a, b, F4, K4, M(78) ); R( b, c, d, e, a, F4, K4, M(79) ); /* update chainig vars */ hd->h0 += a; hd->h1 += b; hd->h2 += c; hd->h3 += d; hd->h4 += e; } /* Update the message digest with the contents * of INBUF with length INLEN. */ static void sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen) { if( hd->count == 64 ) { /* flush the buffer */ transform( hd, hd->buf ); hd->count = 0; hd->nblocks++; } if( !inbuf ) return; if( hd->count ) { for( ; inlen && hd->count < 64; inlen-- ) hd->buf[hd->count++] = *inbuf++; sha1_write( hd, NULL, 0 ); if( !inlen ) return; } while( inlen >= 64 ) { transform( hd, inbuf ); hd->count = 0; hd->nblocks++; inlen -= 64; inbuf += 64; } for( ; inlen && hd->count < 64; inlen-- ) hd->buf[hd->count++] = *inbuf++; } /* The routine final terminates the computation and * returns the digest. * The handle is prepared for a new cycle, but adding bytes to the * handle will the destroy the returned buffer. * Returns: 20 bytes representing the digest. */ static void sha1_final(SHA1_CONTEXT *hd) { u32 t, msb, lsb; byte *p; sha1_write(hd, NULL, 0); /* flush */; msb = 0; t = hd->nblocks; if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */ msb++; msb += t >> 26; t = lsb; if( (lsb = t + hd->count) < t ) /* add the count */ msb++; t = lsb; if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */ msb++; msb += t >> 29; if( hd->count < 56 ) { /* enough room */ hd->buf[hd->count++] = 0x80; /* pad */ while( hd->count < 56 ) hd->buf[hd->count++] = 0; /* pad */ } else { /* need one extra block */ hd->buf[hd->count++] = 0x80; /* pad character */ while( hd->count < 64 ) hd->buf[hd->count++] = 0; sha1_write(hd, NULL, 0); /* flush */; memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ hd->buf[56] = msb >> 24; hd->buf[57] = msb >> 16; hd->buf[58] = msb >> 8; hd->buf[59] = msb ; hd->buf[60] = lsb >> 24; hd->buf[61] = lsb >> 16; hd->buf[62] = lsb >> 8; hd->buf[63] = lsb ; transform( hd, hd->buf ); p = hd->buf; #ifdef WORDS_BIGENDIAN # define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) #else /* little endian */ # define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0) #endif X(0); X(1); X(2); X(3); X(4); #undef X } static byte * sha1_read( SHA1_CONTEXT *hd ) { return hd->buf; } /**************** * Return some information about the algorithm. We need algo here to * distinguish different flavors of the algorithm. * Returns: A pointer to string describing the algorithm or NULL if * the ALGO is invalid. */ const char * sha1_get_info( int algo, size_t *contextsize, byte **r_asnoid, int *r_asnlen, int *r_mdlen, void (**r_init)( void *c ), void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) ) { static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; if( algo != 2 ) return NULL; *contextsize = sizeof(SHA1_CONTEXT); *r_asnoid = asn; *r_asnlen = DIM(asn); *r_mdlen = 20; *r_init = (void (*)(void *))sha1_init; *r_write = (void (*)(void *, byte*, size_t))sha1_write; *r_final = (void (*)(void *))sha1_final; *r_read = (byte *(*)(void *))sha1_read; return "SHA1"; } bsign-0.4.5/sha1.h0100660000175000017500000000251106634411316011727 0ustar elfelf/* sha1.h - SHA1 hash function * Copyright (C) 1998 Free Software Foundation, Inc. * * This file is part of GNUPG. It is included in BSIGN in accordance * with the licence agreement of GNUPG. It has been modified little, * only to make it compile and link with BSIGN. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef G10_SHA1_H #define G10_SHA1_H const char * sha1_get_info( int algo, size_t *contextsize, byte **r_asnoid, int *r_asn_len, int *r_mdlen, void (**r_init)( void *c ), void (**r_write)( void *c, byte *buf, size_t nbytes ), void (**r_final)( void *c ), byte *(**r_read)( void *c ) ); #endif /*G10_SHA1_H*/ bsign-0.4.5/signal.cc0100660000175000017500000000215407421467035012515 0ustar elfelf/* signal.cc $Id: signal.cc,v 1.1 2002/01/17 06:24:29 elf Exp $ written by Marc Singer 16 Jan 2002 Copyright (C) 2002 The Buici Company ----------- DESCRIPTION ----------- Signal handlers to make us resilient. */ #include "standard.h" #include #include "exitstatus.h" void cleanup_temp_verify (bool fSignal); void cleanup_temp_hash (bool fSignal); void signal_handler_cleanup (int); void setup_signals (void) { struct sigaction sa; // Setup SIGHUP handler bzero (&sa, sizeof (sa)); sa.sa_handler = signal_handler_cleanup; #if defined (SIGHUP) sigaction (SIGHUP, &sa, NULL); #endif #if defined (SIGINT) sigaction (SIGINT, &sa, NULL); #endif #if defined (SIGQUIT) sigaction (SIGQUIT, &sa, NULL); #endif #if defined (SIGABRT) sigaction (SIGABRT, &sa, NULL); #endif #if defined (SIGPIPE) sigaction (SIGPIPE, &sa, NULL); #endif #if defined (SIGTERM) sigaction (SIGTERM, &sa, NULL); #endif } void signal_handler_cleanup (int signal) { cleanup_temp_verify (true); cleanup_temp_hash (true); // fprintf (stderr, "exit on signal %d\n", signal); exit (quit); } bsign-0.4.5/standard.h0100660000175000017500000000517207421672446012711 0ustar elfelf/* standard.h -*- C++ -*- $Id: standard.h,v 1.3 2002/01/18 01:06:46 elf Exp $ written by Oscar Levi 21 November 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (C) 1998 The Buici Company This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------- DESCRIPTION ----------- Standard Header inclusion for all files in the project. This inclusion ought (dare I say MUST) be first. */ #if !defined (__STANDARD_H__) # define __STANDARD_H__ /* ----- Includes */ //#include "build.h" // Build parameters, always first #if defined (HAVE_CONFIG_H) # include "config.h" // Autoconf configuration header #endif //#include "debug.h" // Our local debug code #if defined (HAVE_UNISTD_H) # include #endif #if defined (STDC_HEADERS) # include # include #endif #if defined (HAVE_FCNTL_H) # include #endif #include #if defined (HAVE_STRING_H) # include #endif #if defined (HAVE_STRINGS_H) # include #endif #include #if defined (HAVE_MALLOC_H) # include #endif //#include "porting.h" /* ----- Cope with missing standard functions */ #if !defined (STDC_HEADERS) # if !defined (HAVE_MEMCPY) # define memcpy(d,s,n) bcopy((s),(d),(n)) # define memmove(d,s,n) bcopy((s),(d),(n)) # endif #endif #if !defined (__CONSTVALUE) # define __CONSTVALUE __const #endif // ----- Typedefs typedef unsigned char byte; typedef signed char int8; typedef unsigned char unsigned8; typedef short int16; typedef unsigned short unsigned16; #if SIZEOF_INT == 4 typedef signed int int32; typedef unsigned int unsigned32; #elif SIZEOF_LONG == 4 typedef signed long int32; typedef unsigned long unsigned32; #endif #if SIZEOF_LONG == 8 typedef signed long int64; typedef unsigned long unsigned64; #elif SIZEOF_LONG_LONG == 8 typedef signed long long int64; typedef unsigned long long unsigned64; #endif #endif /* __STANDARD_H__ */ bsign-0.4.5/tty.cxx0100660000175000017500000000211106721714440012263 0ustar elfelf/* tty.cxx $Id: tty.cxx,v 1.2 1999/05/23 05:58:56 elf Exp $ written by Oscar Levi 13 December 1998 Copyright (C) 1998 The Buici Company ----------- DESCRIPTION ----------- TTY IO control functions. */ #include "standard.h" #include #include "tty.h" #include extern const char* g_szApplication; struct termios g_termiosSave; void disable_echo (int fh) { struct termios termios; if (tcgetattr (fh, &g_termiosSave)) fprintf (stderr, "%s: tcgetattr failed on %d (%s)\n", g_szApplication, fh, strerror (errno)); // restore_termios = 1; termios = g_termiosSave; termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); if (tcsetattr (fh, TCSAFLUSH, &termios)) fprintf (stderr, "%s: tcsetattr failed on %d (%s)\n", g_szApplication, fh, strerror (errno)); } void restore_echo (int fh) { if (tcsetattr (fh, TCSAFLUSH, &g_termiosSave)) fprintf (stderr, "%s: tcsetattr failed on %d (%s)\n", g_szApplication, fh, strerror (errno)); } int open_user_tty (void) { return open ("/dev/tty", O_RDWR); } bsign-0.4.5/tty.h0100660000175000017500000000051106721714440011712 0ustar elfelf/* tty.h $Id: tty.h,v 1.2 1999/05/23 05:58:56 elf Exp $ written by Oscar Levi 13 Dec 1998 */ #if !defined (__TTY_H__) # define __TTY_H__ /* ----- Includes */ #include /* ----- Globals */ void disable_echo (int fh); void restore_echo (int fh); int open_user_tty (void); #endif /* __TTY_H__ */ bsign-0.4.5/unsigned0100770000175000017500000000012106711510173012453 0ustar elfelf#!/bin/sh find $1 -type f -perm +0100 -exec bsign --unsigned -q \{\} \; -print bsign-0.4.5/version.h0100660000175000017500000000305006634411316012557 0ustar elfelf/* version.h $Id: version.h,v 1.2 1998/12/12 06:53:02 elf Exp $ written by Oscar Levi 1 December 1998 This file is part of the project BSIGN. See the file README for more information. Copyright (C) 1998 Oscar Levi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in a file called COPYING along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------- DESCRIPTION ----------- This file declares C statics for the current version number. */ #if defined (DECLARE_VERSION) /* _version.h contains a single #define for SZ_VERSION. It is created automatically from .version_{major,minor,patch} files in the build process. The define takes this form. #define SZ_VERSION "1.2.3" */ # include "_version.h" # define SZ_COPYRIGHT "Copyright (C) 1998 The Buici Company." const char* g_szVersion = SZ_VERSION; const char* g_szCopyright = SZ_COPYRIGHT; #else extern const char* g_szVersion; extern const char* g_szCopyright; #endif bsign-0.4.5/debian/0040775000175000017500000000000007714272757012172 5ustar elfelfbsign-0.4.5/debian/changelog0100660000175000017500000000474207714272611014031 0ustar elfelfbsign (0.4.5) unstable; urgency=low * Recast the signature data pointer to prevent inappropriate sign extension. -- Marc Singer Wed, 6 Aug 2003 14:35:54 -0700 bsign (0.4.4) unstable; urgency=low * Removed install dependency on gpg so that bsign can install in main. * Detect absence of gnupg when running commands that require it. -- Marc Singer Tue, 29 Jan 2002 15:26:00 -0800 bsign (0.4.3) unstable; urgency=low * Tested/fixed the bsign_ scripts. * Enhanced summary. -- Marc Singer Sun, 27 Jan 2002 10:46:02 -0800 bsign (0.4.2) unstable; urgency=low * Reopened project after long hiatus. Need identified to use it, so there's a need to complete the work. Shouldn't be too difficult since the signing has always worked. It's UI polish that was missing. * Fixed handling of temporary files and signals so that no temporaries are left behind. * Fixed the dup_status function so that setuid bit isn't cleared. * Added fts_ enumeration mode and unified all of the enumeration into a class. * Made some changes to the file processing to avoid mmap'ing files until we know that we will be reading the whole file. * No longer resigning by default. * Summary option. * Rewrote man page to reflect new options and to be more clear. * Added scripts to demonstrate use on productionsystem. * Improved the handling of informational messages and exit codes so that email of output is useful. * Changed semantics of command line to be more obvious. The problem was that the switches were interpreted in order. If a filename appeared before the command, bsign wouldn't know what command to execute. Now, all options are read before starting work. * Fixed the replace_file function so that there is no opportunity to lose a file. -- Marc Singer Thu, 17 Jan 2002 14:14:08 -0800 bsign (0.2.0) unstable; urgency=low * Edits to README. * Appear to be some bug fixes, too. -- Marc Singer Fri, 5 May 2000 09:49:16 -0700 bsign (0.1.7) unstable; urgency=low * Disabled echo on passphrase read. Less paranoid about elf'ness when reading segments. * bss (NOBITS) section can have any durn offset it wants. -- Oscar Levi Mon, 14 Dec 1998 01:07:44 -0800 bsign (0.1.6) unstable; urgency=low * First public release. Digital signature only by GNUPG. -- Oscar Levi Sat, 12 Dec 1998 12:14:35 -0800 bsign-0.4.5/debian/control0100660000175000017500000000120307425630077013552 0ustar elfelfSource: bsign Section: admin Priority: optional Maintainer: Marc Singer Standards-Version: 3.5.6.0 Build-Depends: debhelper (>= 3.0.40), g++ Package: bsign Architecture: i386 Depends: ${shlibs:Depends} Description: Corruption & intrusion detection using embedded hashes This package embeds secure hashes (SHA1) and digital signatures (GNU Privacy Guard) into files for verification and authentication. Currently, target file types are all ELF format: executables, kernel modules, shared and static link libraries. This program has functionality similar to tripwire and integrit without the need to maintain a database.bsign-0.4.5/debian/copyright0100660000175000017500000000167507425065664014123 0ustar elfelfThis copyright refers to all versions of BSIGN, a program that embeds in files verifies a secure hash and optional digital signature. Program Copyright (C) 1998,2002 The Buici Company. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License with your Debian GNU/Linux system, in /usr/share/common-licenses/GPL, or with the Debian GNU/Linux hello source package as the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, MA 02111-1307, USA. bsign-0.4.5/debian/rules0100770000175000017500000000632207435317600013230 0ustar elfelf#!/usr/bin/make -f # debian/rules -*- Makefile -*- # $Id: rules,v 1.11 2002/02/22 01:31:44 elf Exp $ # # written by Oscar Levi # 11 December 1998 # # Copyright 1998 The Buici Company # # These rules provide the glue between Debian and this ${package}. # The interesting target is binary which builds the binary package by # configuring, compiling, and installing it in the debian/tmp # directory and then invoking the Debian packaging tools. # package=bsign base=$(package) ### Used for changes file arch=i386 version=`cat .version` RELEASE_PATH=${HOME}/release build: $(checkdir) ./configure --prefix=/usr $(MAKE) # CFLAGS=-O2 LDFLAGS= touch build build-release: build $(MAKE) $(package).README clean: $(checkdir) -rm -f build -$(MAKE) -i distclean || $(MAKE) -f Makefile.in distclean -rm -rf debian/tmp debian/*~ debian/files* debian/substvars binary-indep: checkroot build $(checkdir) # There are no architecture-independent files to be uploaded # generated by this package. If there were any they would be # made here. binary-arch: checkroot build build-release $(checkdir) -rm -rf debian/tmp dh_clean dh_installdirs $(MAKE) CFLAGS=-O2 LDFLAGS=-s INSTALL='install' \ prefix=`pwd`/debian/tmp/usr install dh_installmenu dh_installdocs dh_installdeb mv bsign-$(version).README debian/tmp/usr/share/doc/$(package)/README dh_installchangelogs dh_compress dh_strip dh_shlibdeps dh_gencontrol dh_fixperms dpkg --build debian/tmp .. ;\ define checkdir test -f $(package).cxx -a -f debian/rules endef .PHONY: source source: -echo === Building $(version) $(checkdir) -rm -rf debian/$(package)-$(version) -rm -rf _source cvs -Q export -rHEAD -d _source $(base) mv _source debian/$(package)-$(version) dpkg-source -b debian/$(package)-$(version) -rm -rf debian/$(package)-$(version) mv $(package)_*.dsc _dsc echo "" >> _dsc gpg -a --clearsign --default-key elf --output $(package)_$(version).dsc _dsc rm _dsc mv $(package)_*.dsc $(package)_*.tar.gz .. .PHONY: package package: $(checkdir) -rm -rf debian/package mkdir debian/package cvs -Q export -rHEAD -d debian/package/$(package)-$(version) $(base) cd debian/package/$(package)-$(version) ; dpkg-buildpackage -rsudo sudo rm -rf debian/package/$(package)-$(version) # Perform the final staging before releasing the package to the debian # servers. (elf target) .PHONY: prerelease prerelease: dpkg-genchanges > ../$(package)_$(version).changes.orig echo "" >> ../$(package)_$(version).changes.orig gpg -a --clearsign --default-key elf --output ../$(package)_$(version)_$(arch).changes ../$(package)_$(version).changes.orig rm ../$(package)_$(version).changes.orig if test -d ${RELEASE_PATH} ; then \ mv ../$(package)_$(version)* ~/release/debian ;\ fi # Perform full release build, binary and source and prerelease so that # we're ready for upload. (elf target) .PHONY: fullrelease fullrelease_clean fullrelease_binary fullrelease: fullrelease_clean fullrelease_binary source prerelease fullrelease_clean: make distclean fullrelease_binary: fakeroot debian/rules binary # Below here is fairly generic really binary: binary-indep binary-arch checkroot: $(checkdir) test root = "`whoami`" .PHONY: binary binary-arch binary-indep clean checkroot