#!/bin/sh -e
#
# $Id: amcryptogzip,v 1.1 2005/11/08 02:37:50 sluskyb Exp $
#
# Copyright © 2005  Ben Slusky <sluskyb@paranoiacs.org>
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
#
# This is meant to be a drop-in replacement for gzip for use by
# AMANDA, but feel free to do anything else you like with it.
#
# Usage is similar to gzip, but very limited:
#	amcryptogzip [ _gzipopts_ ]
# If the first argument is "-dc", then the input will be decrypted
# and then unzipped, otherwise it will be zipped and then encrypted.
# Note the complete absence of any sanity checks on the options; any
# number of things could happen if this script gets confused.  Using
# the -d option in a manner other than described above, or specifying
# a filename without the -c option are good ways to confuse this
# script.
#

# change these as needed
GZIP=/usr/bin/gzip  # bzip2 also works here
OPENSSL=/usr/bin/openssl
CIPHER=aes-256-cbc
BACKUPSET=MyBackupSet

PUBKEY=/etc/amanda/${BACKUPSET}/backup-pubkey.pem
PRIVKEY=/etc/amanda/${BACKUPSET}/backup-key.pem
PASSFILE=/etc/amanda/${BACKUPSET}/passphrase
ME=`basename $0`
WORKDIR=`mktemp -d /tmp/${ME}-XXXXXX`

trap "rm -rf ${WORKDIR}" 0 1 2 3 15

encrypt() {
	# generate a random (printable) cipher key
	${OPENSSL} rand 86 | tr '\0-\377' './0-9A-Za-z./0-9A-Za-z./0-9A-Za-z./0-9A-Za-z' >${WORKDIR}/pass

	# encrypt the cipher key using the RSA public key
	${OPENSSL} rsautl -encrypt -in ${WORKDIR}/pass -out ${WORKDIR}/pass.ciphertext -pubin -inkey ${PUBKEY} -pkcs

	# print magic
	echo -n cryptogzip

	# print the encrypted cipher key, preceded by size
	printf %-10u `ls -l ${WORKDIR}/pass.ciphertext | awk '{print $5}'`
	cat ${WORKDIR}/pass.ciphertext

	# encrypt data using the cipher key and print
	${OPENSSL} enc -${CIPHER} -e -pass file:${WORKDIR}/pass -nosalt
}

decrypt() {
	# read magic
	magic=`dd bs=10 count=1`
	if [ x$magic != xcryptogzip ]; then
		echo "${ME}: bad magic" >&2
		return 1
	fi

	# read size of encrypted cipher key
	n=`dd bs=10 count=1`
	if ! [ $n -gt 0 ] 2>/dev/null; then
		echo "${ME}: bad header" >&2
		return 1
	fi

	# read the encrypted cipher key
	dd of=${WORKDIR}/pass.ciphertext bs=$n count=1 

	# decrypt the cipher key using the RSA private key
	${OPENSSL} rsautl -decrypt -in ${WORKDIR}/pass.ciphertext -out ${WORKDIR}/pass -inkey ${PRIVKEY} -passin file:${PASSFILE} -pkcs

	# use the cipher key to decrypt data
	openssl enc -${CIPHER} -d -pass file:${WORKDIR}/pass -nosalt
}

if [ x$1 = x-dc ]; then
	# decrypt and decompress
	decrypt | ${GZIP} "$@"
else
	# compress and encrypt
	${GZIP} "$@" | encrypt
fi
