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 <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
+#include <string.h>
+#include <sys/types.h>
#include "socket.h"
#include "fetchmail.h"
-#include "md5.h"
+#include "fm_md5.h"
+#include "gettext.h"
#ifdef TESTMODE
extern unsigned char line1[];
extern int linecount;
#endif
-#ifndef NO_PROTO
- /* prototypes for internal functions */
- int POP3_rpa_resp(unsigned char* argbuf, int socket );
- void LenAppend(unsigned char** pptr, int len);
- int LenSkip(unsigned char** pptr, int rxlen);
- int DecBase64(unsigned char* bufp);
- void EncBase64(unsigned char* bufp, int len);
- void ToUnicode(unsigned char** pptr, unsigned char delim,
- unsigned char* buf, int* plen, int conv);
- int SetRealmService(unsigned char* bufp);
- void GenChallenge(unsigned char* buf, int len);
- int DigestPassphrase(unsigned char* passphrase,unsigned char* rbuf, int unicodeit);
- void CompUserResp();
- int CheckUserAuth();
- void md5(unsigned char* in, int len, unsigned char* out);
-#endif
+/* 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);
/* RPA protocol definitions */
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] = { "Success" ,
- "Restricted user (something wrong with account)" ,
- "Invalid userid or passphrase" ,
- "Deity error" };
+ 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_VERBOSE)
- fprintf(stderr,"> AUTH RPA\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 */
if ((ok = POP3_rpa_resp(buf,socket)) != 0)
{
- if (outlevel > O_SILENT && outlevel < O_VERBOSE)
- fprintf(stderr,"%s\n",buf);
+ if (outlevel > O_SILENT && outlevel < O_MONITOR)
+ report(stdout, "%s\n",buf);
return(ok);
}
#ifndef TESTMODE
SockPrintf(socket,"%s\r\n",buf);
#endif
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"> %s\n",buf);
+ if (outlevel >= O_MONITOR)
+ report(stdout, "> %s\n",buf);
if ((ok = POP3_rpa_resp(buf,socket)) != 0)
{
- if (outlevel > O_SILENT && outlevel < O_VERBOSE)
- fprintf(stderr,"%s\n",buf);
+ if (outlevel > O_SILENT && outlevel < O_MONITOR)
+ report(stdout, "%s\n",buf);
return(ok);
}
if ((rxlen = DecBase64(buf)) == 0)
{
if (outlevel > O_SILENT)
- fprintf(stderr,"RPA token 2: Base64 decode error\n");
+ report(stderr, GT_("RPA token 2: Base64 decode error\n"));
return(PS_RPA);
}
bufp = buf;
/* Interpret Token 2 */
- verh = *(bufp++); verl = *(bufp++);
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"Service chose RPA version %d.%d\n",verh,verl);
- Csl = *(bufp++);
+ 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_VERBOSE)
+ if (outlevel >= O_DEBUG)
{
- fprintf(stderr,"Service challenge (l=%d):",Csl);
- for (i=0; i<Csl; i++) fprintf(stderr," %02X",Cs[i]);
- fprintf(stderr,"\n");
+ report(stdout, GT_("Service challenge (l=%d):\n"),Csl);
+ for (i=0; i<Csl; i++)
+ report_build(stdout, "%02X ",Cs[i]);
+ report_complete(stdout, "\n");
}
memcpy(Ts, bufp, Tsl);
Ts[Tsl] = 0;
bufp += Tsl;
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"Service timestamp %s\n",Ts);
- rll = *(bufp++) << 8; rll = rll | *(bufp++);
+ if (outlevel >= 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)
- fprintf(stderr,"RPA token 2 length error\n");
+ report(stderr, GT_("RPA token 2 length error\n"));
return(PS_RPA);
}
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"Realm list: %s\n",bufp);
+ if (outlevel >= O_DEBUG)
+ report(stdout, GT_("Realm list: %s\n"),bufp);
if (SetRealmService(bufp) != 0)
{
if (outlevel > O_SILENT)
- fprintf(stderr,"RPA error in service@realm string\n");
+ report(stderr, GT_("RPA error in service@realm string\n"));
return(PS_RPA);
}
*(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);
+ *(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);
+ SockPrintf(socket,"%s\r\n",buf);
#endif
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"> %s\n",buf);
- if ((ok = POP3_rpa_resp(buf,socket)) != 0)
+ if (outlevel >= O_MONITOR)
+ report(stdout, "> %s\n",buf);
+ if ((ok = POP3_rpa_resp(buf,socket)) != 0)
{
- if (outlevel > O_SILENT && outlevel < O_VERBOSE)
- fprintf(stderr,"%s\n",buf);
- return(ok);
+ if (outlevel > O_SILENT && outlevel < O_MONITOR)
+ report(stdout, "%s\n",buf);
+ return(ok);
}
- if ((rxlen = DecBase64(buf)) == 0)
+ if ((rxlen = DecBase64(buf)) == 0)
{
- if (outlevel > O_SILENT)
- fprintf(stderr,"RPA token 4: Base64 decode error\n");
- return(PS_RPA);
+ if (outlevel > O_SILENT)
+ report(stderr, GT_("RPA token 4: Base64 decode error\n"));
+ return(PS_RPA);
}
- bufp = buf;
- if (LenSkip(&bufp,rxlen) == 0) return(PS_RPA);
+ bufp = buf;
+ if (LenSkip(&bufp,rxlen) == 0) return(PS_RPA);
- /* Interpret Token 4 */
+ /* Interpret Token 4 */
- aulin = *(bufp++);
- if (outlevel == O_VERBOSE)
+ aulin = (unsigned char)*(bufp++);
+ if (outlevel >= O_DEBUG)
{
- fprintf(stderr,"User authentication (l=%d):",aulin);
- for (i=0; i<aulin; i++) fprintf(stderr," %02X",bufp[i]);
- fprintf(stderr,"\n");
+ report(stdout, GT_("User authentication (l=%d):\n"),aulin);
+ for (i=0; i<aulin; i++)
+ report_build(stdout, "%02X ",bufp[i]);
+ report_complete(stdout, "\n");
}
- if (aulin == Aul) memcpy(Au, bufp, Aul);
- bufp += aulin;
- kuslin = *(bufp++);
- if (kuslin == Kusl) memcpy(Kusu, bufp, Kusl); /* blinded */
- bufp += kuslin;
- if (verh == 3)
+ if (aulin == Aul) memcpy(Au, bufp, Aul);
+ bufp += aulin;
+ kuslin = *(bufp++);
+ if (kuslin == Kusl) memcpy(Kusu, bufp, Kusl); /* blinded */
+ bufp += kuslin;
+ if (verh == 3)
{
- status = *(bufp++);
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"RPA status: %02X\n",status);
+ status = *(bufp++);
+ if (outlevel >= O_DEBUG)
+ report(stdout, GT_("RPA status: %02X\n"),status);
}
- else status = 0;
- if ((bufp - buf) != rxlen)
+ else status = 0;
+ if ((bufp - buf) != rxlen)
{
- if (outlevel > O_SILENT)
- fprintf(stderr,"RPA token 4 length error\n");
- return(PS_RPA);
+ if (outlevel > O_SILENT)
+ report(stderr, GT_("RPA token 4 length error\n"));
+ return(PS_RPA);
}
- if (status != 0)
+ if (status != 0)
{
- if (outlevel > O_SILENT)
- if (status < 4)
- fprintf(stderr,"RPA rejects you: %s\n",stdec[status]);
- else
- fprintf(stderr,"RPA rejects you, reason unknown\n");
- return(PS_AUTHFAIL);
+ 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)
+ if (Aul != aulin)
{
- fprintf(stderr,"RPA User Authentication length error: %d\n",aulin);
- return(PS_RPA);
+ report(stderr,
+ GT_("RPA User Authentication length error: %d\n"),aulin);
+ return(PS_RPA);
}
- if (Kusl != kuslin)
+ if (Kusl != kuslin)
{
- fprintf(stderr,"RPA Session key length error: %d\n",kuslin);
- return(PS_RPA);
+ report(stderr, GT_("RPA Session key length error: %d\n"),kuslin);
+ return(PS_RPA);
}
- if (CheckUserAuth() != 0)
+ if (CheckUserAuth() != 0)
{
- if (outlevel > O_SILENT)
- fprintf(stderr,"RPA _service_ auth fail. Spoof server?\n");
- return(PS_AUTHFAIL);
+ if (outlevel > O_SILENT)
+ report(stderr, GT_("RPA _service_ auth fail. Spoof server?\n"));
+ return(PS_AUTHFAIL);
}
- if (outlevel == O_VERBOSE)
+ if (outlevel >= O_DEBUG)
{
- fprintf(stderr,"Session key established:");
- for (i=0; i<Kusl; i++) fprintf(stderr," %02X",Kus[i]);
- fprintf(stderr,"\n");
+ report(stdout, GT_("Session key established:\n"));
+ for (i=0; i<Kusl; i++)
+ report_build(stdout, "%02X ",Kus[i]);
+ report_complete(stdout, "\n");
}
- /* Assemble Token 5 in buf and send (not in ver 2 though) */
- /* Version 3.0 definitely replies with +OK to this. I have */
- /* no idea what sort of response previous versions gave. */
+ /* Assemble Token 5 in buf and send (not in ver 2 though) */
+ /* Version 3.0 definitely replies with +OK to this. I have */
+ /* no idea what sort of response previous versions gave. */
- if (verh != 2)
+ if (verh != 2)
{
- bufp = buf;
- *(bufp++) = HDR;
- LenAppend(&bufp, 1 );
- *(bufp++) = 0x42;
- EncBase64(buf,bufp-buf);
+ bufp = buf;
+ *(bufp++) = HDR;
+ LenAppend(&bufp, 1 );
+ *(bufp++) = 0x42;
+ EncBase64(buf,bufp-buf);
#ifndef TESTMODE
- SockPrintf(socket,"%s\r\n",buf);
+ SockPrintf(socket,"%s\r\n",buf);
#endif
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"> %s\n",buf);
- if ((ok = POP3_rpa_resp(buf,socket)) != 0)
- {
- if (outlevel > O_SILENT && outlevel < O_VERBOSE)
- fprintf(stderr,"%s\n",buf);
- return(ok);
- }
+ 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 (outlevel > O_SILENT)
- fprintf(stderr,"RPA authorisation complete\n");
+ if (outlevel > O_SILENT)
+ report(stdout, GT_("RPA authorisation complete\n"));
- return(PS_SUCCESS);
+ return(PS_SUCCESS);
}
globals: reads outlevel.
*********************************************************************/
-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];
- char *bufp;
- int sockrc;
- fprintf(stderr, "Get response\n");
+ int ok;
+ char buf [POPBUFSIZE];
+ char *bufp;
+ int sockrc;
+
+ if (outlevel >= O_DEBUG)
+ report(stdout, GT_("Get response\n"));
#ifndef TESTMODE
- sockrc = SockRead(socket, buf, sizeof(buf));
+ sockrc = gen_recv(socket, buf, sizeof(buf));
#else
- linecount++;
- if (linecount == 1) strcpy(buf,line1);
- if (linecount == 2) strcpy(buf,line2);
- if (linecount == 3) strcpy(buf,line3);
-/* fprintf(stderr,"--> "); fflush(stderr); */
+ linecount++;
+ if (linecount == 1) strcpy(buf,line1);
+ if (linecount == 2) strcpy(buf,line2);
+ if (linecount == 3) strcpy(buf,line3);
+/* report(stdout, "--> "); fflush(stderr); */
/* scanf("%s",&buf) */
- sockrc = 0;
+ sockrc = PS_SUCCESS;
#endif
- if (sockrc > 0) {
- buf[sockrc] = 0;
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"%s\n",buf);
-
- bufp = buf;
- if ((*buf) == '+')
- {
- bufp++;
+ if (sockrc == PS_SUCCESS) {
+ bufp = buf;
+ if ((*buf) == '+')
+ {
+ bufp++;
/* if (*bufp == ' ') bufp++; */
- if (argbuf != NULL)
- strcpy(argbuf,bufp);
- ok=0;
- }
- else if (strcmp(buf,"-ERR") == 0)
- ok = PS_ERROR;
- else ok = PS_PROTOCOL;
-
- }
- else
- ok = PS_SOCKET;
- fprintf(stderr, "Get response return %d [%s]\n", ok, buf);
- buf[sockrc] = 0;
- return(ok);
+ if (argbuf != NULL)
+ strcpy(argbuf,bufp);
+ ok=0;
+ }
+ else if (strcmp(buf,"-ERR") == 0)
+ ok = PS_ERROR;
+ else ok = PS_PROTOCOL;
+
+ }
+ else
+ ok = PS_SOCKET;
+ if (outlevel >= O_DEBUG)
+ report(stdout, GT_("Get response return %d [%s]\n"), ok, buf);
+ buf[sockrc] = 0;
+ return(ok);
}
/*********************************************************************
globals: none
*********************************************************************/
-void LenAppend(pptr,len)
-unsigned char **pptr;
-int len;
+static void LenAppend(char **pptr_, int len)
{
- if (len < 0x80)
+ unsigned char **pptr = (unsigned char **)pptr_;
+
+ if (len < 0x80)
{
- **pptr = len; (*pptr)++;
+ **pptr = len; (*pptr)++;
}
- else if (len < 0x100)
+ else if (len < 0x100)
{
- **pptr = 0x81; (*pptr)++;
- **pptr = len; (*pptr)++;
+ **pptr = 0x81; (*pptr)++;
+ **pptr = len; (*pptr)++;
}
- else
+ else
{
- **pptr = 0x82; (*pptr)++;
- **pptr = len >> 8; (*pptr)++;
- **pptr = len & 0xFF; (*pptr)++;
+ **pptr = 0x82; (*pptr)++;
+ **pptr = len >> 8; (*pptr)++;
+ **pptr = len & 0xFF; (*pptr)++;
}
}
globals: reads outlevel.
*********************************************************************/
-int LenSkip(pptr,rxlen)
-unsigned char **pptr;
-int rxlen;
+int LenSkip(char **pptr, int rxlen)
{
- int len;
- unsigned char *save;
- save = *pptr;
- if (**pptr != HDR)
+ int len;
+ char *save;
+ save = *pptr;
+ if ((unsigned char)**pptr != HDR)
{
- if (outlevel > O_SILENT) fprintf(stderr,"Hdr not 60\n");
- return(0);
+ if (outlevel > O_SILENT)
+ report(stderr, GT_("Hdr not 60\n"));
+ return(0);
}
- (*pptr)++;
- if (((**pptr) & 0x80) == 0 )
+ (*pptr)++;
+ 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);
- (*pptr) += 3;
+ len = ((unsigned char)(*(*pptr+1)) << 8) | (unsigned char)*(*pptr+2);
+ (*pptr) += 3;
}
- else len = 0;
- if (len==0)
+ else len = 0;
+ if (len==0)
{
- if (outlevel>O_SILENT)
- fprintf(stderr,"Token length error\n");
+ if (outlevel>O_SILENT)
+ report(stderr, GT_("Token length error\n"));
}
- else if (((*pptr-save)+len) != rxlen)
+ else if (((*pptr-save)+len) != rxlen)
{
- if (outlevel>O_SILENT)
- fprintf(stderr,"Token Length %d disagrees with rxlen %d\n",len,rxlen);
- len = 0;
+ if (outlevel>O_SILENT)
+ report(stderr, GT_("Token Length %d disagrees with rxlen %d\n"),len,rxlen);
+ len = 0;
}
- else if (memcmp(*pptr,MECH,11))
+ else if (memcmp(*pptr,MECH,11))
{
- if (outlevel > O_SILENT)
- fprintf(stderr,"Mechanism field incorrect\n");
- len = 0;
+ if (outlevel > O_SILENT)
+ report(stderr, GT_("Mechanism field incorrect\n"));
+ len = 0;
}
- else (*pptr) += 11; /* Skip mechanism field */
- return(len);
+ else (*pptr) += 11; /* Skip mechanism field */
+ return(len);
}
/*********************************************************************
globals: reads outlevel.
*********************************************************************/
-int DecBase64(bufp)
-unsigned char *bufp;
+static int DecBase64(char *bufp)
{
- unsigned int new, bits=0, cnt=0, i, part=0;
- unsigned char ch;
- unsigned char* outp=bufp;
- unsigned char* inp=bufp;
- while((ch=*(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;
- else {
- fprintf(stderr, "dec64 error at char %d: %x\n", inp - bufp, ch);
- return(0);
- }
- part=((part & 0x3F)*64) + new;
- bits += 6;
- if (bits >= 8)
- {
- bits -= 8;
- *outp = (part >> bits);
- cnt++; outp++;
- }
- }
- }
- if (outlevel == O_VERBOSE)
- {
- fprintf(stderr,"Inbound binary data:\n");
- for (i=0; i<cnt; i++)
- {
- fprintf(stderr," %02X",bufp[i]);
- if (((i % 16)==15) || (i==(cnt-1)))
- fprintf(stderr,"\n");
- }
- }
- return(cnt);
+ unsigned int newx, bits=0, cnt=0, i, part=0;
+ unsigned char ch;
+ char* outp=bufp;
+ char* inp=bufp;
+ while((ch=(unsigned char)*(inp++)) != 0)
+ {
+ if ((ch != '=') && (ch != ' ') && (ch != '\n') && (ch != '\r'))
+ {
+ 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 {
+ report(stderr, GT_("dec64 error at char %d: %x\n"), (int)(inp - bufp), ch);
+ return(0);
+ }
+ part=((part & 0x3F)*64) + newx;
+ bits += 6;
+ if (bits >= 8)
+ {
+ bits -= 8;
+ *outp = (part >> bits);
+ cnt++; outp++;
+ }
+ }
+ }
+ if (outlevel >= O_MONITOR)
+ {
+ report(stdout, GT_("Inbound binary data:\n"));
+ for (i=0; i<cnt; i++)
+ {
+ report_build(stdout, "%02X ",(unsigned char)bufp[i]);
+ if (((i % 16)==15) || (i==(cnt-1)))
+ report_complete(stdout, "\n");
+ }
+ }
+ return(cnt);
}
/*********************************************************************
globals: reads outlevel;
*********************************************************************/
-void EncBase64(bufp,len)
-unsigned char *bufp;
-int len;
+static void EncBase64(char *bufp, int len)
{
- unsigned char* outp;
- unsigned char c1,c2,c3;
- char x[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- int i;
-
- if (outlevel == O_VERBOSE)
- {
- fprintf(stderr,"Outbound data:\n");
- for (i=0; i<len; i++)
- {
- fprintf(stderr," %02X",bufp[i]);
- if (((i % 16)==15) || (i==(len-1)))
- fprintf(stderr,"\n");
- }
- }
- outp = bufp + (((len-1)/3)*4);
- *(outp+4) = 0;
- /* So we can do the update in place, start at the far end! */
- for (i=((len-1)/3)*3; 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;
- *(outp) = x[c1/4];
- *(outp+1) = x[((c1 & 3)*16) + (c2/16)];
- if ((i+1) < len) *(outp+2) = x[((c2 & 0x0F)*4) + (c3/64)];
- else *(outp+2) = '=';
- if ((i+2) < len) *(outp+3) = x[c3 & 0x3F];
- else *(outp+3) = '=';
- outp -= 4;
+ char* outp;
+ unsigned char c1,c2,c3;
+ char x[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ int i;
+
+ if (outlevel >= O_MONITOR)
+ {
+ report(stdout, GT_("Outbound data:\n"));
+ for (i=0; i<len; i++)
+ {
+ report_build(stdout, "%02X ",(unsigned char)bufp[i]);
+ if (((i % 16)==15) || (i==(len-1)))
+ report_complete(stdout, "\n");
+ }
+ }
+ outp = bufp + (((len-1)/3)*4);
+ *(outp+4) = 0;
+ /* So we can do the update in place, start at the far end! */
+ for (i=((len-1)/3)*3; i>=0; i-=3)
+ {
+ 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)];
+ else *(outp+2) = '=';
+ if ((i+2) < len) *(outp+3) = x[c3 & 0x3F];
+ else *(outp+3) = '=';
+ outp -= 4;
}
}
globals: reads outlevel;
*********************************************************************/
-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;
- *plen = 0; p=buf;
- while ( ((**pptr)!=delim) && ((**pptr)!=0) && ((*plen)<STRMAX) )
- {
- *(p++) = 0;
- if (conv)
- *(p++) = tolower(**pptr);
- else
- *(p++) = (**pptr);
- (*plen) += 2;
- (*pptr)++;
+ unsigned char *p;
+ int i;
+ *plen = 0; p=buf;
+ while ( ((**pptr)!=delim) && ((**pptr)!=0) && ((*plen)<STRMAX) )
+ {
+ *(p++) = 0;
+ if (conv)
+ *(p++) = tolower((unsigned char)**pptr);
+ else
+ *(p++) = (**pptr);
+ (*plen) += 2;
+ (*pptr)++;
}
- if ( ((**pptr)!=delim) && ((**pptr)!=0) && ((*plen)==STRMAX) )
+ if ( ((**pptr)!=delim) && ((**pptr)!=0) && ((*plen)==STRMAX) )
{
- if (outlevel > O_SILENT)
- fprintf(stderr,"RPA String too long\n");
- *plen = 0;
+ if (outlevel > O_SILENT)
+ report(stderr, GT_("RPA String too long\n"));
+ *plen = 0;
}
- if (outlevel == O_VERBOSE)
+ if (outlevel >= O_DEBUG)
{
- fprintf(stderr,"Unicode:");
- for (i=0; i<(*plen); i++) fprintf(stderr,"%02X ",buf[i]);
- fprintf(stderr,"\n");
+ report(stdout, GT_("Unicode:\n"));
+ for (i=0; i<(*plen); i++)
+ {
+ report_build(stdout, "%02X ",buf[i]);
+ if (((i % 16)==15) || (i==((*plen)-1)))
+ report_complete(stdout, "\n");
+ }
}
}
writes Ns Nsl Nr Nrl
*********************************************************************/
-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 */
- /* has given (as part of id) is in the list, and select it's */
- /* corresponding service name. */
- ToUnicode(&bufp, '@', Ns, &Nsl, 1); /* Service */
- bufp++; /* Skip the @ */
- ToUnicode(&bufp, ' ', Nr, &Nrl, 1); /* Realm name */
- if ((Nrl == 0) || (Nsl == 0))
- return(PS_RPA);
- return(0);
+ /* For the moment we pick the first available realm. It would */
+ /* make more sense to verify that the realm which the user */
+ /* has given (as part of id) is in the list, and select it's */
+ /* corresponding service name. */
+ ToUnicode(&bufp, '@', Ns, &Nsl, 1); /* Service */
+ bufp++; /* Skip the @ */
+ ToUnicode(&bufp, ' ', Nr, &Nrl, 1); /* Realm name */
+ if ((Nrl == 0) || (Nsl == 0))
+ return(PS_RPA);
+ return(0);
}
/*********************************************************************
reads /dev/random
*********************************************************************/
-void GenChallenge(buf,len)
-unsigned char *buf;
-int len;
+static void GenChallenge(unsigned char *buf, int len)
{
- int i;
- FILE *devrandom;
- devrandom = fopen("/dev/urandom","rb");
- if (devrandom == NULL)
+ int i;
+ FILE *devrandom;
+
+ devrandom = fopen("/dev/urandom","rb");
+ if (devrandom == NULL && outlevel > O_SILENT)
{
- if (outlevel > O_SILENT)
- fprintf(stderr,"RPA Failed open of /dev/random. This shouldn't\n");
- fprintf(stderr," prevent you logging in, but means you\n");
- fprintf(stderr," cannot be sure you are talking to the\n");
- fprintf(stderr," service that you think you are (replay\n");
- fprintf(stderr," 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<len; i++) buf[i] = fgetc(devrandom);
-// for (i=0; i<len; i++) buf[i] = random();
- fclose(devrandom);
- if (outlevel == O_VERBOSE)
+
+ for(i=0; i<len; i++)
+ buf[i] = devrandom ? fgetc(devrandom) : random();
+
+ if (devrandom)
+ fclose(devrandom); /* should be safe, file mode was "r" */
+
+ if (outlevel >= O_DEBUG)
{
- fprintf(stderr,"User challenge:");
- for (i=0; i<len; i++) fprintf(stderr," %02X",buf[i]);
- fprintf(stderr,"\n");
+ report(stdout, GT_("User challenge:\n"));
+ for (i=0; i<len; i++)
+ {
+ report_build(stdout, "%02X ",buf[i]);
+ if (((i % 16)==15) || (i==(len-1)))
+ report_complete(stdout, "\n");
+ }
}
}
writes Pu.
*********************************************************************/
-int DigestPassphrase(passphrase,rbuf,unicodeit)
-unsigned char *passphrase;
-unsigned char *rbuf;
-int unicodeit;
+static int DigestPassphrase(char *passphrase,unsigned char *rbuf,
+ int unicodeit)
{
- int len;
- unsigned char workarea[STRMAX];
- unsigned char* ptr;
+ int len;
+ unsigned char workarea[STRMAX];
+ char* ptr;
- if (unicodeit) /* Option in spec. Yuck. */
- {
- ptr = passphrase;
- ToUnicode(&ptr, '\0', workarea, &len, 0); /* No case conv here */
- if (len == 0)
- return(PS_SYNTAX);
- ptr = workarea;
- }
- else
+ if (unicodeit) /* Option in spec. Yuck. */
{
- ptr = rbuf;
- len = strlen(passphrase);
+ ptr = passphrase;
+ ToUnicode(&ptr, '\0', workarea, &len, 0); /* No case conv here */
+ if (len == 0)
+ return(PS_SYNTAX);
+ md5(workarea,len,rbuf);
}
- md5(ptr,len,rbuf);
- return(0);
+ else
+ md5(rbuf,strlen(passphrase),rbuf);
+ return(0);
}
/*********************************************************************
writes Ru.
*********************************************************************/
-void CompUserResp()
+static void CompUserResp(void)
{
- unsigned char workarea[Pul+48+STRMAX*5+Tsl+Pul];
- unsigned char* p;
- p = workarea;
- memcpy(p , Pu, Pul); p += Pul;
- memset(p , '\0', 48); p += 48;
- memcpy(p , Nu, Nul); p += Nul;
- memcpy(p , Ns, Nsl); p += Nsl;
- memcpy(p , Nr, Nrl); p += Nrl;
- memcpy(p , Cu, Cul); p += Cul;
- memcpy(p , Cs, Csl); p += Csl;
- memcpy(p , Ts, Tsl); p += Tsl;
- memcpy(p , Pu, Pul); p += Pul;
- md5(workarea,p-workarea,Ru);
+ unsigned char workarea[Pul+48+STRMAX*5+Tsl+Pul];
+ unsigned char* p;
+ p = workarea;
+ memcpy(p , Pu, Pul); p += Pul;
+ memset(p , '\0', 48); p += 48;
+ memcpy(p , Nu, Nul); p += Nul;
+ memcpy(p , Ns, Nsl); p += Nsl;
+ memcpy(p , Nr, Nrl); p += Nrl;
+ memcpy(p , Cu, Cul); p += Cul;
+ memcpy(p , Cs, Csl); p += Csl;
+ memcpy(p , Ts, Tsl); p += Tsl;
+ memcpy(p , Pu, Pul); p += Pul;
+ md5(workarea,p-workarea,Ru);
}
/*********************************************************************
writes Ru.
*********************************************************************/
-int CheckUserAuth()
+static int CheckUserAuth(void)
{
- unsigned char workarea[Pul+48+STRMAX*7+Tsl+Pul];
- unsigned char* p;
- unsigned char md5ans[16];
- int i;
+ unsigned char workarea[Pul+48+STRMAX*7+Tsl+Pul];
+ unsigned char* p;
+ unsigned char md5ans[16];
+ int i;
/* Create unobscured Kusu */
- p = workarea;
- memcpy(p , Pu, Pul); p += Pul;
- memset(p , '\0', 48); p += 48;
- memcpy(p , Ns, Nsl); p += Nsl;
- memcpy(p , Nu, Nul); p += Nul;
- memcpy(p , Nr, Nrl); p += Nrl;
- memcpy(p , Cs, Csl); p += Csl;
- memcpy(p , Cu, Cul); p += Cul;
- memcpy(p , Ts, Tsl); p += Tsl;
- memcpy(p , Pu, Pul); p += Pul;
- md5(workarea,p-workarea,md5ans);
- for (i=0; i<16; i++) Kus[i] = Kusu[i] ^ md5ans[i];
+ p = workarea;
+ memcpy(p , Pu, Pul); p += Pul;
+ memset(p , '\0', 48); p += 48;
+ memcpy(p , Ns, Nsl); p += Nsl;
+ memcpy(p , Nu, Nul); p += Nul;
+ memcpy(p , Nr, Nrl); p += Nrl;
+ memcpy(p , Cs, Csl); p += Csl;
+ memcpy(p , Cu, Cul); p += Cul;
+ memcpy(p , Ts, Tsl); p += Tsl;
+ memcpy(p , Pu, Pul); p += Pul;
+ md5(workarea,p-workarea,md5ans);
+ for (i=0; i<16; i++) Kus[i] = Kusu[i] ^ md5ans[i];
/* Compute Au from our information */
- p = workarea;
- memcpy(p , Pu, Pul); p += Pul;
- memset(p , '\0', 48); p += 48;
- memcpy(p , Ns, Nsl); p += Nsl;
- memcpy(p , Nu, Nul); p += Nul;
- memcpy(p , Nr, Nrl); p += Nrl;
- memcpy(p , Kusu,Kusl);p += Kusl;
- memcpy(p , Cs, Csl); p += Csl;
- memcpy(p , Cu, Cul); p += Cul;
- memcpy(p , Ts, Tsl); p += Tsl;
- memcpy(p , Kus, Kusl);p += Kusl;
- memcpy(p , Pu, Pul); p += Pul;
- md5(workarea,p-workarea,md5ans);
+ p = workarea;
+ memcpy(p , Pu, Pul); p += Pul;
+ memset(p , '\0', 48); p += 48;
+ memcpy(p , Ns, Nsl); p += Nsl;
+ memcpy(p , Nu, Nul); p += Nul;
+ memcpy(p , Nr, Nrl); p += Nrl;
+ memcpy(p , Kusu,Kusl);p += Kusl;
+ memcpy(p , Cs, Csl); p += Csl;
+ memcpy(p , Cu, Cul); p += Cul;
+ memcpy(p , Ts, Tsl); p += Tsl;
+ memcpy(p , Kus, Kusl);p += Kusl;
+ memcpy(p , Pu, Pul); p += Pul;
+ md5(workarea,p-workarea,md5ans);
/* Compare the two */
- for (i=0; i<16; i++)
- if (Au[i] != md5ans[i]) return(PS_RPA);
- return(0);
+ for (i=0; i<16; i++)
+ if (Au[i] != md5ans[i]) return(PS_RPA);
+ return(0);
}
/*********************************************************************
globals: reads outlevel
*********************************************************************/
-void md5(in,len,out)
-unsigned char* in;
-int len;
-unsigned char* out;
+static void md5(const void *in_,int len,unsigned char *out)
{
- int i;
- MD5_CTX md5context;
-
- if (outlevel == O_VERBOSE)
- {
- fprintf(stderr,"MD5 being applied to data block:\n");
- for (i=0; i<len; i++)
- {
- fprintf(stderr," %02X",in[i]);
- if (((i % 16)==15) || (i==(len-1))) fprintf(stderr,"\n");
- }
- }
- MD5Init( &md5context );
- MD5Update( &md5context, in, len );
- MD5Final( out, &md5context );
- if (outlevel == O_VERBOSE)
- {
- fprintf(stderr,"MD5 result is: ");
- for (i=0; i<16; i++) fprintf(stderr,"%02X ",out[i]);
- fprintf(stderr,"\n");
+ int i;
+ MD5_CTX md5context;
+ const unsigned char *in = (const unsigned char *)in_;
+
+ if (outlevel >= O_DEBUG)
+ {
+ report(stdout, GT_("MD5 being applied to data block:\n"));
+ for (i=0; i<len; i++)
+ {
+ report_build(stdout, "%02X ",in[i]);
+ if (((i % 16)==15) || (i==(len-1)))
+ report_complete(stdout, "\n");
+ }
+ }
+ MD5Init( &md5context );
+ MD5Update( &md5context, in, len );
+ MD5Final( out, &md5context );
+ if (outlevel >= O_DEBUG)
+ {
+ report(stdout, GT_("MD5 result is:\n"));
+ for (i=0; i<16; i++)
+ {
+ report_build(stdout, "%02X ",out[i]);
+ }
+ report_complete(stdout, "\n");
}
}
#endif /* POP3_ENABLE && RPA_ENABLE */