/*********************************************************************** 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 "socket.h" #include "fetchmail.h" #include "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(); static int CheckUserAuth(); 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; 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) { if (outlevel > O_SILENT) report(stderr, GT_("RPA token 2 length error\n")); return(PS_RPA); } if (outlevel >= O_DEBUG) report(stdout, GT_("Realm list: %s\n"),bufp); if (SetRealmService(bufp) != 0) { if (outlevel > O_SILENT) report(stderr, GT_("RPA error in service@realm string\n")); return(PS_RPA); } /* Assemble Token 3 in buf */ bufp = buf; *(bufp++) = HDR; LenAppend(&bufp, 11+2+strlen(userid)+1+Cul+1+Rul ); memcpy(bufp, MECH, 11); bufp += 11; *(bufp++) = 0; *(bufp++) = strlen(userid); memcpy(bufp,userid,strlen(userid)); bufp += strlen(userid); GenChallenge(Cu,Cul); *(bufp++) = Cul; memcpy(bufp, Cu, Cul); bufp += Cul; CompUserResp(); *(bufp++) = Rul; memcpy(bufp, Ru, Rul); bufp += Rul; /* Send Token 3, receive Token 4 */ 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_
/* XPM */
static char *magick[] = {
/* columns rows colors chars-per-pixel */
"64 64 93 2",
"   c Gray0",
".  c #020202",
"X  c Gray2",
"o  c Gray4",
"O  c Gray9",
"+  c #272727",
"@  c Gray22",
"#  c #393939",
"$  c Gray23",
"%  c #414141",
"&  c Gray26",
"*  c #444444",
"=  c Gray28",
"-  c #4c4c4c",
";  c Gray30",
":  c #4e4e4e",
">  c Gray32",
",  c #565656",
"<  c #5a5a5a",
"1  c Gray37",
"2  c #5f5f5f",
"3  c Gray38",
"4  c #626262",
"5  c #676767",
"6  c #686868",
"7  c #6a6a6a",
"8  c Gray42",
"9  c #6c6c6c",
"0  c Gray43",
"q  c #767676",
"w  c #777777",
"e  c Gray47",
"r  c #7b7b7b",
"t  c Gray50",
"y  c #808080",
"u  c #818181",
"i  c #838383",
"p  c #848484",
"a  c Gray52",
"s  c Gray53",
"d  c Gray54",
"f  c #8b8b8b",
"g  c Gray55",
"h  c #8e8e8e",
"j  c Gray57",
"k  c #929292",
"l  c #959595",
"z  c Gray59",
"x  c #979797",
"c  c #989898",
"v  c Gray60",
"b  c #9b9b9b",
"n  c Gray61",
"m  c #9f9f9f",
"M  c Gray64",
"N  c #a5a5a5",
"B  c #a7a7a7",
"V  c Gray66",
"C  c #a9a9a9",
"Z  c #acacac",
"A  c #aeaeae",
"S  c #afafaf",
"D  c Gray69",
"F  c #b1b1b1",
"G  c #b2b2b2",
"H  c Gray70",
"J  c #b4b4b4",
"K  c #b7b7b7",
"L  c Gray72",
"P  c #bbbbbb",
"I  c #c0c0c0",
"U  c #c1c1c1",
"Y  c #c3c3c3",
"T  c Gray77",
"R  c #c8c8c8",
"E  c Gray80",
"W  c Gray82",
"Q  c #d3d3d3",
"!  c Gray83",
"~  c #d8d8d8",
"^  c #dadada",
"/  c Gray86",
"(  c #dddddd",
")  c Gray88",
"_  c #e4e4e4",
"`  c Gray90",
"'  c Gray91",
"]  c Gray93",
"[  c #f1f1f1",
"{  c Gray97",
"}  c Gray98",
"|  c #fdfdfd",
" . c Gray100",
/* pixels */
"} } } } } } } } } } } } } } } } } } } } } } } } } } ' } ' ' ' ' ' ' ' ' ~ ~ ~ ~ ~ ~ ~ R ~ R R R R R L R L L L L L V L V V V V c ",
"} } } } } } } } } } } } } } } } } } } } } } } ' } ' } ' } ' ' ' ' ' ~ ' ' ~ ~ ~ ~ R ~ R R R R R R L R L L L L V L V V V V V c c ",
"} } } } } } } } } } } } } } } } } } } } } } } } } ' } ' ' ' ' ' ' ' ~ ~ ~ ~ ~ ~ ~ R ~ R ~ R R R L R L L L L L L V L V V c c V c ",
"} } } } } } } } } } } } } } } } } } } } } } ' ' } ' ' } ' ' ' ' ~ ~ ' ~ ~ ~ ~ ~ R ~ R R R R R L R L L L L L L V V V V c V c c c ",
"} } } } } } } } } } } } } } } } } } } } ' } } ' } ' ' ' ' ' ' ' ' ~ ~ ~ ~ ~ R ~ R R R R R L R L L L L L L V V L V V V c c c c s ",
"} } } } } } } } } } } } } } } } } } } } } ' } ' } ' ' ' ' ' ~ ~ ~ ~ ~ ~ ~ ~ ~ R ~ R R R R R L R L L L L V L V V c V c c c c s c ",
"} } } } } }  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .b c c c c s s ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   c c c s s s ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   c s s c s s ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   s c s s s w ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   c s s s s w ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   s s s w w w ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   s s w s w w ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   w s w w w w ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   s w w w w 5 ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   w w w w w 5 ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   s w w 5 5 5 ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   w 5 w 5 5 5 ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   w 5 5 5 5 5 ",
"} } } } } }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   5 w 5 5 5 , ",
"} } } } ' }  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   5 5 5 , 5 , ",
"} } } } } '  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   5 5 5 5 , , ",
"} } ' } } '  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   5 , , , , , ",
"} } } ' } '  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   5 5 5 , , , ",
"} ' } ' } '  .b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b   , , , , = , ",
"' } } ' ' }  .b b b b b b b b b b b b b b b b b b b b b b b b b p y p p r p p y p p r p p y p p r p p b b b b b b   , , , , = = ",
"} ' ' } ' '  .b b b b b b b b b b b b b b b b b b b b b b b i t 3 { [ } { } { } { [ { } { [ } { [ { y b b b b b b   , , = , = = ",
"' } ' ' ' '  .b b b b b b b b b b b b b b b b b b b b b i * 2 0 8 J | { } { } { } | | [ | | { | | { r b b b b b b   , , = = = = ",
"' } ' ' ' '  .b b b b b b b b . . . . . p r b b b b 1 % 4 A A 7 & G ( } } } | } { } | | { } | } ! M p b b b b b b   = , = = = @ ",
"' ' ' ' ' '  .b b b b b b b b . . . . . } [ 6 d : 2 e m A K