From 5994e0a308410bcadc4a745e61b25eea4773cb65 Mon Sep 17 00:00:00 2001 From: rhatto Date: Sat, 6 Aug 2005 16:45:53 +0000 Subject: desfazendo a ultima merda, hoje tah foda --- firma | 578 ++++++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 405 insertions(+), 173 deletions(-) diff --git a/firma b/firma index 1fbb2b0..6326362 100755 --- a/firma +++ b/firma @@ -1,173 +1,405 @@ - - - - - - - - codecoop: Exiting with error - - - - - - - - - - - - - - - - - - - -
-
- -
-
  
Log In
- New Account -
  
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - - - - - - - - - - -
HomeMy PageProject TreeProject Openings
- - - -
 
- - - - - - - - - - - - - - - - - - - - -
- -

ERROR - No group_id was chosen

No group Id was chosen

- - - -
- - - -
- - -
-
-Powered By GForge Collaborative Development Environment -
- - - - +#!/bin/bash +# +# firma: encrypted mailing list manager +# feedback: rhatto@riseup.net luis@riseup.net | GPL +# +# list configuration is passed thru the config file, +# where you put PARAMETER=value (whithout spaces) +# +# MAIL= path for mail program +# GPG= path for gnupg binary +# LISTNAME= list email +# LISTADMIN= list administrator email addresses (space separated) +# GPGDIR= gpg dir for the lists' keyring +# PASSWD= passwd for the lists' keyring +# + +FIRMA_LIST_PATH="/usr/local/etc/lists" +VERSION="0.3" + +# todo: +# errase all vars before quit the game +# unset MESSAGE +# unset GPG_MESSAGE +# umask .... + +function usage { + echo "usage: $(basename $0) OPTION [LIST-NAME]" + echo " -a: admin commands" + echo " -c: create a new list" + echo " -h: display this help and exit" + echo " -p: process a message" + echo " -r: admin and user requests (mail only)" + echo " -v: output version information and exit" +} + +function version { + echo "firma $VERSION" + echo "Copyright (C) 2005 A Firma, Inc." + echo "This program comes with ABSOLUTELY NO WARRANTY." + echo "This is free software, and you are welcome to redistribute it" + echo "under certain conditions. See the GNU General Public License" + echo "for more details." +} + + +function check_config { + # check configuration file parameters + if [ ! -f $GPG -o ! -x $GPG ]; then + echo "$CONFIG_FILE: GPG binary ($GPG) could not be found." + exit 1 + elif [ ! -f $MAIL -o ! -x $MAIL ]; then + echo "$CONFIG_FILE: Mail program ($MAIL) could not be found." + exit 1 + elif [ ! -d $GPGDIR -o ! -f $GPGDIR/pubring.gpg -o ! -f $GPGDIR/secring.gpg ]; then + echo "$CONFIG_FILE: GPG home directory ($GPGDIR) or the GPG keyrings could not be found." + exit 1 + elif [ -z "$(cat $CONFIG | grep -o ^PASSWD=\'[^\']*\'$)" -o \ + -z "$(echo -n $PASSWD)" -o \ + "$(echo -n $PASSWD | wc -m)" -lt "25" -o \ + -z "$(echo -n $PASSWD | grep -o [[:lower:][:upper:]])" -o \ + -z "$(echo -n $PASSWD | grep -o [[:digit:]])" -o \ + "$(echo -n $PASSWD | grep -o [[:punct:]] | wc -l)" -lt "5" ]; then + echo "$CONFIG_FILE: PASSWD is empty or does not meet the minimum complexity requirements." + echo "$CONFIG_FILE: Please set a new passphrase for the list's private key. Make it at least" + echo "$CONFIG_FILE: 25 characters long (using a combination of letters, numbers and at least" + echo "$CONFIG_FILE: 5 special characters) and enclose it in 'single quotes'. The passphrase" + echo "$CONFIG_FILE: itself, though, cannot contain any single quote." + exit 1 + elif [ -z "$($GPGLIST | grep ^pub | cut -d : -f 10 | grep -i \<$LISTNAME\>$)" ]; then + echo "$CONFIG_FILE: GPG key for list \"$LISTNAME\" could not be found." + echo "$CONFIG_FILE: Note that this parameter expects an email address." + exit 1 + else + for ADMIN in $LISTADMIN; do { + if [ -z "$($GPGLIST | grep ^pub | cut -d : -f 10 | grep -i \<$ADMIN\>$)" ]; then + echo "$CONFIG_FILE: GPG key for list administrator \"$ADMIN\" could not be found." + echo "$CONFIG_FILE: Note that this parameter expects one or more space separated email addresses." + exit 1 + fi; } + done + fi +} + +function get_gpg_stderr { + # discard $GPGDECRYPT STDOUT and get its STDERR instead, for signature checking + echo -e "$PASSWD\n${GPG_MESSAGE[@]}" | sed -e 's/^ //' | ($GPGDECRYPT --status-fd 2 1> /dev/null) 2>&1 +} + +function get_subscribers_list { + # get list susbscriber's addresses + $GPGLIST | sed -ne "/$LISTNAME/Id" -e '/pub/p' | cut -d : -f 10 | grep -o '<[^<>]*>$' | sed -e 's/[<>]//g' +} + +function get_message { + n=0 + while read STDIN; do + MESSAGE[$n]="$STDIN\n" + ((++n)) + done +} + +function get_gpg_message { + signal=0 + x=0 + for ((count=0;count<=n;count++)); do + if [[ $signal == "0" ]] && [[ "$(echo "${MESSAGE[$count]}" | grep -v -e "-----BEGIN PGP MESSAGE-----")" == "" ]]; then + GPG_MESSAGE[$x]=${MESSAGE[$count]} + ((++x)) + signal=1 + elif [[ $signal == "1" ]]; then + GPG_MESSAGE[$x]=${MESSAGE[$count]} + ((++x)) + if [[ "$(echo "${MESSAGE[$count]}" | grep -v -e "-----END PGP MESSAGE-----")" == "" ]]; then + signal=0 + fi + fi + done +} + +function get_message_headers { + # get the message headers and the sender's email address + FROM=$(echo -e "${MESSAGE[@]}" | grep -m 1 "From:" | cut -d : -f 2- | sed -e 's/^ //') + FROMADD=$( + if [ -z "$(echo $FROM | grep '>$')" ]; then + echo $FROM + else + echo $FROM | grep -o '<[^<>]*>$' | sed -e 's/[<>]//g' + fi + ) + DATE=$(echo -e "${MESSAGE[@]}" | grep -m 1 "Date:" | sed -e 's/^ //') + SUBJECT=$(echo -e "${MESSAGE[@]}" | grep -m 1 "Subject:" | cut -d : -f 2- | sed -e 's/^ //') +} + +function message_list { +# compose and send a message to the list +# $1: subscriber email +# sorry no identation :P +echo "$PASSWD +Message from: $FROM +Subject: $SUBJECT +$DATE + +$(get_gpg_stderr | grep -F 'gpg: Signature made') +$(get_gpg_stderr | grep -F 'gpg: Good signature from') + +$(echo -e "$PASSWD\n${GPG_MESSAGE[@]}" | $GPGDECRYPT 2> /dev/null)" | sed -e 's/=20$//' | $GPGENCRYPT $1 | $MAIL -r $LISTNAME $1 +} + +function message_list_error { +# compose and send an error message +# sorry no identation :P +echo "$PASSWD +Message from: $FROM +Subject: [BAD SIGNATURE] $SUBJECT +$DATE + +$(get_gpg_stderr | grep -F 'gpg: Signature made') +$(get_gpg_stderr | grep -F 'gpg: BAD signature from') + +$(echo -e "$PASSWD\n${GPG_MESSAGE[@]}" | $GPGDECRYPT 2> /dev/null)" | sed -e 's/=20$//' | $GPGENCRYPT $1 | $MAIL -r $LISTNAME $1 +} + +function message_list_return { +# send a bounce message +# $1: sender email (usually $FROMADD) +# sorry no identation :P +echo " +Message from: $FROM +Subject: [RETURNED MAIL] $SUBJECT +$DATE + + [ It was not possible to process this message. Either or both + the message was not encrypted and/or signed, or you are not + subscribed to this list. Contact the list administrator if + you have any questions. ] + + -- + firma v$VERSION" | $MAIL -r $LISTNAME $1 +} + +function process_message { + # process a message sent to the list + + get_message + get_message_headers + get_gpg_message + + # if signature is Good, encrypt and send it for each list subscriber + # todo: declare a function to decrypt, re-encrypt and send the list messages + if (get_gpg_stderr | grep -Fq GOODSIG); then + + for EMAIL in $(get_subscribers_list); do + message_list $EMAIL + done + + # else, if signature is BAD, email it back to the list admins and to sender + elif (get_gpg_stderr | grep -Fq BADSIG) ; then + + for EMAIL in $(echo $LISTADMIN $FROMADD); do + message_list_error $EMAIL + done + + # else, probably either the message was not signed or the sender is not subscribed to the list + # email the message back to sender including a note about this + # todo: parse STDERR to find out why the signature couldn't be checked and send more specific errors back to sender + else + message_list_return $FROMADD + fi + +} + +function newlist { + # create a list if it doesnt already exist + if [ ! -d "$CONFIG_PATH" ]; then + echo creating folder $CONFIG_PATH... + mkdir "$CONFIG_PATH" # || (echo "error creating $CONFIG_PATH: installation aborted"; exit 1) + echo "creating list config file and will ask some questions." + + read -p "path to nail command (eg, /usr/bin/nail): " MAIL + read -p "path to gpg binary (eg, /usr/bin/gpg): " GPG + + # if [ ! -x $GPG ]; then + + read -p "list keyring folder (defaults to $GPGDIR): " GPGDIR + + # todo: please no utf-8 (see DETAILS) + read -p "list email (eg, firma@domain.tld): " LISTNAME + read -p "list admins emails (space delimited): " LISTADMIN + read -p "list description (fake?): " DESCRIPTION + read -p "password for list keyring (use a huge one): " PASSWD + + # todo: key specs (size, expiry date...) + + echo "creating your config..." + touch $CONFIG + chown root.root $CONFIG + chmod 600 $CONFIG + if [ -f $CONFIG ]; then + gpg_args + echo -e "MAIL=$MAIL\nGPG=$GPG\nGPGDIR=$GPGDIR\nLISTNAME=$LISTNAME\nLISTADMIN=$LISTADMIN\nPASSWD=$PASSWD" > $CONFIG + echo "now generating your keyring..." + + $GPGCOMMAND --gen-key < /dev/null | grep -i \<$1\>:$ | cut -d : -f 10)" ]; then + echo "$CONFIG_FILE: \"$(echo -ne $1 | tr A-Z a-z)\" is not associated with any public key on this keyring." + return 1 + elif [ "$($GPGLIST --fixed-list-mode $1 2> /dev/null | grep ^uid | wc -l)" -eq "1" ]; then + echo "$CONFIG_FILE: \"$(echo -ne $1 | tr A-Z a-z)\" is part of the only UID on public key \"$KEYID\"." + return 1 + elif [ "$($GPGLIST --fixed-list-mode $1 2> /dev/null | grep -iF $1 | cut -d : -f 10 | wc -l)" -gt "1" ]; then + echo "$CONFIG_FILE: \"$(echo -ne $1 | tr A-Z a-z)\" is listed in more than one UID on this keyring. Narrow down your selection" + echo "$CONFIG_FILE: or delete all but one of the public keys associated with this email address." + return 1 + fi + + expect -nN -- << EOF + log_user 0 + set timeout 5 + + set keyid [eval exec $GPG --fingerprint --with-colons --fixed-list-mode $1 | grep ^fpr | cut -d : -f 10] + set uid_count [eval exec $GPG --list-keys --with-colons --fixed-list-mode \$keyid | grep ^uid | wc -l] + set chosen_uid [eval exec $GPG --list-keys --with-colons --fixed-list-mode \$keyid | grep ^uid | grep -ni $1 | cut -d : -f 1] + + eval spawn -noecho $GPG --with-colons --command-fd 0 --status-fd 1 --edit-key \$keyid + expect "GET_LINE keyedit.prompt" { + set uid 1 + while { \$uid <= \$uid_count } { + if { \$uid != \$chosen_uid } { + send "uid \$uid\n" + expect "GET_LINE keyedit.prompt" + } + set uid [incr uid] + } + send "deluid\n" + expect "GET_BOOL keyedit.remove.uid.okay" {send "yes\n"} + expect "GET_LINE keyedit.prompt" {send "save\n"} + expect "GOT_IT" + } + + wait + send_user "$CONFIG_FILE: \"$(echo -ne $1 | tr A-Z a-z)\" chosen successfully. [ expr \$uid_count - 1 ] UIDs deleted from public key \"$KEYID\".\n" + interact + +EOF +} + +# main - +# command line checking +if [ -z "$2" -a "$1" != "-c" -a "$1" != "-h" -a "$1" != "-v" ]; then + usage + exit 1 +else + CONFIG_FILE="$2" + CONFIG_PATH="$FIRMA_LIST_PATH/$2" + CONFIG="$CONFIG_PATH/$2.conf" +fi + +# if the configuration file exists, disable "sourcepath" and evaluate the parameters +if [ "$1" != "-c" -a "$1" != "-h" -a "$1" != "-v" ]; then + if [ -f $CONFIG ]; then + shopt -u sourcepath && source $CONFIG + else + echo "$(basename $0): Configuration file \"$CONFIG\" could not be found." + exit 1 + fi +fi + +declare -a MESSAGE +declare -a GPG_MESSAGE +declare n +export LANG=en_US + +# get gpg parameters and check the config +if [ "$1" = "-a" -o "$1" = "-p" -o "$1" = "-r" ]; then + gpg_args + check_config +fi + +# command line parsing +if [ "$1" = "-a" ]; then + + declare -a ADMINCOMMANDS + + n=0 + while read STDIN; do + ADMINCOMMANDS[$n]="$STDIN\n" + ((n++)) + done + + for i in $(seq 0 $((${#ADMINCOMMANDS[@]} - 1))); do + if [ ! -z "$(echo -ne ${ADMINCOMMANDS[$i]})" -a "$(echo -ne ${ADMINCOMMANDS[$i]} | cut -c1)" != "#" ]; then + list_admin $(echo -ne "${ADMINCOMMANDS[$i]}") + fi + done + +elif [ "$1" = "-c" ]; then + newlist +elif [ "$1" = "-h" ]; then + usage +elif [ "$1" = "-p" ]; then + process_message +elif [ "$1" = "-r" ]; then + list_request +elif [ "$1" = "-v" ]; then + version +else + usage + exit 1 +fi + + -- cgit v1.2.3