#!/usr/bin/bash ############################################################################## # This file is part of the CRYPTO BONE # File : safewebdropfile (server) # Version : 1.6 (ALL-IN-ONE) # License : BSD # Date : 12 April 2023 # Contact : Please send enquiries and bug-reports to innovation@senderek.ie # # Copyright (c) 2015-2023 # Ralf Senderek, Ireland. All rights reserved. (https://senderek.ie) # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. All advertising materials mentioning features or use of this software # must display the following acknowledgement: # This product includes software developed by Ralf Senderek. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. ############################################################################## #----------------------------------------------------# # load functions and global variables . ./safewebdrop-functions function new_name { # $1 : directory # $2 : extension that is appended, if $2 exists # $3 : PREFIX without number extension NAME="" LAST="" typeset -i NUM=1 if [[ x$1 != "x" ]] then if [[ x$2 != "x" ]] then LAST=$(/bin/ls $1/$3*.$2 2>/dev/null | /usr/bin/sort | /usr/bin/tail -1) LAST=${LAST%.$2} else LAST=$(/bin/ls $1/$3* 2> /dev/null | /usr/bin/sort | /usr/bin/tail -1) fi LAST=${LAST##*.} LAST=${LAST#0} LAST=${LAST#0} LAST=${LAST#0} NUM=${LAST} NUM=${NUM}+1 PRE="mail" if [[ x$3 != "x" ]]; then PRE=$3 fi if [[ ${NUM} -lt 10 ]] then NAME="${PRE}.000"${NUM} else if [[ ${NUM} -lt 100 ]] then NAME="${PRE}.00"${NUM} else if [[ ${NUM} -lt 1000 ]] then NAME="${PRE}.0"${NUM} else NAME="${PRE}."${NUM} fi fi fi fi if [[ ${NUM} -eq 0 ]] then NAME="${PRE}.0001" fi if [[ x$2 != "x" ]] then NAME=${NAME}.$2 fi /usr/bin/echo ${NAME} } #----------------------------------------------------# # import config file if [[ -s ${DEST}/safewebdrop.config ]] ; then . ${DEST}/safewebdrop.config fi /usr/bin/echo Content-type: text/html /usr/bin/echo if [[ ! ${MAX} ]] ; then ## if no MAX is defined MAX=500 # kilobyte fi if [[ ! ${MAXFILES} ]] ; then ## if no MAXFILES is defined MAXFILES=5 # all further files overwrite the last one fi if [[ ${ACCEPT_FILES} = "yes" ]]; then OLDIFS="${IFS}" IFS=\& set -- $QUERY_STRING RECIPIENT=$1 SENDER=$2 MESSAGE=$3 HASHSIG=$4 NUM=$5 IFS=${OLDIFS} # check if the recipient exists here if [[ -d ${DEST}/${RECIPIENT} ]] ; then LOG=${DEST}/${RECIPIENT}/log log "---- file upload $NUM ----" else LOG=${DEST}/admin/log log "${RECIPIENT} is not registered here" exit 5 fi if [[ "${NUM}"x != "x" ]] ; then FILE=file-${SENDER}.${NUM} else FILE=$(new_name "${DEST}/${RECIPIENT}" "" "file-${SENDER}") fi #check that this is not one too many files # count all files of RECIPIENT instead !!! NUMFILES=$(/usr/bin/ls ${DEST}/${RECIPIENT}/file-${SENDER}* 2> /dev/null | wc -l) if (( "${NUMFILES}" >= ${MAXFILES} )) ; then FILE=file-${SENDER}.9999 fi # check that SENDER's public key exists # check local user log "looking for ${SENDER}'s pubkey" PUBKEY=${DEST}/${SENDER}/pubkey.pem if [[ ! -r ${PUBKEY} ]] ; then log "not found as local user" # check in RECIPIENT's contacts PUBKEY=${DEST}/${RECIPIENT}/contacts/${SENDER}.pubkey.pem if [[ ! -r ${PUBKEY} ]] ; then # no public key available log "no public key available for ${SENDER}" exit 5 fi fi log "using public key : ${PUBKEY}" ### log "last file ${NUM} : max number of files = ${MAXFILES}" FILE=${DEST}/${RECIPIENT}/$FILE log "using $FILE" # read data /usr/bin/dd of=/tmp/file bs=1k count=${MAX} 2>/dev/null if [[ -r /tmp/file ]]; then log "$(/usr/bin/ls -l /tmp/file)" # check, if file is in OpenPGP format if [[ -x /usr/bin/gpg ]] ; then CHECK=$(/usr/bin/echo | /usr/bin/gpg --homedir ${DEST}/tmp /tmp/file 2>&1) /usr/bin/echo -n "${CHECK}" | /usr/bin/grep "encrypted data" 2>/dev/null | /usr/bin/grep "AES" 2>/dev/null >/dev/null if [[ $? -ne 0 ]] ; then rm -f ${DEST}/tmp/file 2>/dev/null log "the message is not AES encrypted data" exit 6 else log "attachment is AES encrypted" fi else log "/usr/bin/gpg does not exist, so the OpenPGP message cannot be checked." fi # check signature and exit if not OK NUMBER="" if [[ "${PUBKEY}x" != "x" ]] ; then # the SENDER's pubkey can be used for verification SIGNED=${DEST}/${RECIPIENT}/signedfilehash VERIFIED=${DEST}/${RECIPIENT}/verifiedfilehash rm -f $SIGNED $VERIFIED /usr/bin/echo -n "${HASHSIG}" | /usr/bin/base64 -d > ${SIGNED} # verify the signature on the message /usr/bin/openssl pkeyutl -verifyrecover -in ${SIGNED} -keyform PEM -inkey ${PUBKEY} -pubin -out ${VERIFIED} if [[ ! -s ${VERIFIED} ]] ; then log "${SENDER} : corrupt signature or RSA public key" cleansig exit 3 fi SIGNEDHASH=$(cat ${VERIFIED}) MESSAGEHASH=$(/usr/bin/echo -n ${MESSAGE}| /usr/bin/sha256sum | /usr/bin/cut -c-64) if [[ ${SIGNEDHASH} != ${MESSAGEHASH} ]] ; then log "signature verification failed" cleansig exit 3 fi # split MESSAGE into Number and Hash OLDIFS="${IFS}" IFS=: set -- ${MESSAGE} NUMBER=$1 FILEHASH=$2 IFS=${OLDIFS} if [[ ${MESSAGE} ]] ; then # check if the signed filehash matches /tmp/file HASH=$(/usr/bin/cat /tmp/file | /usr/bin/sha256sum | /usr/bin/cut -c-64) if [[ ${HASH} != ${FILEHASH} ]] ; then log "ERROR: hashes don't match" cleansig exit 3 fi fi fi cleansig # hashes are OK # check NUMBER in signature if [[ ${NUMBER} != ${NUM} ]] ; then # conflicting request log "the numbers don't match ${NUMBER} : ${NUM}" exit 4 fi if [[ -d ${DEST}/${RECIPIENT} ]] && [[ -r /tmp/file ]] ; then /usr/bin/mv /tmp/file ${FILE} ### log "finally: $(ls -l ${FILE})" # register in filelist ALIST=${DEST}/${RECIPIENT}/attachmentlist ATTACH=$(/usr/bin/grep Attachment ${DEST}/${RECIPIENT}/drop-${SENDER}.${NUM} 2>/dev/null) ATTACH=${ATTACH##*: } /usr/bin/echo "$(/usr/bin/date +'%x %X') : ${NUMBER}:${ATTACH}" >> ${ALIST} /usr/bin/echo -e "${NUMBER}:${ATTACH}\n.\n" >> ${FILE} /usr/bin/echo -n "WEBDROP MESSAGE+ATTACHMENT SAVED" log "${FILE} stored successfully" log "--- End file upload ---" exit 0 fi fi # no data received log "No data has been stored." /usr/bin/echo "failed" else /usr/bin/echo "Config: forbidden" exit 7 fi exit 0