/*********************************************************************** module: rpa.c program: fetchmail programmer: Michael J. Palmer <106177.1156@compuserve.com> date: 29 August 1997 compiler: GCC 2.7.2 environment: RedHat 4.0 Linux 2.0.18 description: RPA authorisation code for POP3 client The sole entry point is POP3_auth_rpa() For license terms, see the file COPYING in this directory. ***********************************************************************/ #include "config.h" #if defined(POP3_ENABLE) && defined(RPA_ENABLE) #include #include #include #include #include #include #include "socket.h" #include "fetchmail.h" #include "fm_md5.h" #include "i18n.h" #ifdef TESTMODE extern unsigned char line1[]; extern unsigned char line2[]; extern unsigned char line3[]; extern int linecount; #endif #ifndef NO_PROTO /* prototypes for internal functions */ static int POP3_rpa_resp(char* argbuf, int socket ); static void LenAppend(char** pptr, int len); static int LenSkip(char** pptr, int rxlen); static int DecBase64(char* bufp); static void EncBase64(char* bufp, int len); static void ToUnicode(char** pptr, char delim, unsigned char* buf, int* plen, int conv); static int SetRealmService(char* bufp); static void GenChallenge(unsigned char* buf, int len); static int DigestPassphrase(char* passphrase, unsigned char* rbuf, int unicodeit); static void CompUserResp(void); static int CheckUserAuth(void); static void md5(const void* in, int len, unsigned char* out); #endif /* RPA protocol definitions */ #define EARLYVER "\x01\x00" /* Earliest supp version */ #define LATEVER "\x03\x00" /* Latest supp version */ #define HDR 0x60 /* ASN.1 SEQUENCE */ #define MECH "\x06\x09\x60\x86\x48\x01\x86\xF8\x73\x01\x01" #define FLAGS "\x00\x01" /* Mutual authentication */ #define STRMAX 128 /* Bytes in Unicode */ #define Tsl 14 /* Timestamp bytelen */ #define Pul 16 /* Passphrase digest len */ #define Cul 16 /* Usr challenge bytelen */ #define Rul 16 /* Usr response bytelen */ #define Aul 16 /* User auth bytelen */ #define Kusl 16 /* Session key bytelen */ #define UNIPASS 1 /* 1=Unicode 0=iso8859 */ #define PS_RPA 42 /* Return code */ /* RPA authentication items */ unsigned char Cs[256]; /* Service challenge */ int Csl; /* Length of " " */ unsigned char Ts[Tsl+1]; /* Timestamp incl \0 */ unsigned char Nu[STRMAX]; /* Username in Unicode */ int Nul; /* Length of " in bytes */ unsigned char Ns[STRMAX]; /* Service in Unicode */ int Nsl; /* Length of " in bytes */ unsigned char Nr[STRMAX]; /* Realm in Unicode */ int Nrl; /* Length of " in bytes */ unsigned char Pu[Pul]; /* Passphrase after MD5 */ unsigned char Cu[Cul]; /* User challenge */ unsigned char Ru[Rul]; /* User response */ unsigned char Au[Aul]; /* User auth from Deity */ unsigned char Kusu[Kusl]; /* Obscured Session key */ unsigned char Kus[Kusl]; /* Session key */ /********************************************************************* function: POP3_auth_rpa description: send the AUTH RPA commands to the server, and get the server's response. Then progress through the RPA challenge/response protocol until we are (hopefully) granted authorisation. arguments: userid user's id@realm e.g. myuserid@csi.com passphrase user's passphrase (upper lower or mixed case as the realm has chosen. spec allows various options :-( ) socket socket to which the server is connected. return value: zero if success, else non-zero. calls: SockPrintf, POP3_rpa_resp, EncBase64, DecBase64, LenAppend, GenChallenge globals: read outlevel. *********************************************************************/ int POP3_auth_rpa (char *userid, char *passphrase, int socket) { int ok,rxlen,verh,verl,i,rll; char buf [POPBUFSIZE]; char *bufp; int status,aulin,kuslin; const char* stdec[4] = { N_("Success") , N_("Restricted user (something wrong with account)") , N_("Invalid userid or passphrase") , N_("Deity error") }; /* Initiate RPA authorisation */ SockPrintf(socket,"AUTH RPA\r\n"); if (outlevel >= O_MONITOR) report(stdout, "> AUTH RPA\n"); /* Create unicode user name in Nu. */ /* Create MD5 digest of user's passphrase in Pu */ bufp = userid; ToUnicode(&bufp, '@', Nu, &Nul, 1); /* User (lowercase) */ DigestPassphrase(passphrase, Pu, UNIPASS); /* Get + response from server (RPA ready) */ if ((ok = POP3_rpa_resp(buf,socket)) != 0) { if (outlevel > O_SILENT && outlevel < O_MONITOR) report(stdout, "%s\n",buf); return(ok); } /* Assemble Token 1 in buf */ bufp = buf; *bufp++ = HDR; LenAppend(&bufp, 17); memcpy(bufp, MECH, 11); bufp += 11; memcpy(bufp, EARLYVER, 2); bufp += 2; memcpy(bufp, LATEVER, 2); bufp += 2; memcpy(bufp, FLAGS, 2); bufp += 2; /* Send Token 1, receive Token 2 */ EncBase64(buf, bufp-buf); #ifndef TESTMODE SockPrintf(socket,"%s\r\n",buf); #endif if (outlevel >= O_MONITOR) report(stdout, "> %s\n",buf); if ((ok = POP3_rpa_resp(buf,socket)) != 0) { if (outlevel > O_SILENT && outlevel < O_MONITOR) report(stdout, "%s\n",buf); return(ok); } if ((rxlen = DecBase64(buf)) == 0) { if (outlevel > O_SILENT) report(stderr, GT_("RPA token 2: Base64 decode error\n")); return(PS_RPA); } bufp = buf; *(buf+rxlen) = 0; /* Terminates realm list */ if (LenSkip(&bufp,rxlen) == 0) return(PS_RPA); /* Interpret Token 2 */ verh = (unsigned char)*(bufp++); verl = (unsigned char)*(bufp++); if (outlevel >= O_DEBUG) report(stdout, GT_("Service chose RPA version %d.%d\n"),verh,verl); Csl = (unsigned char)*(bufp++); memcpy(Cs, bufp, Csl); bufp += Csl; if (outlevel >= O_DEBUG) { report(stdout, GT_("Service challenge (l=%d):\n"),Csl); for (i=0; i= O_DEBUG) report(stdout, GT_("Service timestamp %s\n"),Ts); rll = (unsigned char)*(bufp++) << 8; rll = rll | (unsigned char)*(bufp++); if ((bufp-buf+rll) != rxlen) {
#!/bin/sh

MSG() {
cat << EOF

# Fetchsetup is a shell script for creating a .fetchmailrc file,  
# that will be used by the program "fetchmail" to connect to your 
# mail domain and retrieve your mail. 
# This script is linux specific, so it may not work on another system.
# Kent Robotti <krobot@erols.com> (3-31-99)

EOF
}

if [ ! "$UID" = "0" ]; then
echo "[$LOGNAME] You need to be [root] to run this script."
echo "You could login: root"
echo "You could also try one of these: # sudo fetchsetup"
echo "                                 # su -c fetchsetup"
exit 1
fi

MSG
echo -n "Continue? (Y/n) : "
read ans
if [ "$ans" = "n" -o "$ans" = "N" ]; then
echo "Cancelled."
exit 0
fi

stty erase "^?" 2>/dev/null

echo
echo "Remote mail site?: pop.boo.com   <Your service providers mail domain name>"
echo -n "Remote mail site?: "
read SITE
echo
echo "Protocol?: pop3   <My service provider uses the 'pop3' mail protocol>"
echo "Protocol?: auto   <If not sure put: auto>"
echo "Choices: apop auto etrn imap imap-gss imap-k4 kpop pop2 pop3 rpop sdps" 
echo -n "Protocol?: "
read PROTO
echo
echo "Remote username?: jerry   <My username or login is jerry>"
echo -n "Remote username?: "
read USR
echo
echo "Remote password?: ?       <What's the password for?: $USR>"
echo -n "Remote password?: "
read PASS

echo
echo -n "Create $HOME/.fetchmailrc file? (Y/n) : "
read ans
if [ "$ans" = "n" -o "$ans" = "N" ]; then
echo
echo "Fetchsetup cancelled."
echo
exit 0
fi

echo 'poll "'$SITE'"' > $HOME/.fetchmailrc
echo "protocol $PROTO" >> $HOME/.fetchmailrc
echo 'username "'$USR'"' >> $HOME/.fetchmailrc
echo 'password "'$PASS'"' >> $HOME/.fetchmailrc
 
PROCMAIL=`type -all procmail | sed -n "1 p" | cut -d' ' -f3`  
SENDMAIL=`type -all sendmail | sed -n "1 p" | cut -d' ' -f3`  

if [ ! "$PROCMAIL" = "" ]; then
echo 'mda "'$PROCMAIL -d %s'"' >> $HOME/.fetchmailrc
MDA="1"
elif [ ! "$SENDMAIL" = "" ]; then
echo 'mda "'$SENDMAIL %s'"' >> $HOME/.fetchmailrc
MDA="2"
else
MDA="3"
fi 

echo >> $HOME/.fetchmailrc
echo
echo "This is your $HOME/.fetchmailrc file."

chmod 600 $HOME/.fetchmailrc

echo
cat $HOME/.fetchmailrc

if [ ! "$MAIL" = "" ]; then
echo "Fetchmail will retrieve your mail and put it in:"
echo "$MAIL"
if [ ! -f "$MAIL" ]; then
touch $MAIL 2>/dev/null
chmod 600 $MAIL 2>/dev/null
fi
fi

echo
if [ "$MDA" = "1" ]; then
echo "I put that (m)ail (d)elivery (a)gent in .fetchmailrc"
echo "because i found it on your system, this doesn't mean" 
echo "it's correct or the one you want to use."
echo
echo "The first time you run fetchmail, you should run it"
echo "this way: # fetchmail -k"
echo
elif [ "$MDA" = "2" ]; then
echo "You seem to have sendmail, sendmail will be used"
echo "as the (m)ail (d)elivery (a)gent for fetchmail."
echo
echo "WARNING! There's no way to know if sendmail is set up"
echo "properly for lo