1#! /bin/sh 2# 3# nasty: 4# Simple virtual-domains authentication with auth_other. Also, the World's 5# Worst Bourne Shell Script. 6# 7# Mailspools live under /var/spool/mail/SERVERS/domain/user; users are 8# authenticated against a password file in /etc/mail/SERVERS/domain/passwd, 9# which is in the format username:password hash; the password hash is the 10# cksum(1) of the password. 11# 12# Thanks to Rick Leeming and Richard Smith for perpetrating the first part of 13# this deranged monstrosity. 14# 15# This script should not be used for any purpose whatsoever, with the possible 16# exception of scaring people who are afraid of the shell. 17# 18# $Id$ 19# 20 21VCONF=/etc/mail/SERVERS # where password files live 22VSPOOL=/var/spool/mail/SERVERS # where spools live 23VUSER=mail # user and group to use 24VGROUP=mail 25 26# Get the parameters. You are not expected to understand this. 27IFS= 28eval ` 29while true ; do 30 a=@ 31 while [ "$a" ] ; do 32 tmp=\`echo @ | dd ibs=1 obs=1 count=1 2>/dev/null; dd ibs=1 obs=1 count=1 2>/dev/null; echo @ | dd ibs=1 obs=1 count=1 2>/dev/null\` 33 if [ x"$tmp" = x"@" -o "$tmp" = x"@@" ] ; then 34 break 35 fi 36 a="$a$tmp" 37 done 38 39 if [ "$a" = @ ] ; then 40 break 41 fi 42 43 a=\`echo $a | sed 's/@\\(.\\)@/\\1/g;s/^@//;s/@$//;s/\\"/\\\\"/g'\` 44 45 b=@ 46 while [ "$b" ] ; do 47 tmp=\`echo @ | dd ibs=1 obs=1 count=1 2>/dev/null; dd ibs=1 obs=1 count=1 2>/dev/null; echo @ | dd ibs=1 obs=1 count=1 2>/dev/null\` 48 if [ x"$tmp" = x"@" -o "$tmp" = x"@@" ] ; then 49 break 50 fi 51 b="$b$tmp" 52 done 53 b=\`echo $b | sed 's/@\\(.\\)@/\\1/g;s/^@//;s/@$//;s/\\"/\\\\"/g'\` 54 55 echo auth_other_$a=\\"$b\\" 56done 57` 58 59# Replacement for echo -n, for systems which don't have it 60function echo_n { 61 echo $1 | tr -d '\n' 62} 63 64# Send a \0 65function charzero { 66 dd if=/dev/zero ibs=1 obs=1 count=1 2> /dev/null 67} 68 69# Send back a failure message 70function refuse_authentication { 71 echo_n "result" 72 charzero 73 echo_n "NO" 74 charzero 75 echo_n logmsg 76 charzero 77 echo_n $1 78 charzero 79 charzero 80} 81 82# OK, at this stage, we should have some auth_other_... variables 83if [ x"$auth_other_method" = x"APOP" ] ; then 84 # no APOP support 85 refuse_authentication "APOP not supported" 86elif [ x"$auth_other_method" = x"PASS" ] ; then 87 # OK, we should be authenticating user@domain here 88 domain=`echo $auth_other_user | sed 's/^[^@!%]\+[@!%]//' | tr -d '/'` 89 local_part=`echo $auth_other_user | sed 's/^\([^@!%]\+\).*/\1/'` 90 91 if [ -e "$VCONF/$domain/passwords" ] ; then 92 # Look up the user's password 93 pwentry=`grep "^$local_part:" "$VCONF/$domain/passwords"` 94 if [ x"$pwentry" = x"" ] ; then 95 refuse_authentication "unknown user $local_part@$domain" 96 else 97 # Calculate hash of user's password 98 hash=`echo_n $auth_other_password | cksum | sed 's/ [0-9]+$//'` 99 if [ x"$pwentry" = x"$local_part:$hash" ] ; then 100 # OK, success; return a suitable packet of data to the server. 101 echo_n result 102 charzero 103 echo_n YES 104 charzero 105 echo_n uid 106 charzero 107 echo_n $VUSER 108 charzero 109 echo_n gid 110 charzero 111 echo_n $VGROUP 112 charzero 113 echo_n mboxtype 114 charzero 115 echo_n bsd 116 charzero 117 echo_n mailbox 118 charzero 119 echo_n $VSPOOL/$domain/$local_part 120 charzero 121 charzero 122 else 123 refuse_authentication "wrong password for $local_part@$domain" 124 fi 125 fi 126 else 127 # We don't know about this domain 128 refuse_authentication "unknown domain $domain" 129 fi 130fi 131 132# Re-exec script to handle another request. 133exec $0 134