Add outsize parameter to en64

This commit is contained in:
Vladimir Dubrovin 2026-08-08 17:58:49 +03:00
parent 7eba73fc8f
commit eceb5a22df
7 changed files with 23 additions and 17 deletions

View File

@ -6,6 +6,7 @@
*/
#include <string.h>
#include <limits.h>
static const unsigned char base64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@ -23,8 +24,10 @@ static const unsigned char base64val[] = {
};
#define DECODE64(c) ((c > 32 && c<127)? base64val[(int)c] : BAD)
unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen)
unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen, int outsize)
{
if (inlen < 0 || inlen > (INT_MAX - 2) || outsize < 1) return NULL;
if (((inlen + 2) / 3) > ((outsize - 1) / 4)) return NULL;
for (; inlen > 0; inlen -= 3, in+=3)
{
@ -42,6 +45,7 @@ int de64 (const char *in, char *out, int maxlen)
int len = 0;
register unsigned char digit1, digit2, digit3, digit4;
if (maxlen < 0) return(-1);
if (in[0] == '+' && in[1] == ' ')
in += 2;
if (*in == '\r')
@ -61,20 +65,23 @@ int de64 (const char *in, char *out, int maxlen)
if (digit4 != '=' && DECODE64(digit4) == BAD)
return(-1);
in += 4;
if (len >= maxlen) return (len);
*out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
++len;
if (digit3 != '=')
{
if (len >= maxlen) return (len);
*out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
++len;
if (digit4 != '=')
{
if (len >= maxlen) return (len);
*out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
++len;
}
}
} while
(*in && *in != '\r' && digit4 != '=' && (maxlen-=4) >= 4);
(*in && *in != '\r' && digit4 != '=');
return (len);
}

View File

@ -182,12 +182,12 @@ void * imappchild(struct clientparam* param) {
if(method == CL_PLAIN){
i = (int)strlen((char *)param->extusername);
res = (int)strlen((char *)pb);
if(((i + res + 4) / 3) * 4 + 1 > (int)sizeof(srvbuf)) {RETURN(693);}
if(i + res + 2 > (int)sizeof(ibuf)) {RETURN(693);}
ibuf[0] = 0;
memcpy(ibuf + 1, param->extusername, i);
ibuf[i + 1] = 0;
memcpy(ibuf + i + 2, pb, res);
en64(ibuf, srvbuf, i + res + 2);
if(!en64(ibuf, srvbuf, i + res + 2, (int)sizeof(srvbuf))) {RETURN(693);}
if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), conf.timeouts[STRING_S]) <= 0 ||
socksend(param, param->remsock, (unsigned char *)" AUTHENTICATE PLAIN ", 20, conf.timeouts[STRING_S])!= 20 ||
socksend(param, param->remsock, srvbuf, (int)strlen((char *)srvbuf), conf.timeouts[STRING_S]) <= 0 ||
@ -200,15 +200,13 @@ void * imappchild(struct clientparam* param) {
{RETURN(699);}
i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]);
if(i < 1 || *srvbuf != '+') {RETURN(699);}
if(((int)strlen((char *)param->extusername) + 2) / 3 * 4 + 1 > (int)sizeof(ibuf) - 3) {RETURN(693);}
en64(param->extusername, ibuf, (int)strlen((char *)param->extusername));
if(!en64(param->extusername, ibuf, (int)strlen((char *)param->extusername), (int)sizeof(ibuf))) {RETURN(693);}
if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), conf.timeouts[STRING_S]) <= 0 ||
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
{RETURN(699);}
i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]);
if(i < 1 || *srvbuf != '+') {RETURN(699);}
if(((int)strlen((char *)pb) + 2) / 3 * 4 + 1 > (int)sizeof(ibuf) - 3) {RETURN(693);}
en64(pb, ibuf, (int)strlen((char *)pb));
if(!en64(pb, ibuf, (int)strlen((char *)pb), (int)sizeof(ibuf))) {RETURN(693);}
if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), conf.timeouts[STRING_S]) <= 0 ||
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
{RETURN(699);}

View File

@ -929,7 +929,8 @@ for(;;){
if(param->extusername){
hlen += sprintf((char*)buf + hlen, "%s: Basic ", (redirect)?"Proxy-Authorization":"Authorization");
sprintf((char*)username, "%.128s:%.128s", param->extusername, param->extpassword?param->extpassword:(unsigned char*)"");
hlen = (int)(en64(username, buf + hlen, (int)strlen((char *)username)) - buf);
if(!(sb = en64(username, buf + hlen, (int)strlen((char *)username), bufsize - hlen))) {RETURN(21);}
hlen = (int)(sb - buf);
hlen += sprintf((char*)buf + hlen, "\r\n");
}
hlen += sprintf((char*)buf + hlen, "\r\n");

View File

@ -271,7 +271,7 @@ extern int demon;
unsigned char * mycrypt(const unsigned char *key, const unsigned char *salt, unsigned char *buf);
unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPassword, int tohex);
int de64 (const unsigned char *in, unsigned char *out, int maxlen);
unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen);
unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen, int outsize);
void tohex(unsigned char *in, unsigned char *out, int len);
void fromhex(unsigned char *in, unsigned char *out, int len);

View File

@ -70,7 +70,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
if(user){
len += sprintf((char *)buf + len, "Proxy-Authorization: Basic ");
sprintf((char *)username, "%.128s:%.128s", user, pass?pass:(unsigned char *)"");
en64(username, buf+len, (int)strlen((char *)username));
if(!en64(username, buf+len, (int)strlen((char *)username), 2048 - len)) return 21;
len = (int)strlen((char *)buf);
len += sprintf((char *)buf + len, "\r\n");
}

View File

@ -237,14 +237,14 @@ void * smtppchild(struct clientparam* param) {
param->nwrites++;
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(680);}
en64(param->extusername, buf, (int)strlen((char *)param->extusername));
if(!en64(param->extusername, buf, (int)strlen((char *)param->extusername), (int)sizeof(buf))) {RETURN(683);}
socksend(param, param->remsock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S]);
param->statscli64+=(i+2);
param->nwrites+=2;
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(681);}
en64(param->extpassword, buf, (int)strlen((char *)param->extpassword));
if(!en64(param->extpassword, buf, (int)strlen((char *)param->extpassword), (int)sizeof(buf))) {RETURN(683);}
socksend(param, param->remsock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S]);
param->statscli64+=(i+2);
@ -259,12 +259,12 @@ void * smtppchild(struct clientparam* param) {
*username = 0;
i = (int)strlen((char *)param->extusername) + 1;
res = (int)strlen((char *)param->extpassword);
if(i + 1 + res >= (int)sizeof(username) || ((i + 1 + res + 2) / 3) * 4 + 1 > (int)sizeof(buf)) {RETURN(683);}
if(i + 1 + res >= (int)sizeof(username)) {RETURN(683);}
memcpy(username+1, param->extusername, i);
i++;
memcpy(username + i, param->extpassword, res);
i+=res;
en64(username, buf, i);
if(!en64(username, buf, i, (int)sizeof(buf))) {RETURN(683);}
i = (int)strlen((char *)buf);
socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S]);
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S]);

View File

@ -832,7 +832,7 @@ struct pluginlink {
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
int (*alwaysauth)(struct clientparam * param);
int (*checkACL)(struct clientparam * param);
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen);
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen, int outsize);
int (*de64)(const unsigned char *in, unsigned char *out, int maxlen);
void (*tohex)(unsigned char *in, unsigned char *out, int len);
void (*fromhex)(unsigned char *in, unsigned char *out, int len);