X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=rpa.c;h=c365f0ded8b2338ed9a1b2792557c4d0da07b209;hb=7f6138ffd4935043382ce5f867ee9e177e0a9787;hp=f295e47d744817862b8716b97da33fafee20f0f4;hpb=ee409a69c7f931c02aac69553c92817dfa7951db;p=~andy%2Ffetchmail diff --git a/rpa.c b/rpa.c index f295e47d..c365f0de 100644 --- a/rpa.c +++ b/rpa.c @@ -8,19 +8,24 @@ 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 #include "socket.h" #include "fetchmail.h" -#include "md5.h" +#include "fm_md5.h" #include "i18n.h" #ifdef TESTMODE @@ -33,20 +38,20 @@ extern int linecount; #ifndef NO_PROTO /* prototypes for internal functions */ - static int POP3_rpa_resp(unsigned char* argbuf, int socket ); - static void LenAppend(unsigned char** pptr, int len); - static int LenSkip(unsigned char** pptr, int rxlen); - static int DecBase64(unsigned char* bufp); - static void EncBase64(unsigned char* bufp, int len); - static void ToUnicode(unsigned char** pptr, unsigned char delim, - unsigned char* buf, int* plen, int conv); - static int SetRealmService(unsigned char* bufp); + 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(unsigned char* passphrase, + static int DigestPassphrase(char* passphrase, unsigned char* rbuf, int unicodeit); - static void CompUserResp(); - static int CheckUserAuth(); - static void md5(unsigned char* in, int len, unsigned char* out); + static void CompUserResp(void); + static int CheckUserAuth(void); + static void md5(const void* in, int len, unsigned char* out); #endif /* RPA protocol definitions */ @@ -104,13 +109,13 @@ unsigned char Kus[Kusl]; /* Session key */ globals: read outlevel. *********************************************************************/ -int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) +int POP3_auth_rpa (char *userid, char *passphrase, int socket) { int ok,rxlen,verh,verl,i,rll; - unsigned char buf [POPBUFSIZE]; - unsigned char *bufp; + char buf [POPBUFSIZE]; + char *bufp; int status,aulin,kuslin; - char* stdec[4] = { N_("Success") , + const char* stdec[4] = { N_("Success") , N_("Restricted user (something wrong with account)") , N_("Invalid userid or passphrase") , N_("Deity error") }; @@ -120,7 +125,7 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) SockPrintf(socket,"AUTH RPA\r\n"); if (outlevel >= O_MONITOR) - progress(0, 0, "> AUTH RPA\n"); + report(stdout, "> AUTH RPA\n"); /* Create unicode user name in Nu. */ /* Create MD5 digest of user's passphrase in Pu */ @@ -134,7 +139,7 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) if ((ok = POP3_rpa_resp(buf,socket)) != 0) { if (outlevel > O_SILENT && outlevel < O_MONITOR) - progress(0, 0, "%s\n",buf); + report(stdout, "%s\n",buf); return(ok); } @@ -156,17 +161,17 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) SockPrintf(socket,"%s\r\n",buf); #endif if (outlevel >= O_MONITOR) - progress(0, 0, "> %s\n",buf); + report(stdout, "> %s\n",buf); if ((ok = POP3_rpa_resp(buf,socket)) != 0) { if (outlevel > O_SILENT && outlevel < O_MONITOR) - progress(0, 0, "%s\n",buf); + report(stdout, "%s\n",buf); return(ok); } if ((rxlen = DecBase64(buf)) == 0) { if (outlevel > O_SILENT) - error(0, 0, _("RPA token 2: Base64 decode error\n")); + report(stderr, GT_("RPA token 2: Base64 decode error\n")); return(PS_RPA); } bufp = buf; @@ -175,37 +180,37 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) /* Interpret Token 2 */ - verh = *(bufp++); verl = *(bufp++); + verh = (unsigned char)*(bufp++); verl = (unsigned char)*(bufp++); if (outlevel >= O_DEBUG) - progress(0, 0, _("Service chose RPA version %d.%d\n"),verh,verl); - Csl = *(bufp++); + 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) { - progress(0, 0, _("Service challenge (l=%d):"),Csl); + report(stdout, GT_("Service challenge (l=%d):\n"),Csl); for (i=0; i= O_DEBUG) - progress(0, 0, _("Service timestamp %s\n"),Ts); - rll = *(bufp++) << 8; rll = rll | *(bufp++); + 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) - error(0, 0, _("RPA token 2 length error\n")); + report(stderr, GT_("RPA token 2 length error\n")); return(PS_RPA); } if (outlevel >= O_DEBUG) - progress(0, 0, _("Realm list: %s\n"),bufp); + report(stdout, GT_("Realm list: %s\n"),bufp); if (SetRealmService(bufp) != 0) { if (outlevel > O_SILENT) - error(0, 0, _("RPA error in service@realm string\n")); + report(stderr, GT_("RPA error in service@realm string\n")); return(PS_RPA); } @@ -232,17 +237,17 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) SockPrintf(socket,"%s\r\n",buf); #endif if (outlevel >= O_MONITOR) - progress(0, 0, "> %s\n",buf); + report(stdout, "> %s\n",buf); if ((ok = POP3_rpa_resp(buf,socket)) != 0) { if (outlevel > O_SILENT && outlevel < O_MONITOR) - progress(0, 0, "%s\n",buf); + report(stdout, "%s\n",buf); return(ok); } if ((rxlen = DecBase64(buf)) == 0) { if (outlevel > O_SILENT) - error(0, 0, _("RPA token 4: Base64 decode error\n")); + report(stderr, GT_("RPA token 4: Base64 decode error\n")); return(PS_RPA); } bufp = buf; @@ -250,13 +255,13 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) /* Interpret Token 4 */ - aulin = *(bufp++); + aulin = (unsigned char)*(bufp++); if (outlevel >= O_DEBUG) { - progress(0, 0, _("User authentication (l=%d):"),aulin); + report(stdout, GT_("User authentication (l=%d):\n"),aulin); for (i=0; i= O_DEBUG) - progress(0, 0, _("RPA status: %02X\n"),status); + report(stdout, GT_("RPA status: %02X\n"),status); } else status = 0; if ((bufp - buf) != rxlen) { if (outlevel > O_SILENT) - error(0, 0, _("RPA token 4 length error\n")); + report(stderr, GT_("RPA token 4 length error\n")); return(PS_RPA); } if (status != 0) { - if (outlevel > O_SILENT) - if (status < 4) - error(0, 0, _("RPA rejects you: %s\n"),_(stdec[status])); - else - error(0, 0, _("RPA rejects you, reason unknown\n")); + if (outlevel > O_SILENT) { + if (status < 4) { + report(stderr, GT_("RPA rejects you: %s\n"),GT_(stdec[status])); + } else { + report(stderr, GT_("RPA rejects you, reason unknown\n")); + } + } return(PS_AUTHFAIL); } if (Aul != aulin) { - error(0, 0, _("RPA User Authentication length error: %d\n"),aulin); + report(stderr, + GT_("RPA User Authentication length error: %d\n"),aulin); return(PS_RPA); } if (Kusl != kuslin) { - error(0, 0, _("RPA Session key length error: %d\n"),kuslin); + report(stderr, GT_("RPA Session key length error: %d\n"),kuslin); return(PS_RPA); } if (CheckUserAuth() != 0) { if (outlevel > O_SILENT) - error(0, 0, _("RPA _service_ auth fail. Spoof server?\n")); + report(stderr, GT_("RPA _service_ auth fail. Spoof server?\n")); return(PS_AUTHFAIL); } if (outlevel >= O_DEBUG) { - progress(0, 0, _("Session key established:")); + report(stdout, GT_("Session key established:\n")); for (i=0; i= O_MONITOR) - progress(0, 0, "> %s\n",buf); + report(stdout, "> %s\n",buf); if ((ok = POP3_rpa_resp(buf,socket)) != 0) { if (outlevel > O_SILENT && outlevel < O_MONITOR) - progress(0, 0, "%s\n",buf); + report(stdout, "%s\n",buf); return(ok); } } if (outlevel > O_SILENT) - progress(0, 0, _("RPA authorisation complete\n")); + report(stdout, GT_("RPA authorisation complete\n")); return(PS_SUCCESS); } @@ -353,9 +361,7 @@ int POP3_auth_rpa (unsigned char *userid, unsigned char *passphrase, int socket) globals: reads outlevel. *********************************************************************/ -static int POP3_rpa_resp (argbuf,socket) -unsigned char *argbuf; -int socket; +static int POP3_rpa_resp (char *argbuf, int socket) { int ok; char buf [POPBUFSIZE]; @@ -363,7 +369,7 @@ int socket; int sockrc; if (outlevel >= O_DEBUG) - progress(0, 0, _("Get response\n")); + report(stdout, GT_("Get response\n")); #ifndef TESTMODE sockrc = gen_recv(socket, buf, sizeof(buf)); #else @@ -371,7 +377,7 @@ int socket; if (linecount == 1) strcpy(buf,line1); if (linecount == 2) strcpy(buf,line2); if (linecount == 3) strcpy(buf,line3); -/* progress(0, 0, "--> "); fflush(stderr); */ +/* report(stdout, "--> "); fflush(stderr); */ /* scanf("%s",&buf) */ sockrc = PS_SUCCESS; #endif @@ -393,7 +399,7 @@ int socket; else ok = PS_SOCKET; if (outlevel >= O_DEBUG) - progress(0, 0, _("Get response return %d [%s]\n"), ok, buf); + report(stdout, GT_("Get response return %d [%s]\n"), ok, buf); buf[sockrc] = 0; return(ok); } @@ -412,10 +418,10 @@ int socket; globals: none *********************************************************************/ -static void LenAppend(pptr,len) -unsigned char **pptr; -int len; +static void LenAppend(char **pptr_, int len) { + unsigned char **pptr = (unsigned char **)pptr_; + if (len < 0x80) { **pptr = len; (*pptr)++; @@ -446,48 +452,47 @@ int len; globals: reads outlevel. *********************************************************************/ -int LenSkip(pptr,rxlen) -unsigned char **pptr; -int rxlen; +int LenSkip(char **pptr, int rxlen) { int len; - unsigned char *save; + char *save; save = *pptr; - if (**pptr != HDR) + if ((unsigned char)**pptr != HDR) { - if (outlevel > O_SILENT) error(0, 0, _("Hdr not 60\n")); + if (outlevel > O_SILENT) + report(stderr, GT_("Hdr not 60\n")); return(0); } (*pptr)++; - if (((**pptr) & 0x80) == 0 ) + if (((unsigned char)(**pptr) & 0x80) == 0 ) { - len = **pptr; (*pptr)++; + len = (unsigned char)**pptr; (*pptr)++; } - else if ((**pptr) == 0x81) + else if ((unsigned char)(**pptr) == 0x81) { - len = *(*pptr+1); (*pptr) += 2; + len = (unsigned char)*(*pptr+1); (*pptr) += 2; } - else if ((**pptr) == 0x82) + else if ((unsigned char)(**pptr) == 0x82) { - len = ((*(*pptr+1)) << 8) | *(*pptr+2); + len = ((unsigned char)(*(*pptr+1)) << 8) | (unsigned char)*(*pptr+2); (*pptr) += 3; } else len = 0; if (len==0) { if (outlevel>O_SILENT) - error(0, 0, _("Token length error\n")); + report(stderr, GT_("Token length error\n")); } else if (((*pptr-save)+len) != rxlen) { if (outlevel>O_SILENT) - error(0, 0, _("Token Length %d disagrees with rxlen %d\n"),len,rxlen); + report(stderr, GT_("Token Length %d disagrees with rxlen %d\n"),len,rxlen); len = 0; } else if (memcmp(*pptr,MECH,11)) { if (outlevel > O_SILENT) - error(0, 0, _("Mechanism field incorrect\n")); + report(stderr, GT_("Mechanism field incorrect\n")); len = 0; } else (*pptr) += 11; /* Skip mechanism field */ @@ -507,27 +512,26 @@ int rxlen; globals: reads outlevel. *********************************************************************/ -static int DecBase64(bufp) -unsigned char *bufp; +static int DecBase64(char *bufp) { - unsigned int new, bits=0, cnt=0, i, part=0; + unsigned int newx, bits=0, cnt=0, i, part=0; unsigned char ch; - unsigned char* outp=bufp; - unsigned char* inp=bufp; - while((ch=*(inp++)) != 0) + char* outp=bufp; + char* inp=bufp; + while((ch=(unsigned char)*(inp++)) != 0) { if ((ch != '=') && (ch != ' ') && (ch != '\n') && (ch != '\r')) { - if ((ch>='A') && (ch <= 'Z')) new = ch - 'A'; - else if ((ch>='a') && (ch <= 'z')) new = ch - 'a' + 26; - else if ((ch>='0') && (ch <= '9')) new = ch - '0' + 52; - else if ( ch=='+' ) new = 62; - else if ( ch=='/' ) new = 63; + if ((ch>='A') && (ch <= 'Z')) newx = ch - 'A'; + else if ((ch>='a') && (ch <= 'z')) newx = ch - 'a' + 26; + else if ((ch>='0') && (ch <= '9')) newx = ch - '0' + 52; + else if ( ch=='+' ) newx = 62; + else if ( ch=='/' ) newx = 63; else { - error(0, 0, _("dec64 error at char %d: %x\n"), inp - bufp, ch); + report(stderr, GT_("dec64 error at char %d: %x\n"), (int)(inp - bufp), ch); return(0); } - part=((part & 0x3F)*64) + new; + part=((part & 0x3F)*64) + newx; bits += 6; if (bits >= 8) { @@ -539,12 +543,12 @@ unsigned char *bufp; } if (outlevel >= O_MONITOR) { - progress(0, 0, _("Inbound binary data:\n")); + report(stdout, GT_("Inbound binary data:\n")); for (i=0; i= O_MONITOR) { - progress(0, 0, _("Outbound data:\n")); + report(stdout, GT_("Outbound data:\n")); for (i=0; i=0; i-=3) { - c1 = bufp[i]; - if ((i+1) < len) c2 = bufp[i+1]; else c2=0; - if ((i+2) < len) c3 = bufp[i+2]; else c3=0; + c1 = (unsigned char)bufp[i]; + if ((i+1) < len) c2 = (unsigned char)bufp[i+1]; else c2=0; + if ((i+2) < len) c3 = (unsigned char)bufp[i+2]; else c3=0; *(outp) = x[c1/4]; *(outp+1) = x[((c1 & 3)*16) + (c2/16)]; if ((i+1) < len) *(outp+2) = x[((c2 & 0x0F)*4) + (c3/64)]; @@ -620,12 +622,9 @@ int len; globals: reads outlevel; *********************************************************************/ -static void ToUnicode(pptr,delim,buf,plen,conv) -unsigned char **pptr; /* input string */ -unsigned char delim; -unsigned char *buf; /* output buffer */ -int *plen; -int conv; +static void ToUnicode(char **pptr /* input string*/, + char delim, unsigned char *buf /* output buffer */, + int *plen, int conv) { unsigned char *p; int i; @@ -634,7 +633,7 @@ int conv; { *(p++) = 0; if (conv) - *(p++) = tolower(**pptr); + *(p++) = tolower((unsigned char)**pptr); else *(p++) = (**pptr); (*plen) += 2; @@ -643,17 +642,17 @@ int conv; if ( ((**pptr)!=delim) && ((**pptr)!=0) && ((*plen)==STRMAX) ) { if (outlevel > O_SILENT) - error(0, 0, _("RPA String too long\n")); + report(stderr, GT_("RPA String too long\n")); *plen = 0; } if (outlevel >= O_DEBUG) { - progress(0, 0, _("Unicode:")); + report(stdout, GT_("Unicode:\n")); for (i=0; i<(*plen); i++) { - progress_build("%02X ",buf[i]); + report_build(stdout, "%02X ",buf[i]); if (((i % 16)==15) || (i==((*plen)-1))) - progress_complete(0, 0, ""); + report_complete(stdout, "\n"); } } } @@ -671,8 +670,7 @@ int conv; writes Ns Nsl Nr Nrl *********************************************************************/ -static int SetRealmService(bufp) -unsigned char* bufp; +static int SetRealmService(char *bufp) { /* For the moment we pick the first available realm. It would */ /* make more sense to verify that the realm which the user */ @@ -700,9 +698,7 @@ unsigned char* bufp; reads /dev/random *********************************************************************/ -static void GenChallenge(buf,len) -unsigned char *buf; -int len; +static void GenChallenge(unsigned char *buf, int len) { int i; FILE *devrandom; @@ -710,27 +706,27 @@ int len; devrandom = fopen("/dev/urandom","rb"); if (devrandom == NULL && outlevel > O_SILENT) { - progress(0, 0, _("RPA Failed open of /dev/urandom. This shouldn't\n")); - progress(0, 0, _(" prevent you logging in, but means you\n")); - progress(0, 0, _(" cannot be sure you are talking to the\n")); - progress(0, 0, _(" service that you think you are (replay\n")); - progress(0, 0, _(" attacks by a dishonest service are possible.)\n")); + report(stdout, GT_("RPA Failed open of /dev/urandom. This shouldn't\n")); + report(stdout, GT_(" prevent you logging in, but means you\n")); + report(stdout, GT_(" cannot be sure you are talking to the\n")); + report(stdout, GT_(" service that you think you are (replay\n")); + report(stdout, GT_(" attacks by a dishonest service are possible.)\n")); } for(i=0; i= O_DEBUG) { - progress(0, 0, _("User challenge:")); + report(stdout, GT_("User challenge:\n")); for (i=0; i= O_DEBUG) { - progress(0, 0, _("MD5 being applied to data block:\n")); + report(stdout, GT_("MD5 being applied to data block:\n")); for (i=0; i= O_DEBUG) { - progress(0, 0, _("MD5 result is: ")); + report(stdout, GT_("MD5 result is:\n")); for (i=0; i<16; i++) { - progress_build("%02X ",out[i]); + report_build(stdout, "%02X ",out[i]); } - progress_complete(0, 0, ""); + report_complete(stdout, "\n"); } } #endif /* POP3_ENABLE && RPA_ENABLE */