#!/bin/sh # Copyright 2006 Alan Grow. # All rights reserved. # Licensed under the terms contained in the file 'COPYING' in the # source directory. # plop.cgi - a simple opaque file portal # # plop is a simple cgi file portal that imposes key-based access to files. # it's a quick way to share files without exposing them to spiders. shared # files automatically expire after a specified period of time and are no # longer accessible via the cgi interface. # # plop by itself DOES NOT provide a secure communication channel. if you # need that, serve it up only over https, or share pgp-encrypted files. # security phase earlyerr() { test "$?" -ne 0 && echo "configuration problem, exiting." 1>&2 } trap earlyerr 0 set -e PATH=/bin:/usr/bin IFS="`printf ' \t\n'`" while [ $# -gt 0 ]; do shift; done # configuration phase for d in /etc/plop /usr/local/etc/plop; do for f in plop.conf.default plop.conf; do test -f "$d/$f" && . "$d/$f" done done plopdbdir="$plopdir/db" plopfiledir="$plopdir/files" ploptmpdir="$plopdir/tmp" plopmasterdb="$plopdbdir/master" # processing phase die() { terse="$1" detailed="$2" httperror "$terse" [ -n "$detailed" ] && echo "$detailed" 1>&2 exit 111 } httpheader() { if [ $# -eq 2 ]; then printf "$1: $2\r\n" else printf "\r\n" fi } httperror() { message="$1" html="$message" bytes=`echo -n "$html" | wc -c` httpheader Content-Length "$bytes" httpheader Connection close httpheader Content-Type text/html httpheader echo -n "$html" } cgiquery() { if [ "$REQUEST_METHOD" = "POST" ]; then length="$CONTENT_LENGTH" if [ "$plopmaxpost" -gt 0 -a "$length" -gt "$plopmaxpost" ]; then length="$plopmaxpost" fi head -c "$length" elif [ "$REQUEST_METHOD" = "GET" ]; then echo -n "$QUERY_STRING" | head -c "$plopmaxpost" elif [ -n "$debug" ]; then head -c "$plopmaxpost" else die "sorry." "bad cgi request method." fi } inputerr() { test "$?" -ne 0 && die "sorry." } trap inputerr 0 test -f "$plopmasterdb" || die "sorry." "error reading database $plopmasterdb." cgiquery | tr '&' '\n' | awk -F= '{if ($1=="key") print $2}' | { join -t' ' - "$plopmasterdb"; echo -n "0 0"; } | sort -u -r | \ ( read key file expires [ "$key" = "0" ] && die "sorry." "no record found or malformed query." [ -z "$file" ] && die "file not found." "file field for record $key is empty." path="$plopfiledir/$file" [ ! -f "$path" ] && die "file not found." "file $path for $key not found." if [ -n "$expires" ]; then now="`date +%s`" [ "$expires" -lt "$now" ] && die "file not found." "record $key is expired." fi bytes=`$cmd_size "$path"` mime=`$cmd_mime "$path"` httpheader Content-Length "$bytes" httpheader Connection close httpheader Content-Type "$mime" httpheader Content-Disposition "attachment; filename $file" httpheader exec cat "$path" )