#!/bin/bash
#
# $Id: authProg,v 1.1 2005/03/20 19:58:55 mrsam Exp $
#
# Sample external program invoked by the authpipe module

#MY_PASSWORD_FILE="/var/srv/imap/imap-users"
MY_PASSWORD_FILE="/tmp/test.imap"

# command must be either  (every command finished with a new-line)

myMD5pw()
{
	local uid=$1
	local pw=$2
	REPLY=$(echo "${uid}:${pw}:${uid}" | md5sum)
}

checkEntry()
{
	local entry=$*
	if [ "$entry" = "${entry/*:*/}" ]
	then
		return 0
	else
		return 1
	fi
}

myCorrectInput()
{
	local what=$1
	local newValue
	echo "Please enter new $what: "
	read newValue
	while ! checkEntry $newValue
	do
		echo "Sorry $what may not contain ':'"
		echo "Please enter new $what: "
		read newValue
	done

	REPLY=$newValue
}

myNewEntry()
{
	local uid
	local pw
	local md5pw
	local username
	local homedir
	local maildir
	local address
	local fullname
	local options

	myCorrectInput "uid"
	uid=$REPLY
	echo -n "Please enter password for $uid (not shown): "
	read -s pw
	myMD5pw $uid $pw
	md5pw=$REPLY
	echo
	echo -n "Please re-enter password for $uid (not shown): "
	read -s pw
	myMD5pw $uid $pw
	if [ ! "$md5pw" = "$REPLY" ]
	then
		echo "Passwords differ"
		echo "Please start again"
		echo "(Sorry I was too lazy to implement this correctly)"
		exit -2
	fi
	echo
	local username
	local homedir
	local maildir
	local address
	local fullname
	local options
	myCorrectInput "username"; username=$REPLY
	myCorrectInput "homedir";  homedir=$REPLY
	myCorrectInput "maildir";  maildir=$REPLY
	myCorrectInput "address";  address=$REPLY
	myCorrectInput "fullname"; fullname=$REPLY
	myCorrectInput "options";  options=$REPLY

	echo "$uid:$md5pw:$username:$homedir:$maildir:$address:$fullname:$options" >> $MY_PASSWORD_FILE
}

myGiveInfo()
{
	local uid=$1
	local uidInfos
	uidInfos=$(grep "^${uid}:" $MY_PASSWORD_FILE)

	# let's split them
	local username
	local homedir
	local maildir
	local address
	local fullname
	local options

	uidInfos=${uidInfos#*:*:}   # delete uid and password
	username=${uidInfos%%:*}; uidInfos=${uidInfos#*:}
	homedir=${uidInfos%%:*}; uidInfos=${uidInfos#*:}
	maildir=${uidInfos%%:*}; uidInfos=${uidInfos#*:}
	address=${uidInfos%%:*}; uidInfos=${uidInfos#*:}
	fullname=${uidInfos%%:*}; uidInfos=${uidInfos#*:}
	options=${uidInfos%%:*};

	while read whatInfo
	do
		case $whatInfo in
			"USERNAME") echo "OK ${username}"; false;;
			"HOMEDIR")  echo "OK ${homedir}";  false;;
			"MAILDIR")  echo "OK ${maildir}";  false;;
			"ADDRESS")  echo "OK ${address}";  false;;
			"FULLNAME") echo "OK ${fullname}"; false;;
			"OPTIONS")  echo "OK ${options}";  false;;
		esac

		# in case we didn't know the "question" send 'OK '
		if [ $? -eq 0 ]
		then
			echo "?? "
		fi
	done
}

# * AUTH followed by uid and password
myAuth()
{
	local uid
	local pw

	read uid
	read pw

	local md5pw
	myMD5pw $uid $pw
	md5pw=$REPLY

	if ! checkEntry $uid
	then
		echo "BAD UID!!! (contains :)"
		exit -1
	fi

	if grep "^${uid}:${md5pw}:.*$" $MY_PASSWORD_FILE > /dev/null
	then
		echo "OK user exists and password is correct"
	elif grep "^${uid}:" $MY_PASSWORD_FILE > /dev/null
	then
		echo "SORRY user exists but password is wrong"
		exit -1
	else
		exit -1
	fi

	myGiveInfo $uid
}

# * CHECK followed by uid
myCheck()
{
	local uid

	read uid
	if ! checkEntry $uid
	then
		echo "BAD UID!!! (contains :)"
		exit -1
	fi

	if grep "^${uid}:" $MY_PASSWORD_FILE > /dev/null
	then
		echo "OK user exists"
	else
		exit -1
	fi

	myGiveInfo $uid
}

# * PASSWD followed by uid, oldpasswd and newpassword
myPasswd()
{
	local uid
	local oldpw
	local newpw

	read uid
	if ! checkEntry $uid
	then
		echo "BAD UID!!! (contains :)"
		exit -1
	fi

	read oldpw
	read newpw
	
	local md5oldpw
	local md5newpw
	myMD5pw $uid $oldpw 
	md5oldpw=$REPLY
	myMD5pw $uid $newpw 
	md5newpw=$REPLY

	if grep "^${uid}:${md5oldpw}:" $MY_PASSWORD_FILE > /dev/null
	then
		sed -i "s/^${uid}:${md5oldpw}:/${uid}:${md5newpw}:/" $MY_PASSWORD_FILE > /dev/null
		echo "OK password changed"
		exit 0
	elif grep "^${uid}:" $MY_PASSWORD_FILE > /dev/null
	then
		echo "SORRY old password was wrong"
		exit -1
	else
		# username wrong
		exit -1
	fi
}

declare command
read command
case $command in
	"AUTH")   myAuth;;
	"CHECK")  myCheck;;
	"PASSWD") myPasswd;;
	"NEW")    myNewEntry;;
esac

