#!/bin/bash

# Copyright 2008-2014 Anibal Monsalve Salazar <anibal@debian.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.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

set -e
set -u
#set -x

shopt -s nocasematch

declare from=""
declare msg_id=""
declare msg=""
declare line=""
declare filename=""
declare subject=""
declare import=""
declare fingerprint=""
declare signature=""
declare uid=""
declare keys=""
declare key=""
declare regex=""
declare eof="no"

declare -i res=""

declare -r GPG_TMP="gpg --homedir gnupg-tmp -v"
declare -r GPG_KSP="gpg --homedir gnupg-dc14"
declare -r EXPORT="--export-options export-clean,export-minimal --export"
declare -r SENDMAIL="/usr/bin/ssh anibal@master.debian.org /usr/sbin/sendmail"
declare -r FROM="Anibal Monsalve Salazar <anibal@debian.org>"
declare -r BCC="anibal@debian.org,ams@v7w.com,ani6al@gmail.com"

declare -r regex_1="^From "
declare -r regex_2="^From: (.*)$"
declare -r regex_3="^Message-ID: (.*)$"
declare -r regex_4="^Subject: (.*)$"

[ -d gnupg-tmp ] || mkdir -m 700 gnupg-tmp
[ -d gnupg-dc14 ] || mkdir -m 700 gnupg-dc14
[ -d mail ] || mkdir mail
[ -d msgs ] || mkdir msgs

while [ "$eof" == "no" ]
do
    if ! IFS= read -r line
    then
        eof="yes"
    fi

    if [[ "$line" =~ $regex_1 ]] || [ "$eof" == "yes" ]
    then
        if [ -n "$msg" ]
        then
            if [ -z "$msg_id" ]
            then
                echo -e '\033[01;31m'"msg_id is empty!"'\033[00m'
                exit 1
            fi
            filename=${msg_id#<}
            filename=${filename%>}
            filename=${filename////_}
            if [ -f $filename ]
            then
                echo -e '\033[01;31m'"exist $filename"'\033[00m'
            elif [ -f msgs/$filename ]
            then
                echo  -e '\033[01;30m'"exist msgs/$filename"'\033[00m'
            else
                rm -f gnupg-tmp/*

                set +e
                set -o pipefail
                import=$( $GPG_TMP <<< "$msg" 2> /dev/null | $GPG_TMP --import 2>&1 )
                res="$?"
                set +o pipefail
                set -e

                uid=${import#*\"}
                uid=${uid%%\"*}
                uid=${uid/(*)/}

                keys=$(
                    while read linea
                    do
                        if [[ "$linea" =~ imported$ ]]
                        then
                            key=${linea//gpg: key /}
                            key=${key//:*/}
                            echo $key
                        fi
                    done <<< "$import"
                )
                keys=${keys//$'\n'/ }

                set +e
                exec 3>&1                                               # link FD 3 with stdout and save stdout
                signature=$( $GPG_TMP <<< "$msg" 2>&1 1>/dev/null )     # redirect stderr only to stdout
                res="$?"
                exec 1>&3 3>&-                                          # restore stdout and close FD 3
                set -e

                if [ "$res" -ne "0" ]
                then
                    extra=$( $GPG_TMP <<< "$msg" 2>&1  | grep -B1 "^gpg: Can't check signature: public key not found$" | grep " key ID ")
                    extra=${extra##* }
                    if  [ -n "$extra" ]
                    then
                        set +e
                        echo $GPG_TMP --keyserver pgp.net.nz --recv-keys $extra
                        $GPG_TMP --keyserver pgp.net.nz --recv-keys $extra

                        exec 3>&1                                               # link FD 3 with stdout and save stdout
                        signature=$( $GPG_TMP <<< "$msg" 2>&1 1>/dev/null )     # redirect stderr only to stdout
                        res="$?"
                        exec 1>&3 3>&-                                          # restore stdout and close FD 3

                        echo $GPG_TMP --batch --yes --delete-keys $extra
                        $GPG_TMP --batch --yes --delete-keys $extra
                        set -e
                    fi
                fi

                fingerprints=$(
                    while read linea
                    do
                        if [[ "$linea" =~ fingerprint: ]]
                        then
                            fingerprint=${linea//*key fingerprint: /}
                            fingerprint=${fingerprint// /}
                            echo $fingerprint
                        fi
                    done <<< "$signature"
                )
                fingerprints=${fingerprints//$'\n'/ }

                regex=${keys// /|}
                if [ "$res" -eq "0" ] && [ -n "$regex" ] && [[ "$fingerprints" =~ $regex ]]
                then
                    set -o pipefail
                    $GPG_TMP $EXPORT | $GPG_KSP --import > /dev/null 2>&1
                    res="$?"
                    set +o pipefail

                    echo $uid\,$from\;$keys\;$msg_id\; >> names.txt

                    echo -e '\033[01;32m'"new msgs/$filename"'\033[00m'
                    echo "$msg" > msgs/$filename

                    #ping -c1 pgp.net.nz > /dev/null 2>&1
                    #$GPG_TMP --keyserver pgp.net.nz --send-keys $keys
                    keycheck=$(
                        for key in $keys
                        do
                            KEYSERVER=pgp.net.nz keycheck.sh $key 2> /dev/null
                            echo
                        done
                    )

                    fingerprint=$( $GPG_TMP --fingerprint )
                    ( echo -e "Subject: Re: $subject\nTo: $from\nFrom: $FROM\nBcc: $BCC\nMessage-ID: <$(date +%Y%m%d.%H%M%S.%N -u)@ksp-dc14.debian.org>\nIn-Reply-To: $msg_id\n\nImported keys:\n\n$import\n\nFingerprints:\n\n$fingerprint\n\nSignatures:\n\n$signature\n\nKeycheck:\n\n$keycheck" ) > mail/$filename
                    $SENDMAIL -t < mail/$filename
                else
                    echo -e '\033[01;31m'"new $filename"'\033[00m'
                    echo "$msg" > $filename
                fi
            fi
            from=""
            subject=""
            msg_id=""
            msg=""
        fi
    elif [[ "$line" =~ $regex_2 ]]
    then
        from="${BASH_REMATCH[1]}"
        #from="anibal@v7w.com"
    elif [[ "$line" =~ $regex_3 ]]
    then
        msg_id="${BASH_REMATCH[1]}"
    elif [[ "$line" =~ $regex_4 ]]
    then
        subject="${BASH_REMATCH[1]}"
        subject=${subject#re: }
        subject=${subject#Re: }
        subject=${subject#RE: }
    fi

    if [ "$eof" == "no" ]
    then
        msg="$msg$line"$'\n'
    fi
done

echo -e '\033[01;31m'"done"'\033[00m'
exit 0
