#!/bin/bash
#
# File: /usr/local/bin/gpgswitch
#
# Process eMail with GnuPG.
#
#    Copyright (C) 2008  Juergen Kaesmann (JK)
#    Modified 2013 by Ingo Kaesmann (inka)
#
#    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
#
# Exit codes:
# Standard
# 30 = Program locked, no execution

##############################################################################
# SOURCE FILES

. /usr/local/etc/main-inka-sh.conf			# config main
. $LLIBDIR/lib-ksm-func-std.sh				# functions general

##############################################################################
# DECLARATION OF VARIABLES

# STRINGS
pkgname=ksm-gpgswitch-inka
version=$(grep "^VERSION" $PROGREG/$pkgname.inf | cut -f 2)	# version
lib_func_std_sh_needed=0.2.0
#lib_func_ip_sh_needed=0.2.0
#lib_func_cddvd_sh_needed=0.3.0
scriptname=`basename $0`				# name of script
tempfile=$TEMPDIR/$scriptname.$UID.$$.tmp		# temporary file
infolog="logger -p user.info -t $scriptname --"		# log info messages
errlog="logger -p user.err -t $scriptname -- ERROR:"	# log error messages
debuglog="logger -p user.debug -t $scriptname -- DEBUG:" # log debug messages
debug=no			# debug=yes/no, debug output goes to debuglog
verbose=''						# verbose=yes/''/no
cmd_found=no						# cmd_found=yes/no
opt_found=no						# opt_found=yes/no
cmd=''							# cmd
#------------------End Of Standard Variables----------------------------------
debug1=no	# debug1=yes/no, additional debug output goes to debuglog
debug2=no	# debug2=yes/no, redir mail to stdout instead to sendmail

lockfile=$TEMPDIR/$scriptname.LOCK
tempfile1=$TEMPDIR/$scriptname.$UID.t1.tmp
tempfile2=$TEMPDIR/$scriptname.$UID.t2.tmp
headerfile=$TEMPDIR/$scriptname.$UID.h.tmp
bodyfile=$TEMPDIR/$scriptname.$UID.b.tmp
attfile1=$TEMPDIR/$scriptname.$UID.a1.tmp
attfile2=$TEMPDIR/$scriptname.$UID.a2.tmp
pgpfile=$TEMPDIR/$scriptname.$UID.p.tmp
decrfile=$TEMPDIR/$scriptname.$UID.d.tmp
encrfile=$TEMPDIR/$scriptname.$UID.e.tmp
statfile=$TEMPDIR/$scriptname.$UID.s.tmp
funcfile=$TEMPDIR/$scriptname.$UID.f.tmp
funcrfile=$TEMPDIR/$scriptname.$UID.r.tmp

ffile="/var/local/$pkgname/gpgswitch.on"		# Flag file
sendmail='/usr/sbin/sendmail -oem -oi'			# how to call sendmail
hostname=`hostname --fqdn`				# FQDN
date_rfc="`date -R` `date '+(%Z)'`"
gpguserfile='/usr/local/etc/gpguser.conf'		# user, id, key file
gpgsw_mail=''

hdrenc="X-gpgswitch-encrypted: by $hostname"		# incl hdr if encrypt
hdrsig="X-gpgswitch-signed: by $hostname"		# incl hdr if signed
hdrdec="X-gpgswitch-decrypted: by $hostname"		# incl hdr if decrypt
hdrver="X-gpgswitch-verified: by $hostname"		# incl hdr if verified
hdrsta="X--"						# incl hdr res of ver

begmsg='^-----BEGIN PGP MESSAGE-----$'
endmsg='^-----END PGP MESSAGE-----$'
begsig='^-----BEGIN PGP SIGNATURE-----$'
endsig='^-----END PGP SIGNATURE-----$'
begcsig='^-----BEGIN PGP SIGNED MESSAGE-----$'
endcsig='^-----END PGP SIGNED MESSAGE-----$'

hdr_enc_bnd='Boundary_gpgswitch_Encrypted_Con_Purzel'
hdr_enc_mul="Content-Type: multipart/encrypted; protocol=\"application/pgp-encrypted\";
	boundary=\"${hdr_enc_bnd}\""

hdr_sig_bnd='Boundary_gpgswitch_Signed_Con_Susi'
hdr_sig_mul="Content-Type: multipart/signed; micalg=pgp-sha1;
	protocol=\"application/pgp-signature\"; boundary=\"${hdr_sig_bnd}\""
hdr_sig_sig='Content-Type: application/pgp-signature
Content-Disposition: inline'

hdr_all_enc='Content-Type: application/pgp-encrypted
Content-Disposition: attachment'
hdr_all_oct='Content-Type: application/octet-stream
Content-Disposition: inline; filename="msg.asc"'
hdr_all_teq='Content-Transfer-Encoding: quoted-printable'
hdr_all_ted=''

user=''							# gpgswitch runs for
secrkeyfile=''						# user passwordfile
mykeyid=''						# key id (eMail)
global_result=''					# result of functions

# NUMBERS
maxwait=10						# wait for unlock (sec)
err=0
i=0

##############################################################################
# FUNCTIONS

#-----------------------------------------------------------------------------
function helptext ()
{
# Output helptext
# Uses: cat
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog helptext: $# $@
fi

cat <<EOT

Aufruf: $scriptname OPTION [PARAMETER]...
Entschluesselt/verifiziert/verschluesselt/signiert E-Mails mit GnuPG

-h, --help      Hilfe anzeigen und beenden
 --version      Versionsinformationen ausgeben und beenden
        -i      eingehende E-Mail
        -o      ausgehende E-Mail
        -s      E-Mail kommt per SMTP

PARAMETER       mit -o, -s: weitere Parameter fuer 'sendmail'

EOT

return
}
#-----------------------------------------------------------------------------
function get_local_config ()
{
# Get local config and set global vars. If needed update ~/.gpgswitchrc
# par1 = user
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_local_config: $# $@
fi

local user ret
user="$1"
ret=0

if [ -e $HOME/.gpgswitchrc ]; then			# user config file
	. $HOME/.gpgswitchrc				# source config file

	# check version of config files
	if [ "$version" != "$GPGswitch_Rc" ]; then
		$errlog user $user, version of config file differ - call update-gpgswitch
		update-gpgswitch -q
		ret=$?
		. $HOME/.gpgswitchrc			# source config file
	fi

	if [ "$ret" -eq 0 ]; then
		defcs=$gpg_def_charset			# default charset
		defenc=$gpg_def_encoding		# default encoding
		usrcnt="${#gpg_user[@]}"		# num usr auto encrypt
		sigusrcnt="${#gpg_siguser[@]}"		# num usr auto sig+encr
		excl_usrcnt="${#gpg_exclude_user[@]}" # num usr excl from inco.
		secrkeyfile=/home/$user/.gpgkey		# local password file
		hdr_all_ted="Content-Transfer-Encoding: ${defenc}"
	fi

else
	ret=1
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_user ()
{
# get the user of an key id out of gpguserfile
# par1 = key id
# Uses: cat, cut, grep
# output goes to global var 'global_result'
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_user: $# $@
fi

local keyid s l ret
keyid=$1
s=''
l=0
ret=0

s=`cat $gpguserfile | cut -d ';' -f 2 | grep -n -m 1 "^${keyid}\$"`
ret=$?
if [ "$ret" -eq 0 ]; then				# keyid found
	l=${s%%:*}					# rm ':*' from EOL
	s=`Get_Lines $gpguserfile $l $l`
	ret=$?
	if [ "$ret" -eq 0 ]; then
		global_result=${s%%;*}
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_keyid ()
{
# get the gpg key id of an user out of gpguserfile
# par1 = user
# Uses: cat, cut, grep
# output goes to global var 'global_result'
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_keyid: $# $@
fi

local luser s l ret
luser=$1
s=''
l=0
ret=0

s=`cat $gpguserfile | cut -d ';' -f 1 | grep -n -m 1 "^${luser}\$"`
ret=$?
if [ "$ret" -eq 0 ]; then
	l=${s%%:*}					# rm ':*' from EOL
	s=`Get_Lines $gpguserfile $l $l`
	ret=$?
	if [ "$ret" -eq 0 ]; then
		s=${s#*;}
		global_result=${s%;*}
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_mail_header ()
{
# extract a multiple line header from a mail (';' at EOL, 1. found)
# par1 = filename
# par2 = searchstring
# uses global vars: global_result
# Uses: cat, grep, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_mail_header: $# $@
fi

local fn ss s sl i n ret
fn=$1							# file name
ss=$2							# search string
s=''
sl=''							# start line
i=0
n=0							# lines in file
ret=0

s=`grep -n -m 1 "$ss" $fn`				# search str in file
ret=$?
if [ "$ret" -eq 0 ]; then				# searchstr found
	n=`cat $fn | wc -l`				# n = lines in file
	ret=$?
	sl=${s%%:*}					# rm ':*' from EOL
	i=$sl
	while [ "$i" -lt $n ] && [ "${s:$[${#s}-1]}" == ";" ] && \
	  [ "$ret" -eq 0 ]; do			# repeat if last char = ';'
		let i++
		s=`Get_Lines $fn $i $i`
		ret=$?
	done
	if [ "$ret" -eq 0 ]; then
		s=`Get_Lines $fn $sl $i`		# get all hdr lines
		ret=$?
		if [ "$ret" -eq 0 ]; then		# lines are ok
			global_result=$s
		fi
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function remove_mail_header ()
{
# remove a multiple line header from a mail (';' at EOL, 1. found)
# par1 = filename
# par2 = searchstring
# Uses: cat, cp, grep, rm, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog remove_mail_header: $# $@
fi

local fn ss tf s sl i n ret
fn=$1							# file name
ss=$2							# search string
tf=$funcfile						# local tempfile
s=''
sl=''							# start line
i=0
n=0							# lines in file
ret=0

s=`grep -n -m 1 "$ss" $fn`				# search str in file
ret=$?
if [ "$ret" -eq 0 ]; then				# searchstr found
	n=`cat $fn | wc -l`				# n = lines in file
	ret=$?
	sl=${s%%:*}					# rm ':*' from EOL
	i=$sl
	while [ "$i" -lt $n ] && [ "${s:$[${#s}-1]}" == ";" ] && \
	  [ "$ret" -eq 0 ]; do			# repeat if last char = ';'
		let i++
		s=`Get_Lines $fn $i $i`
		ret=$?
	done
	if [ "$ret" -eq 0 ]; then
		Remove_Lines $fn $sl $i > $tf		# remove lines
		ret=$?
		if [ "$ret" -eq 0 ]; then		# remove is ok
			cp $tf $fn
		fi
		rm -f $tf
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_and_remove_mail_header ()
{
# extract and remove a multiple line header from a mail (';' at EOL, 1. found)
# par1 = filename
# par2 = searchstring
# uses global vars: global_result
# Uses: cat, cp, grep, rm, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_and_remove_mail_header: $# $@
fi

local fn ss tf s sl i n ret
fn=$1							# file name
ss=$2							# search string
tf=$funcfile						# local tempfile
s=''
sl=''							# start line
i=0
n=0							# lines in file
ret=0

s=`grep -n -m 1 "$ss" $fn`				# search str in file
ret=$?
if [ "$ret" -eq 0 ]; then				# searchstr found
	n=`cat $fn | wc -l`				# n = lines in file
	ret=$?
	sl=${s%%:*}					# rm ':*' from EOL
	i=$sl
	while [ "$i" -lt $n ] && [ "${s:$[${#s}-1]}" == ";" ] && \
	  [ "$ret" -eq 0 ]; do			# repeat if last char = ';'
		let i++
		s=`Get_Lines $fn $i $i`
		ret=$?
	done
	if [ "$ret" -eq 0 ]; then
		s=`Get_Lines $fn $sl $i`		# get all hdr lines
		ret=$?
		if [ "$ret" -eq 0 ]; then		# lines are ok
			global_result=$s
			Remove_Lines $fn $sl $i > $tf	# remove lines
			ret=$?
			if [ "$ret" -eq 0 ]; then	# remove is ok
				cp $tf $fn
			fi
			rm -f $tf
		fi
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function replace_mail_header ()
{
# replace a multiple line header in a mail (';' at EOL, 1. found)
# par1 = filename
# par2 = searchstring
# par3 = replacestring
# Uses: cat, cp, grep, rm, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog replace_mail_header: $# $@
fi

local fn ss rs tf s sl i n ret
fn=$1							# file name
ss=$2							# search string
rs=$3							# replace string
tf=$funcfile						# local tempfile
s=''
sl=0							# start line
i=0
n=0							# lines in file
ret=0

s=`grep -n -m 1 "$ss" $fn`				# search str in file
ret=$?
if [ "$ret" -eq 0 ]; then				# searchstr found
	n=`cat $fn | wc -l`				# n = lines in file
	ret=$?
	sl=${s%%:*}					# rm ':*' from EOL
	i=$sl
	while [ "$i" -lt $n ] && [ "${s:$[${#s}-1]}" == ";" ] && \
	  [ "$ret" -eq 0 ]; do			# repeat if last char = ';'
		let i++
		s=`Get_Lines $fn $i $i`
		ret=$?
	done
	if [ "$ret" -eq 0 ]; then
		Remove_Lines $fn $sl $i > $tf		# remove lines
		ret=$?
		if [ "$ret" -eq 0 ]; then		# remove is ok
			cp $tf $fn
			Insert_Line $fn $[${sl}-1] "$rs" > $tf	# insert line
			ret=$?
			if [ "$ret" -eq 0 ]; then	# insert is ok
				cp $tf $fn
			fi
		fi
		rm -f $tf
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function split_to_header_body ()
{
# split a mailfile into header and body file
# par1 = name of mailfile
# par2 = name of headerfile
# par3 = name of bodyfile
# par4 = optional gpgswitch hdr to include
# Uses: cat, echo, grep, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog split_to_header_body: $# $@
fi

local fm fh fb hd s eh n ret
fm=$1							# mail file
fh=$2							# header file
fb=$3							# body file
hd="$4"							# gpgswitch hdr
s=''
eh=0
n=0
ret=0

# get end of headers
s=`grep -n -m 1 '^$' $fm`
ret=$?
if [ "$ret" -eq 0 ]; then				# end of headers found
	eh=${s%%:*}					# rm ':*' from EOL
	# save headers to file
	Get_Lines $fm 1 $[${eh}-1] > $fh		# lines to end of hdr
	ret=$?
	if [ "$ret" -eq 0 ]; then			# end of headers found
		if [ "$hd" != "" ]; then
			echo "$hd" >> $fh		# incl gpgswitch hdr
		fi
		echo "" >> $fh				# incl last hdr line

		# save body to file
		n=`cat $fm | wc -l`			# n = lines in file
		ret=$?
		Get_Lines $fm $[${eh}+1] $n > $fb	# lines till eof
		ret=$?
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_boundary ()
{
# get the boundary which is set in a headerfile (1. found).
# par1 = name of file to search for boundary
# Uses: grep
# return boundary in global_result
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_boundary: $# $@
fi

local fn s ret
fn=$1
s=''
ret=0

s=`grep -m 1 'boundary=' $fn`
ret=$?
if [ "$ret" -eq 0 ]; then
	s=${s/*boundary=\"/}
	global_result=${s%%\"*}				# boundary string
else
	global_result=''
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_charset ()
{
# get the charset of a file (1. found).
# par1 = name of file to search for charset
# Uses: grep
# return charset in global_result
# if not found then return default charset
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_charset: $# $@
fi

local fn s ret
fn=$1
s=''
ret=0

# get charset
s=`grep -m 1 'charset=' $fn`
ret=$?
if [ "$ret" -eq 0 ]; then
	s=${s/*charset=/}
	global_result=${s%%;*}				# charset value
else
	global_result=$defcs
fi

return $ret
}
#-----------------------------------------------------------------------------
function split_to_2atts ()
{
# split the file in 2 attachments (boundary stripped off).
# each attachment consists of a header and a body part.
# par1 = name of file to split
# par2 = name of file to give 1. attachment
# par3 = name of file to give 2. attachment
# par4 = boundary
# Uses: cat, echo, grep, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog split_to_2atts: $# $@
fi

local fm fh fb bo s n i b1 b2 b3 ret
fm=$1
fh=$2
fb=$3
bo=$4
s=''
n=0
i=0
b1=0
b2=0
b3=0
ret=0

s=`grep -n -m 1 "^\-\-$bo" $fm`
ret=$?
if [ "$ret" -eq 0 ]; then				# 1. boundary
	b1=${s%%:*}					# rm ':*' form EOL
	n=`cat $fm | wc -l`				# n = lines in file
	ret=$?
	i=$b1
	while [ "$i" -lt $n ]; do
		let i++
		s=`Get_Lines $fm $i $i`
		ret=$?
		if [ "$ret" -eq 0 ]; then
			s=`echo "$s" | grep "^\-\-$bo"`
			ret=$?
			if [ "$ret" -eq 0 ]; then	# 2. boundary
				b2=$i
				break
			fi
		fi
	done
	if [ "$ret" -eq 0 ]; then
		s=`grep -n -m 1 "^\-\-$bo\-\-" $fm`
		ret=$?
		if [ "$ret" -eq 0 ]; then		# last. boundary
			b3=${s%%:*}			# rm ':*' form EOL
			Get_Lines $fm $[$b1+1] $[$b2-2] > $fh	# 1. attachment
			ret=$?
			Get_Lines $fm $[$b2+1] $[$b3-2] > $fb	# 2. attachment
			ret=$?
		fi
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_and_remove_hdr_received ()
{
# get a received header out of a file and remove it from file (1. found)
# par1 = name of headerfile
# Uses: cat, cp, grep, rm, wc
# return hdr in global_result
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_and_remove_hdr_received: $# $@
fi

local fn tf s found i l ls le ret
fn=$1							# file
tf=$funcrfile						# local tempfile
s=''
found=no
i=0
l=0
ls=0							# srch start line
le=0							# srch end line
ret=0

# search 1. received-hdr
s=`grep -n -m 1 'Received:' $fn`
ret=$?
if [ "$ret" -eq 0 ]; then				# hdr found
	ls=${s%%:*}					# start line number
	l=`cat $fn | wc -l`				# numb of lins in file
	ret=$?
	found=no
	i=$ls
	while [ "$ret" -eq 0 ] && [ "$found" == "no" ] && [ "$i" -lt $l ]; do
		let i++					# rep till nxt hdr
		s=`Get_Lines $fn $i $i`
		ret=$?
		if [ "$ret" -eq 0 ] && [ "${s:0:1}" \> ' ' ]; then
			found=yes
			le=$[${i}-1]
		fi
	done
	if [ "$ret" -eq 0 ] && [ "$found" == "no" ] && [ "$i" -eq $l ]; then
		found=yes
		le=$i
	fi
	if [ "$found" == "yes" ]; then			# hdr lines found
		s=`Get_Lines $fn $ls $le`
		ret=$?
		if [ "$ret" -eq 0 ]; then		# get lines is ok
			Remove_Lines $fn $ls $le > $tf	# remove lines
			ret=$?
			if [ "$ret" -eq 0 ]; then	# remove is ok
				cp $tf $fn
			fi
			rm -f $tf
			global_result=$s
		fi
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function insert_hdr_received ()
{
# insert a received header in a file with headers
# par1 = name of headerfile
# Uses: cp, cut, echo, gethostip, grep, rm
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog insert_hdr_received: $# $@
fi

local fn tf s sl sr hdr fromhost fromip recip l ret
fn=$1
tf=$funcrfile						# local tempfile
s=''
sl=''							# left string
sr=''							# right string
hdr=''							# received hdr
fromhost=''
fromip=''
recip=''
l=0
ret=0

# sender host ist locally
fromhost=$hostname
# get sender IP from sender host
fromip=`gethostip -d $fromhost`
ret=$?
if [ "$ret" -ne 0 ]; then
	fromip='unknown-IP'
fi

# get 1. recipient from 'To: ' header
s=`grep -m 1 '^To: ' $fn`
ret=$?
if [ "$ret" -eq 0 ]; then				# end of headers found
	sl=`echo "$s" | cut -d '@' -f 1`
	sr=`echo "$s" | cut -d '@' -f 2`
	sl=${sl//</ }
	sl=${sl//(/ }
	sl=${sl##* }
	sr=${sr//>/ }
	sr=${sr//)/ }
	sr=${sr%% *}
	recip="${sl}@${sr}"
else
	recip='unknown-recipient'
fi

hdr="Received: from ${fromhost} [${fromip}]
	by ${hostname} (gpgswitch-${version})
	for <${recip}>; ${date_rfc}"

# check 1. line
s=`Get_Lines $fn 1 1`
ret=$?
if [ "$ret" -eq 0 ]; then
	s=${s%% *}					# separate 1. word
	if [ "$s" == "From" ]; then			# line number = 1
		l=1
	else						# line number = 0
		l=0
	fi
	# insert hdr after given line
	Insert_Line $fn $l "$hdr" > $tf			# insert line
	ret=$?
	cp $tf $fn
	rm -f $tf
fi

return $ret
}
#-----------------------------------------------------------------------------
function decrypt_mail ()
{
# decode an old plain style mail or
# decode a pgp/mime encrypted mail or
# decode a pgp/mime signed and encrypted mail.
# recode quoted-printable msg to default encoding
# Uses: cat, cp, egrep, gpg, grep, recode, rm, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog decrypt_mail: $# $@
fi

local cs s sfr sto fsig sm em i n ret
cs=''							# charset
s=''
sfr=''
sto=''
fsig=no
sm=0							# start of msg
em=0							# end of msg
i=0
n=0							# lines in file
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile "$hdrdec"
ret=$?

s=`grep -n -m 1 "$begmsg" $bodyfile`
ret=$?
if [ "$ret" -eq 0 ]; then				# start msg
	sm=${s%%:*}
fi

s=`grep -n -m 1 "$endmsg" $bodyfile`
ret=$?
if [ "$ret" -eq 0 ]; then				# end msg
	em=${s%%:*}
fi

Get_Lines $bodyfile $sm $em > $pgpfile			# msg part
ret=$?

egrep -q -m 1 'protocol="application/pgp-encrypted"' $headerfile
ret=$?
if [ "$ret" -eq 0 ]; then				# mail is pgp/mime
	if [ "$debug1" == "yes" ]; then			# DEBUG1
		$debuglog gpgswitch decrypt_mail pgp/mime: secrkeyfile=$secrkeyfile
	fi

	# decrypt a pgp/mime attachment
	/usr/bin/gpg --status-fd=2 --passphrase-fd 0 --no-verbose --quiet --batch --output - $pgpfile < $secrkeyfile > $decrfile 2>$statfile
	ret=$?
	if [ "$ret" -eq 0 ] || [ "$ret" -eq 1 ]; then	# gpg ok
		# set up headers
		# rm Content-Type
		remove_mail_header $headerfile "^Content-Type: "
		ret=$?

		# rm Content-Disposition
		remove_mail_header $headerfile "^Content-Disposition: "
		ret=$?

		# rm Content-Transfer-Encoding
		remove_mail_header $headerfile "^Content-Transfer-Encoding: "
		ret=$?

		# rm last line from headerfile
		n=`cat $headerfile | wc -l`		# n = lines in file
		ret=$?
		Remove_Lines $headerfile $n $n > $tempfile1
		ret=$?
		cp $tempfile1 $headerfile

		# get gpg: msgs from statfile
		n=`cat $statfile | wc -l`		# n = lines in file
		ret=$?
		fsig=no
		i=0
		while [ "$i" -lt $n ]; do
			let i++
			s=`Get_Lines $statfile $i $i | grep '^gpg: '`
			ret=$?
			if [ "$ret" -eq 0 ]; then	# gpg hdr found
				echo "${hdrsta}${s}" >> $headerfile
				fsig=yes
			fi
		done
		if [ "$fsig" == "yes" ]; then		# insert hdrver
			# find hdrdec
			s=`grep -n -m 1 "$hdrdec" $headerfile`
			ret=$?
			if [ "$ret" -eq 0 ]; then	# line number hdrdec
				i=${s%%:*}
				# insert hdrver
				Insert_Line $headerfile $i "$hdrver" > $tempfile1
				ret=$?
				cp $tempfile1 $headerfile
			fi
		fi

		# set up body
		# get charset
		get_charset $decrfile
		ret=$?
		cs=$global_result

		# change CR-LF --> LF
		recode -q ${cs}/CR-LF..${cs} $decrfile
		ret=$?

		# split msg into msg hdr and msg body
		split_to_header_body $decrfile $tempfile1 $tempfile2
		ret=$?
		if [ "$ret" -eq 0 ]; then
			# if quoted-printable then decode msg body to default encoding (1. found)
			grep -q -m 1 "^Content-Transfer-Encoding: quoted-printable" $tempfile1
			ret=$?
			if [ "$ret" -eq 0 ]; then		# quoted-printabl found
				# recode quoted-printable to default encoding
				recode ${cs}/QP..${cs} $tempfile2
				ret=$?

				# replace Content-Transfer-Encoding (1. found)
				replace_mail_header $tempfile1 "^Content-Transfer-Encoding: " "$hdr_all_ted"
				ret=$?
			fi
			cat $headerfile $tempfile1 $tempfile2
			ret=$?
		else
			cat $headerfile $decrfile
		fi
		s=`grep -i -m 1 '^Message-ID: ' $tempfile`
		sfr=`grep -m 1 '^From: ' $tempfile`
		sto=`grep -m 1 '^To: ' $tempfile`
		$infolog mail $sfr $sto $s, pgp/mime decrypt
	else						# gpg not ok
		cat $tempfile				# output original mail
	fi
else							# mail is old style
	if [ "$debug1" == "yes" ]; then			# DEBUG1
		$debuglog gpgswitch decrypt_mail application/pgp: secrkeyfile=$secrkeyfile
	fi

	# decode application/pgp
	/usr/bin/gpg --charset utf-8 --status-fd=2 --passphrase-fd 0 --no-verbose --quiet --batch --output - $bodyfile < $secrkeyfile > $decrfile 2>$statfile
	ret=$?
	if [ "$ret" -eq 0 ]; then			# gpg ok
		# get charset
		get_charset $headerfile
		ret=$?
		cs=$global_result

		# change CR-LF --> LF
		recode -q ${cs}/CR-LF..${cs} $decrfile
		ret=$?

		# output decrypted mail
		cat $headerfile $decrfile
		ret=$?
		s=`grep -i -m 1 '^Message-ID: ' $tempfile`
		sfr=`grep -m 1 '^From: ' $tempfile`
		sto=`grep -m 1 '^To: ' $tempfile`
		$infolog mail $sfr $sto $s, old application/pgp decrypt
	else						# gpg not ok
		cat $tempfile				# output original mail
	fi
fi

rm -f $tempfile1
rm -f $tempfile2
rm -f $headerfile
rm -f $bodyfile
rm -f $pgpfile
rm -f $decrfile
rm -f $statfile

return $ret
}
#-----------------------------------------------------------------------------
function verify_pgp_mime ()
{
# verify a pgp/mime signed mail.
# recode quoted-printable msg to default encoding
# set headers 'X--gpg: ' according to the result
# Uses: cat, cp, echo, gpg, grep, recode, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog verify_pgp_mime: $# $@
fi

local cs s sfr sto bo ss es i n ret
cs=''							# charset
s=''
sfr=''
sto=''
bo=''							# boundary
ss=0							# start sig
es=0							# end sig
i=0
n=0
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile "$hdrver"
ret=$?

# split body in msgpart and sigpart
get_boundary $headerfile
ret=$?
bo=$global_result					# boundary
split_to_2atts $bodyfile $attfile1 $attfile2 "$bo"
ret=$?

s=`grep -n -m 1 "$begsig" $attfile2`
ret=$?
if [ "$ret" -eq 0 ]; then				# start sig
	ss=${s%%:*}
fi

s=`grep -n -m 1 "$endsig" $attfile2`
ret=$?
if [ "$ret" -eq 0 ]; then				# end sig
	es=${s%%:*}
fi

Get_Lines $attfile2 $ss $es > $pgpfile			# sig part
ret=$?

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch verify_pgp_mime:
fi

# verify a pgp/mime signature
/usr/bin/gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify $pgpfile $attfile1 2>$statfile
ret=$?
if [ "$ret" -eq 0 ] || [ "$ret" -eq 1 ]; then		# gpg ok
	# set up headers
	# rm Content-Type
	remove_mail_header $headerfile "^Content-Type: "
	ret=$?

	# rm Content-Disposition
	remove_mail_header $headerfile "^Content-Disposition: "
	ret=$?

	# rm Content-Transfer-Encoding
	remove_mail_header $headerfile "^Content-Transfer-Encoding: "
	ret=$?

	# rm last line from headerfile
	n=`cat $headerfile | wc -l`			# n = lines in file
	ret=$?
	Remove_Lines $headerfile $n $n > $tempfile2	# rm last hdr line
	ret=$?
	cp $tempfile2 $headerfile

	# get gpg: msgs from statfile to hdr file
	n=`cat $statfile | wc -l`			# n = lines in file
	ret=$?
	i=0
	while [ "$i" -lt $n ]; do
		let i++
		s=`Get_Lines $statfile $i $i | grep '^gpg: '`
		ret=$?
		if [ "$ret" -eq 0 ]; then		# gpg header found
			echo "${hdrsta}${s}" >> $headerfile
		fi
	done

	# set up body
	# split msg into msg hdr and msg body
	split_to_header_body $attfile1 $tempfile1 $tempfile2
	ret=$?

	# if quoted-printable then decode msg body to default encoding (1. found)
	grep -q -m 1 "^Content-Transfer-Encoding: quoted-printable" $tempfile1
	ret=$?
	if [ "$ret" -eq 0 ]; then			# quoted-printabl found
		# get charset
		get_charset $tempfile1
		ret=$?
		cs=$global_result

		# recode quoted-printable to default encoding
		recode ${cs}/QP..${cs} $tempfile2
		ret=$?

		# replace Content-Transfer-Encoding (1. found)
		replace_mail_header $tempfile1 "^Content-Transfer-Encoding: " "$hdr_all_ted"
		ret=$?
	fi
	cat $headerfile $tempfile1 $tempfile2
	ret=$?
	s=`grep -i -m 1 '^Message-ID: ' $tempfile`
	sfr=`grep -m 1 '^From: ' $tempfile`
	sto=`grep -m 1 '^To: ' $tempfile`
	$infolog mail $sfr $sto $s, pgp/mime verify
else							# gpg not ok
	cat $tempfile					# output original mail
fi

rm -f $tempfile1
rm -f $tempfile2
rm -f $headerfile
rm -f $bodyfile
rm -f $attfile1
rm -f $attfile2
rm -f $pgpfile
rm -f $statfile

return $ret
}
#-----------------------------------------------------------------------------
function verify_old ()
{
# verify a clear signed mail
# do nothing but give out the original file
# let the mailer verify the mail
# Uses: cat
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog verify_old: $# $@
fi
if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog verify_old:
fi

cat $tempfile						# give original out

return
}
#-----------------------------------------------------------------------------
function encrypt_pgp_mime ()
{
# encrypt any mail to a pgp/mime encoded mail.
# pars = all cmdline pars
# check for 2 types:
# a) plain text mail is encrypted and a pgp/mime attachment is build
#    including the gpg attachment. filename=msg.asc
# b) multipart mail - all attachments incl. headers are encrypted as 1 block.
#    filename=msg.asc
# the headers Content-Type, Content-Disposition, Content-Transfer-Encoding
# are incl. at top of file to encrypt.
# Uses: cat, cp, cut, echo, egrep, gpg, grep, pgpewrap, recode, rm, sendmail
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog encrypt_pgp_mime: $# $@
fi

local cs r s sfr sto fqp ret
cs=''							# charset of body
r=''							# recipient address
s=''
sfr=''
sto=''
fqp=no
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile "$hdrenc"
ret=$?

# test if body is attachment
egrep -q -m 1 '^Content-Type: multipart' $headerfile
ret=$?
if [ "$ret" -ne 0 ]; then				# no attachment
	# get charset
	get_charset $headerfile
	ret=$?
	cs=$global_result

	# transform body to quoted printable
	recode ${cs}..${cs}/QP $bodyfile
	ret=$?

	fqp=yes						# set flag quotd prtbl
fi

# get 1. recipient from 'To: ' header
r=`grep -m 1 '^To: ' $headerfile | cut -d '<' -f 2 | cut -d '>' -f 1`
ret=$?

# get headers to incl in encrypted attachment
cp /dev/null $tempfile1
get_mail_header $headerfile '^Content-Type: '
ret=$?
if [ "$ret" -eq 0 ]; then
	echo "$global_result" >> $tempfile1
fi

get_mail_header $headerfile '^Content-Disposition: '
ret=$?
if [ "$ret" -eq 0 ]; then
	echo "$global_result" >> $tempfile1
fi

if [ "$fqp" == "yes" ]; then
	echo "$hdr_all_teq" >> $tempfile1
else
	get_mail_header $headerfile '^Content-Transfer-Encoding: '
	ret=$?
	if [ "$ret" -eq 0 ]; then
		echo "$global_result" >> $tempfile1
	else
		echo "$hdr_all_ted" >> $tempfile1
	fi
fi

# complete new bodyfile
echo "" >> $tempfile1
cat $bodyfile >> $tempfile1
cp $tempfile1 $bodyfile

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch encrypt_pgp_mime: rTo=$r $@
fi

# create a pgp/mime encrypted attachment
pgpewrap /usr/bin/gpg --charset utf-8 --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r $r -- $bodyfile > $encrfile
ret=$?
if [ "$ret" -eq 0 ]; then				# gpg ok
	# replace Content-Type: in header file
	replace_mail_header $headerfile '^Content-Type: ' "$hdr_enc_mul"
	ret=$?

	# build bodyfile
	echo "" > $tempfile1
	echo "--${hdr_enc_bnd}" >> $tempfile1
	echo "$hdr_all_enc" >> $tempfile1
	echo "" >> $tempfile1

	echo "Version: 1" >> $tempfile1

	echo "" >> $tempfile1
	echo "--${hdr_enc_bnd}" >> $tempfile1
	echo "$hdr_all_oct" >> $tempfile1
	echo "" >> $tempfile1

	cat $encrfile >> $tempfile1

	echo "" >> $tempfile1
	echo "--${hdr_enc_bnd}--" >> $tempfile1

	# give sendmail the encrypted mail and additional params
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $headerfile $tempfile1
	else
		cat $headerfile $tempfile1 | $sendmail $@
	fi
	ret=$?
	s=`grep -i -m 1 '^Message-ID: ' $tempfile`
	sfr=`grep -m 1 '^From: ' $tempfile`
	sto=`grep -m 1 '^To: ' $tempfile`
	$infolog mail $sfr $sto $s, pgp/mime encrypt
else							# gpg not ok
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $tempfile
	else
		cat $tempfile | $sendmail $@
	fi
	ret=$?
fi

rm -f $tempfile1
rm -f $headerfile
rm -f $bodyfile
rm -f $encrfile

return $ret
}
#-----------------------------------------------------------------------------
function encrypt_old ()
{
# encrypt an old plain style mail
# pars = all cmdline pars
# Uses: cat, cut, grep, pgpewrap, gpg, rm, sendmail
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog encrypt_old: $# $@
fi

local r s sfr sto ret
r=''
s=''
sfr=''
sto=''
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile "$hdrenc"
ret=$?

# get 1. recipient from 1. 'To: ' header
r=`grep -m 1 '^To: ' $headerfile | cut -d '<' -f 2 | cut -d '>' -f 1`
ret=$?

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch encrypt_old: rTo=$r $@
fi

# create an application/pgp encrypted attachment
pgpewrap /usr/bin/gpg --charset utf-8 --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r $r -- $bodyfile > $encrfile
ret=$?
if [ "$ret" -eq 0 ]; then				# gpg ok
	# give sendmail the encrypted mail and additional params
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $headerfile $encrfile
	else
		cat $headerfile $encrfile | $sendmail $@
	fi
	ret=$?
	s=`grep -i -m 1 '^Message-ID: ' $tempfile`
	sfr=`grep -m 1 '^From: ' $tempfile`
	sto=`grep -m 1 '^To: ' $tempfile`
	$infolog mail $sfr $sto $s, old application/pgp encrypt
else							# gpg not ok
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $tempfile
	else
		cat $tempfile | $sendmail $@
	fi
	ret=$?
fi

rm -f $headerfile
rm -f $bodyfile
rm -f $encrfile

return $ret
}
#-----------------------------------------------------------------------------
function sign_pgp_mime ()
{
# sign a mail pgp/mime encoded
# pars = all cmdline pars
# Uses: cat, cp, echo, egrep, gpg, grep, recode, rm, sendmail
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog sign_pgp_mime: $# $@
fi

local cs s sfr sto fqp ret
cs=''
s=''
sfr=''
sto=''
fqp=no
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile "$hdrsig"
ret=$?

# test if body is attachment
egrep -q -m 1 '^Content-Type: multipart' $headerfile
ret=$?
if [ "$ret" -ne 0 ]; then				# no attachment
	# get charset
	get_charset $headerfile
	ret=$?
	cs=$global_result

	# transform body to quoted printable
	recode ${cs}..${cs}/QP $bodyfile
	ret=$?

	fqp=yes						# set flag quotd prtbl
fi

# get headers to incl in signed attachment
cp /dev/null $tempfile1
get_mail_header $headerfile '^Content-Type: '
ret=$?
if [ "$ret" -eq 0 ]; then
	echo "$global_result" >> $tempfile1
fi

get_mail_header $headerfile '^Content-Disposition: '
ret=$?
if [ "$ret" -eq 0 ]; then
	echo "$global_result" >> $tempfile1
fi

if [ "$fqp" == "yes" ]; then
	echo "$hdr_all_teq" >> $tempfile1
else
	get_mail_header $headerfile '^Content-Transfer-Encoding: '
	ret=$?
	if [ "$ret" -eq 0 ]; then
		echo "$global_result" >> $tempfile1
	else
		echo "$hdr_all_ted" >> $tempfile1
	fi
fi

# complete new bodyfile
echo "" >> $tempfile1
cat $bodyfile >> $tempfile1
cp $tempfile1 $bodyfile

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch sign_pgp_mime: secrkeyfile=$secrkeyfile mykeyid=$mykeyid $@
fi

# create a pgp/mime signed attachment
/usr/bin/gpg --no-verbose --batch --quiet --output - --passphrase-fd 0 --armor --detach-sign --textmode -u $mykeyid $bodyfile < $secrkeyfile > $encrfile
ret=$?
if [ "$ret" -eq 0 ]; then				# gpg ok
	# replace Content-Type: in header file
	replace_mail_header $headerfile '^Content-Type: ' "$hdr_sig_mul"
	ret=$?

	# build multipart pgp/mime attachments (tempfile1)
	echo "" > $tempfile1
	echo "--${hdr_sig_bnd}" >> $tempfile1

	cat $bodyfile >> $tempfile1

	echo "" >> $tempfile1
	echo "--${hdr_sig_bnd}" >> $tempfile1
	echo "$hdr_sig_sig" >> $tempfile1
	echo "" >> $tempfile1

	cat $encrfile >> $tempfile1

	echo "" >> $tempfile1
	echo "--${hdr_sig_bnd}--" >> $tempfile1

	# give sendmail the signed mail and additional params
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $headerfile $tempfile1
	else
		cat $headerfile $tempfile1 | $sendmail $@
	fi
	ret=$?
	s=`grep -i -m 1 '^Message-ID: ' $tempfile`
	sfr=`grep -m 1 '^From: ' $tempfile`
	sto=`grep -m 1 '^To: ' $tempfile`
	$infolog mail $sfr $sto $s, pgp/mime sign
else							# gpg not ok
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $tempfile
	else
		cat $tempfile | $sendmail $@
	fi
	ret=$?
fi

rm -f $tempfile1
rm -f $headerfile
rm -f $bodyfile
rm -f $encrfile

return $ret
}
#-----------------------------------------------------------------------------
function sign_old ()
{
# sign a mail with the old style clearsign method
# pars = all cmdline pars
# Uses: cat, cp, gpg, grep, recode, rm, sendmail
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog sign_old: $# $@
fi

local cs s sfr sto ret
cs=''
s=''
sfr=''
sto=''
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile "$hdrsig"
ret=$?

# get charset
get_charset $headerfile
ret=$?
cs=$global_result

# transform body to quoted printable
recode ${cs}..${cs}/QP $bodyfile
ret=$?

# replace charset with quoted-printable
remove_mail_header $headerfile '^Content-Transfer-Encoding: '
ret=$?
Insert_Line $headerfile $[${eh}-1] "$hdr_all_teq" > $tempfile1
ret=$?
cp $tempfile1 $headerfile

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch sign_old: secrkeyfile=$secrkeyfile mykeyid=$mykeyid $@
fi

# create a application/pgp signed (old-style clearsigned) message
/usr/bin/gpg --charset utf-8 --no-verbose --batch --quiet --output - --passphrase-fd 0 --armor --textmode --clearsign -u $mykeyid $bodyfile < $secrkeyfile > $encrfile
ret=$?
if [ "$ret" -eq 0 ]; then				# gpg ok
	# give sendmail the signed mail and additional params
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $headerfile $encrfile
	else
		cat $headerfile $encrfile | $sendmail $@
	fi
	ret=$?
	s=`grep -i -m 1 '^Message-ID: ' $tempfile`
	sfr=`grep -m 1 '^From: ' $tempfile`
	sto=`grep -m 1 '^To: ' $tempfile`
	$infolog mail $sfr $sto $s, old application/pgp sign
else							# gpg not ok
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $tempfile
	else
		cat $tempfile | $sendmail $@
	fi
	ret=$?
fi

rm -f $tempfile1
rm -f $headerfile
rm -f $bodyfile
rm -f $encrfile

return $ret
}
#-----------------------------------------------------------------------------
function sign_encrypt_pgp_mime ()
{
# sign and encrypt a mail pgp/mime encoded
# pars = all cmdline pars
# Uses: cat, cp, cut, echo, egrep, gpg, grep, pgpewrap, recode, sendmail
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog sign_encrypt_pgp_mime: $# $@
fi

local cs r s sfr sto fqp i ret
cs=''							# charset of body
r=''							# recipient address
s=''
sfr=''
sto=''
fqp=no
i=0
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile "$hdrsig"
ret=$?

# find hdrsig
s=`grep -n -m 1 "$hdrsig" $headerfile`
ret=$?
if [ "$ret" -eq 0 ]; then				# line number hdrsig
	i=${s%%:*}
	# insert hdrenc
	Insert_Line $headerfile $i "$hdrenc" > $tempfile1
	ret=$?
	cp $tempfile1 $headerfile
fi

# test if body is attachment
egrep -q -m 1 '^Content-Type: multipart' $headerfile
ret=$?
if [ "$ret" -ne 0 ]; then				# no attachment
	# get charset
	get_charset $headerfile
	ret=$?
	cs=$global_result

	# transform body to quoted printable
	recode ${cs}..${cs}/QP $bodyfile
	ret=$?

	fqp=yes						# set flag quotd prtbl
fi

# get headers to incl in signed and encrypted attachment
cp /dev/null $tempfile1
get_mail_header $headerfile '^Content-Type: '
ret=$?
if [ "$ret" -eq 0 ]; then
	echo "$global_result" >> $tempfile1
fi

get_mail_header $headerfile '^Content-Disposition: '
ret=$?
if [ "$ret" -eq 0 ]; then
	echo "$global_result" >> $tempfile1
fi

if [ "$fqp" == "yes" ]; then
	echo "$hdr_all_teq" >> $tempfile1
else
	get_mail_header $headerfile '^Content-Transfer-Encoding: '
	ret=$?
	if [ "$ret" -eq 0 ]; then
		echo "$global_result" >> $tempfile1
	else
		echo "$hdr_all_ted" >> $tempfile1
	fi
fi

# complete new bodyfile
echo "" >> $tempfile1
cat $bodyfile >> $tempfile1
cp $tempfile1 $bodyfile

# get 1. recipient from 'To: ' header
r=`grep -m 1 '^To: ' $headerfile | cut -d '<' -f 2 | cut -d '>' -f 1`
ret=$?

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch sign_encrypt_pgp_mime: rTo=$r mykeyid=$mykeyid secrkeyfile=$secrkeyfile $@
fi

# create a pgp/mime encrypted and signed attachment
pgpewrap /usr/bin/gpg --charset utf-8 --passphrase-fd 0 --batch --quiet --no-verbose --textmode --output - --encrypt --sign -u $mykeyid --armor --always-trust -- -r $r -- $bodyfile < $secrkeyfile > $encrfile
ret=$?
if [ "$ret" -eq 0 ]; then				# gpg ok
	# replace Content-Type: in header file
	replace_mail_header $headerfile '^Content-Type: ' "$hdr_enc_mul"
	ret=$?

	# build bodyfile
	echo "" > $tempfile1
	echo "--${hdr_enc_bnd}" >> $tempfile1
	echo "$hdr_all_enc" >> $tempfile1
	echo "" >> $tempfile1

	echo "Version: 1" >> $tempfile1

	echo "" >> $tempfile1
	echo "--${hdr_enc_bnd}" >> $tempfile1
	echo "$hdr_all_oct" >> $tempfile1
	echo "" >> $tempfile1

	cat $encrfile >> $tempfile1

	echo "" >> $tempfile1
	echo "--${hdr_enc_bnd}--" >> $tempfile1

	# give sendmail the encrypted mail and additional params
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $headerfile $tempfile1
	else
		cat $headerfile $tempfile1 | $sendmail $@
	fi
	ret=$?
	s=`grep -i -m 1 '^Message-ID: ' $tempfile`
	sfr=`grep -m 1 '^From: ' $tempfile`
	sto=`grep -m 1 '^To: ' $tempfile`
	$infolog mail $sfr $sto $s, pgp/mime sign-encrypt
else							# gpg not ok
	if [ "$debug2" == "yes" ]; then			# DEBUG2
		cat $tempfile
	else
		cat $tempfile | $sendmail $@
	fi
	ret=$?
fi

rm -f $tempfile1
rm -f $headerfile
rm -f $bodyfile
rm -f $encrfile

return $ret
}
#-----------------------------------------------------------------------------
function check_for_gpg_exclude_user ()
{
# get sender address and check if user is a gpg exclude user
# Uses: grep
# Return codes:
# 0 = no gpg needed
# 1 = gpg needed for decryption

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog check_for_gpg_exclude_user: $# $@
fi

local s sl sr i pm err ret
s=''
sl=''
sr=''
i=0
pm=0
err=0
ret=1

# get sender from 'From: ' header
s=`grep -am 1 '^From: ' $tempfile`
err=$?
if [ "$err" -eq 0 ]; then				# 'From: ' found
	Find_Substr "$s" '<'
	err=$?
	Pop pm
	if [ "$err" -eq 0 ]; then			# '<' found
		Find_Substr "$s" '>'
		err=$?
		Pop pm
		if [ "$err" -eq 0 ]; then		# '>' found
			s=${s#*<}
			s=${s%>*}			# s = sender
		else
			return 1			# error in 'From: hdr'
		fi
	else						# no '<>' in header
		Find_Substr "$s" '@'
		err=$?
		Pop pm
		if [ "$err" -eq 0 ]; then		# '@' found
			sl=${s:0:$pm}			# left part without '@'
			sr=${s:$pm}			# right part with '@'
			sl=${sl##* }
			sr=${sr%% *}
			s=${sl}${sr}
		fi
	fi

	i=0
	while [ "$i" -lt $excl_usrcnt ]; do		# all gpg_exclude_user
		let i++
		if [ "$s" == "${gpg_exclude_user[$i]}" ]; then	# sender found
			ret=0
			break
		fi
	done
fi

return $ret
}
#-----------------------------------------------------------------------------
function check_to_decrypt ()
{
# check if mail needs to decrypt
# Uses: grep
# Return codes:
# 0 = no encryption found
# 1 = encryption found

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog check_to_decrypt: $# $@
fi

local s err ret
s=''
err=0
ret=0

s=`grep -m 1 "^Content-Type: multipart/encrypted;" $tempfile` # check pgp/mime
err=$?
if [ "$err" -eq 0 ]; then				# is pgp/mime
	ret=1
else
	# look at old plain-style encryption
	s=`grep -m 1 "^Content-Type: multipart/" $tempfile` # check multipart
	err=$?
	if [ "$err" -ne 0 ]; then			# is no multipart
		s=`grep -m 1 "$begmsg" $tempfile`	# check for encryption
		err=$?					# encrypted
		if [ "$err" -eq 0 ]; then		# is old plain-style
			ret=1
		fi
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_action_in ()
{
# check what to do with incoming mails
# Uses: grep
# Return codes:
# 0 = nothing to do
# 1 = decrypt
# 2 = verify pgp/mime
# 3 = verify old clearsigned

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_action_in: $# $@
fi

local s err ret
s=''
err=0
ret=0

check_for_gpg_exclude_user				# check for exclusion
err=$?
if [ "$err" -eq 0 ]; then				# in gpg_exclude_user
	ret=0						# no gpg action
else
	check_to_decrypt				# need to decrypt?
	err=$?
	if [ "$err" -ne 0 ]; then			# ready to decrypt
		ret=1					# decrypt
	else
		s=`grep -m 1 "$begsig" $tempfile`	# check for mime sig
		err=$?
		if [ "$err" -eq 0 ]; then		# is signed
			ret=2				# verify
		else
			s=`grep -m 1 "$begcsig" $tempfile` # check clearsigned
			err=$?
			if [ "$err" -eq 0 ]; then	# is clear signed
				ret=3			# verify old
			fi

		fi
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function check_gpg_in ()
{
# Check what to do with incoming mail
# get user, keyid, secrkeyfile
# insert Received: hdr, get and do action_in
# Uses: cat
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog check_gpg_in: $# $@
fi

local dogpg ret
dogpg=yes
ret=0

user="$LOGNAME" 					# 'LOGNAME' by procmail
#user="${HOME##/*/}"
get_local_config $user					# get local config vars
ret=$?
if [ "$ret" -eq 0 ]; then				# gpg user found
	get_keyid $user
	ret=$?
fi
if [ "$ret" -eq 0 ]; then				# gpg user found
	mykeyid=$global_result
else							# no gpg user found
	dogpg=no
fi
insert_hdr_received $tempfile				# incl Received header
ret=$?
if [ "$dogpg" == "yes" ]; then
	get_action_in
	ret=$?
else
	ret=4
fi

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch check_gpg_in: user=$user mykeyid=$mykeyid ret=$ret $@
fi

case $ret in
  1)	decrypt_mail; ret=$?;;			# decrypt pgp/mime + old
  2)	verify_pgp_mime; ret=$?;;		# verify pgp/mime
  3)	verify_old; ret=$?;;			# verify old clearsig
  *)	cat $tempfile; ret=$?;;			# output original mail
esac

return $ret
}
#-----------------------------------------------------------------------------
function clean_subject ()
{
# rm keyphrase from 'Subject: ' line of tempfile
# par1 = keyphrase
# Uses: cat, cp, grep, rm, wc
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog clean_subject: $# $@
fi

local p1 s sl n p ret
p1=$1
s=''
sl=0							# subject line number
n=0							# lines in file
p=0
ret=0

n=`cat $tempfile | wc -l`				# lines in tempfile
s=`grep -n -m 1 '^Subject: ' $tempfile`			# subj line incl lnum
ret=$?
sl=${s%%:*}						# subject line number
s=${s#*:}						# rm line number
Find_Substr "$s" "$p1"					# search key
ret=$?
Pop p							# search key
if [ "$ret" -eq 0 ] && [ "$p" -eq 9 ]; then		# key is at 1. pos.
	s=${s/${p1}/}					# rm key from line
fi

Remove_Lines $tempfile $sl $sl > $tempfile1
ret=$?
cp $tempfile1 $tempfile
Insert_Line $tempfile $[${sl}-1] "$s" > $tempfile1
ret=$?
cp $tempfile1 $tempfile

rm -f $tempfile1

return $ret
}
#-----------------------------------------------------------------------------
function check_for_gpg_user ()
{
# get recipient address and check if user is a 'gpg user' or 'gpg sigusr'
# 'gpg sigusr' has precedence over 'gpg user'
# Uses: cut, grep
# Return codes:
# 0 = no gpg needed
# 1 = gpg needed for encryption (pgp/mime)
# 5 = gpg needed for signing and encryption (pgp/mime)

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog check_for_gpg_user: $# $@
fi

local s i ret
s=''
i=0
ret=0

# get 1. recipient from 1. 'To: ' header
s=`grep -m 1 '^To: ' $tempfile | cut -d '<' -f 2 | cut -d '>' -f 1`
ret=$?

if [ "$ret" -eq 0 ]; then				# To: header found
	i=0
	while [ "$i" -lt $sigusrcnt ]; do		# look for gpg siguser
		let i++
		if [ "$s" == "${gpg_siguser[$i]}" ]; then # recipient found
			ret=5
			break
		fi
	done
fi

if [ "$ret" -eq 0 ]; then				# To: header found
	ret=0
	i=0
	while [ "$i" -lt $usrcnt ]; do			# look for gpg user
		let i++
		if [ "$s" == "${gpg_user[$i]}" ]; then	# recipient found
			ret=1
			break
		fi
	done
fi

return $ret
}
#-----------------------------------------------------------------------------
function get_action_out ()
{
# rm keyphrases from subject line and update tempfile
# Uses: cat, echo, grep
# Return codes:
# 0 = gpg not needed
# 1 = pgp/mime encrypt
# 2 = old plain style encrypt
# 3 = pgp/mime sign
# 4 = old clearsigned sign
# 5 = sign and encrypt

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog get_action_out: $# $@
fi

local s key err ret
s=''
key=''
err=0
ret=0

# get subject line
s=`grep -m 1 '^Subject: ' $tempfile`
err=$?
s=${s:9}						# rm 'Subject: '

# test subject for keyphrases
key=`echo "$s" | grep -m 1 "^$gpg_no_auto"`
err=$?
if [ "$err" -eq 0 ]; then				# exclude found
	clean_subject "$gpg_no_auto"
	err=$?
	ret=0
else
	key=`echo "$s" | grep -m 1 "^$gpg_encrypt"`
	err=$?
	if [ "$err" -eq 0 ]; then			# mime encryption fnd
		clean_subject "$gpg_encrypt"
		err=$?
		ret=1
	else
		key=`echo "$s" | grep -m 1 "^$gpg_oencrypt"`
		err=$?
		if [ "$err" -eq 0 ]; then		# old encryption found
			clean_subject "$gpg_oencrypt"
			err=$?
			ret=2
		else
			key=`echo "$s" | grep -m 1 "^$gpg_sign"`
			err=$?
			if [ "$err" -eq 0 ]; then	# mime sign found
				clean_subject "$gpg_sign"
				err=$?
				ret=3
			else
				key=`echo "$s" | grep -m 1 "^$gpg_osign"`
				err=$?
				if [ "$err" -eq 0 ]; then # old sign found
					clean_subject "$gpg_osign"
					err=$?
					ret=4
				else
					key=`echo "$s" | grep -m 1 "^$gpg_signencrypt"`
					err=$?
					if [ "$err" -eq 0 ]; then # signencrypt
						clean_subject "$gpg_signencrypt"
						err=$?
						ret=5
					else		# check for gpg user
						check_for_gpg_user
						ret=$?
					fi
				fi
			fi
		fi
	fi
fi

return $ret
}
#-----------------------------------------------------------------------------
function check_gpg_out ()
{
# check what to do with outgoing mail
# pars = all cmd line pars
# get user, keyid, secretkeyfile
# insert Received: hdr, get and do action_out
# rm all keyphrases from subject
# Uses: cat
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog check_gpg_out: $# $@
fi

local dogpg ret
dogpg=yes
ret=0

user="$USER"						# 'USER' from ENV
#user="${HOME##/*/}"
get_local_config $user					# get local config vars
ret=$?
if [ "$ret" -eq 0 ]; then				# gpg user found
	get_keyid $user
	ret=$?
fi
if [ "$ret" -eq 0 ]; then				# gpg user found
	mykeyid=$global_result
else							# no gpg user found
	dogpg=no
fi
insert_hdr_received $tempfile				# incl Received header
ret=$?
if [ "$dogpg" == "yes" ]; then
	get_action_out					# also cleans subject
	ret=$?
else
	ret=6
fi

if [ "$debug1" == "yes" ]; then				# DEBUG1
	$debuglog gpgswitch check_gpg_out: user=$user mykeyid=$mykeyid ret=$ret $@
fi

case $ret in
  1)	encrypt_pgp_mime $@; ret=$?;;			# pgp/mime encrypt
  2)	encrypt_old $@; ret=$?;;			# old style encrypt
  3)	sign_pgp_mime $@; ret=$?;;			# pgp/mime sign
  4)	sign_old $@; ret=$?;;				# old clearsign style
  5)	sign_encrypt_pgp_mime $@; ret=$?;;		# pgp/mime sign+encrypt
  *)	if [ "$debug2" == "yes" ]; then		# DEBUG2, output original mail
		cat $tempfile
	else
		cat $tempfile | $sendmail $@
	fi; ret=$?;;
esac

return $ret
}
#-----------------------------------------------------------------------------
function outgoing_mail ()
{
# check if mail is outgoing or incoming
# pars = all cmd line pars
# outgoing: no Received hdr was from outside
# incoming: min. 1 Received hdr was from outside
# Uses: echo, grep, rm
# Return codes:
# 0 = mail is outgoing
# 1 = mail is incoming

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog outgoing_mail: $# $@
fi

local s hdr err ret
s=''
hdr=''
err=0
ret=0

# split mail into header and body file
split_to_header_body $tempfile $headerfile $bodyfile
err=$?

err=0
while [ "$err" -eq 0 ] && [ "$ret" -eq 0 ]; do
	get_and_remove_hdr_received $headerfile
	err=$?
	if [ "$err" -eq 0 ]; then			# received hdr found
		hdr="$global_result"
		s=`echo "$hdr" | grep -m 1 'by '`
		err=$?
		if [ "$err" -eq 0 ]; then		# 'by ' found
			s=${s#*by }
			s=${s%% *}

			if [ "$debug1" == "yes" ]; then	# DEBUG1
				$debuglog gpgswitch outgoing_mail: s=$s hostname=$hostname
			fi

			if [ "$s" != "$hostname" ]; then # received hdr outside
				ret=1
			fi
		fi
	fi
done

rm -f $headerfile
rm -f $bodyfile

return $ret
}
#-----------------------------------------------------------------------------
function check_gpg_smtp ()
{
# check if mail is outgoing or incoming
# if outgoing then process mail
# else pipe mail to sendmail
# pars = all cmd line pars
# Uses: cat
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog check_gpg_smtp: $# $@
fi

local ret
ret=0

if outgoing_mail; then					# proc outgoing
	if [ "$debug1" == "yes" ]; then			# DEBUG1
		$debuglog gpgswitch check_gpg_smtp: outgoing $@
	fi

	check_gpg_out $@
	ret=$?
else							# give to sendmail
	if [ "$debug2" == "yes" ]; then		# DEBUG2, output original mail
		cat $tempfile
	else
		if [ "$debug1" == "yes" ]; then		# DEBUG1
			$debuglog gpgswitch check_gpg_smtp: incoming $@
		fi

		cat $tempfile | $sendmail $@
	fi
	ret=$?
fi

return $ret
}
#-----------------------------------------------------------------------------
function main_proc ()
{
# main part of the program
# pars = all cmd line pars
# works with respect to the flagfile 'ffile'
# locks and unlocks gpgswitch
# Uses: cat, cp, echo, rm
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog main_proc: $# $@
fi

local ret
ret=0

if [ "$1" == "-i" ]; then				# option -i
	if [ -e $ffile ]; then				# gpgswitch is active
		cat > $tempfile
		echo "" > $lockfile

		if [ "$debug1" == "yes" ]; then		# DEBUG1
			$debuglog gpgswitch main_proc: $@
		fi

		check_gpg_in
		ret=$?
		rm -f $tempfile
		rm -f $lockfile
	else						# pipe to stdout
		cat
		ret=$?
	fi
elif [ "$1" == "-o" ]; then				# option -o
	shift						# rm opt. from cmdline
	if [ -e $ffile ]; then				# gpgswitch is active
		cat > $tempfile
		echo "" > $lockfile

		if [ "$debug1" == "yes" ]; then		# DEBUG1
			$debuglog gpgswitch main_proc: -o $@
		fi

		check_gpg_out $@
		ret=$?
		rm -f $tempfile
		rm -f $lockfile
	else						# pipe to sendmail
		cat | $sendmail $@
		ret=$?
	fi
elif [ "$1" == "-s" ]; then				# option -s
	shift						# rm opt. from cmdline
	gpgsw_mail=$1
	shift
	if [ -e $ffile ]; then				# gpgswitch is active
		cp $gpgsw_mail $tempfile
		echo "" > $lockfile

		if [ "$debug1" == "yes" ]; then		# DEBUG1
			$debuglog gpgswitch main_proc: -s $gpgsw_mail $@
		fi

		check_gpg_smtp $@
		ret=$?
		rm -f $tempfile
		rm -f $lockfile
	else						# pipe to sendmail
		cat $gpgsw_mail | $sendmail $@
		ret=$?
	fi
else							# error
	ret=1
fi

return $ret
}
##############################################################################
# PARSE COMMANDLINE

# Read the cmd, all options with args and all additional args into variables.
# Stop parsing after last parameter.
# Try to do a check on all parameters and version numbers.
# Handle cmds -h and -V directly.
# Exit on error.

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog Parse Commandline: $# $@
fi

# get command (1. cmdline parameter)
case $1 in
  -h|--help)	cmd='-h'; shift; cmd_found='yes';;	# cmd -h
  --version)	cmd='--v'; shift; cmd_found='yes';;	# cmd --v
  -i|-o|-s)	cmd="$1"; cmd_found='yes';;		# cmd found
  *)	echo "Fehler - Option $1 unbekannt!" >&2	# error
	$errlog unknown command $1
	exit 1;;
esac

# get options
#while [ "${1:0:1}" == "-" ]; do			# get all options
#	case $1 in
#	  -d|--debug)	debug=yes;;			# option -d
#	  -q|--quiet)	verbose=no;;			# option -q
#	  -v|--verbose)	verbose=yes;;			# option -v
#	  *)	echo "Error - unknown option $1 !" >&2	# error
#		$errlog unknown option $1
#		exit 1;;
#	esac
#	shift
#	opt_found=yes
#done

# handle standard commands -h, --v
case $cmd in
  -h)	helptext; exit 0;;				# give help
  --v)	echo "$scriptname (${pkgname}) $version"; exit 0;; # output version
esac

# check libraries S I C
Check_Libs S

# check version of config files
#if [ "$version" != "$sample_cnf" ] || [ "$version" != "$sample_rc" ]; then
#	if [ "$verbose" != no ]; then
#		echo "Error in version of config files!" >&2
#	else
#		$errlog version of config files differ
#	fi
#	exit 3
#fi

# check arguments after commands and options
#if [ "$cmd" == "-i" ] && [ "$#" -ne 1 ]; then		# error in param count
#	echo "Error in parameter count!" >&2
#	$errlog wrong parameter count
#	exit 2
#fi

##############################################################################
# MAINPROGRAM
# Uses: sleep

if [ "$debug" == "yes" ]; then				# DEBUG
	$debuglog Main: $# $@
fi

# Check what to do (initial cmds, options and args are removed from cmdline)
if [ -e $lockfile ]; then
	i=0
	while [ "$i" -lt $maxwait ] && [ -e $lockfile ]; do	# wait maxwait
		let i++
		sleep 1					# wait 1 second
	done
	if [ ! -e $lockfile ]; then
		main_proc $@
		err=$?
	else
		err=30
	fi
else
	main_proc $@
	err=$?
fi

exit $err
