Multiple fixes, including security-related ones (in smtpp and LDAP plugin)
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Waiting to run

This commit is contained in:
Vladimir Dubrovin 2026-07-20 19:52:10 +03:00
parent afb2ec0696
commit d60ac723a5
7 changed files with 150 additions and 25 deletions

View File

@ -216,6 +216,24 @@ int dnsauth(struct clientparam * param){
return param->username? 0:3; return param->username? 0:3;
} }
static int ctmemcmp(const void *a, const void *b, size_t len){
const unsigned char *pa = (const unsigned char *)a, *pb = (const unsigned char *)b;
unsigned char diff = 0;
size_t i;
for(i = 0; i < len; i++) diff |= (unsigned char)(pa[i] ^ pb[i]);
return diff;
}
static int ctstrcmp(const char *a, const char *b, size_t maxlen){
unsigned char diff = 0;
size_t i;
for(i = 0; i < maxlen; i++){
diff |= (unsigned char)((unsigned char)a[i] ^ (unsigned char)b[i]);
if(!a[i] && !b[i]) break;
}
return diff;
}
int strongauth(struct clientparam * param){ int strongauth(struct clientparam * param){
static char dummy; static char dummy;
unsigned char buf[256]; unsigned char buf[256];
@ -229,7 +247,7 @@ int strongauth(struct clientparam * param){
int pwlen = strlen((char *)param->password); int pwlen = strlen((char *)param->password);
if(pwlen > 255) pwlen = 255; if(pwlen > 255) pwlen = 255;
if((unsigned)pwlen < pwl_table.recsize) { if((unsigned)pwlen < pwl_table.recsize) {
if(!strncmp(pass + 1, (char *)param->password, pwl_table.recsize - 1)) return 0; if(strlen(pass + 1) == strlen((char *)param->password) && !ctmemcmp(pass + 1, param->password, pwl_table.recsize - 1)) return 0;
} else { } else {
mdh_ctx *bctx; mdh_ctx *bctx;
unsigned hashsz; unsigned hashsz;
@ -242,18 +260,18 @@ int strongauth(struct clientparam * param){
blen = hashsz; blen = hashsz;
mdh_final(bctx, buf, &blen); mdh_final(bctx, buf, &blen);
mdh_free(bctx); mdh_free(bctx);
if(!memcmp(pass + 1, buf, pwl_table.recsize - 1)) return 0; if(!ctmemcmp(pass + 1, buf, pwl_table.recsize - 1)) return 0;
} }
return 6; return 6;
} }
case CR: case CR:
if (mycrypt(param->password, (unsigned char *)pass + 1, buf) && if (mycrypt(param->password, (unsigned char *)pass + 1, buf) &&
!strcmp(pass + 1, (char *)buf)) !ctstrcmp(pass + 1, (char *)buf, sizeof(pass) - 1))
return 0; return 0;
else return 7; else return 7;
#ifdef WITH_SSL #ifdef WITH_SSL
case NT: case NT:
if(ntpwdhash(buf, param->password, 1) && !strcmp(pass + 1, (char *)buf)) return 0; if(ntpwdhash(buf, param->password, 1) && !ctstrcmp(pass + 1, (char *)buf, sizeof(pass) - 1)) return 0;
else return 8; else return 8;
#endif #endif
default: default:

View File

@ -214,6 +214,7 @@ struct pcre_filter_data {
int users; int users;
pcre2_code * re; pcre2_code * re;
pcre2_match_data * match_data; pcre2_match_data * match_data;
pcre2_match_context * match_context;
int action; int action;
char * replace; char * replace;
struct ace *acl; struct ace *acl;
@ -223,6 +224,7 @@ static void pcre_data_free(struct pcre_filter_data *pcrefd){
_3proxy_mutex_lock(&pcre_mutex); _3proxy_mutex_lock(&pcre_mutex);
pcrefd->users--; pcrefd->users--;
if(!pcrefd->users){ if(!pcrefd->users){
if(pcrefd->match_context) pcre2_match_context_free(pcrefd->match_context);
if(pcrefd->match_data) pcre2_match_data_free(pcrefd->match_data); if(pcrefd->match_data) pcre2_match_data_free(pcrefd->match_data);
if(pcrefd->re) pcre2_code_free(pcrefd->re); if(pcrefd->re) pcre2_code_free(pcrefd->re);
if(pcrefd->acl) pl->freeacl(pcrefd->acl); if(pcrefd->acl) pl->freeacl(pcrefd->acl);
@ -283,10 +285,12 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
if(!match) return CONTINUE; if(!match) return CONTINUE;
if(!pcrefd->re) return pcrefd->action; if(!pcrefd->re) return pcrefd->action;
for(; offset < *length_p; nreplaces++){ for(; offset < *length_p; nreplaces++){
int repsz;
count = pcre2_match(pcrefd->re, (PCRE2_SPTR)*buf_p, *length_p, offset, 0, pcrefd->match_data, NULL); count = pcre2_match(pcrefd->re, (PCRE2_SPTR)*buf_p, *length_p, offset, 0, pcrefd->match_data, pcrefd->match_context);
if(count <= 0) break; if(count <= 0) break;
ovector = pcre2_get_ovector_pointer(pcrefd->match_data); ovector = pcre2_get_ovector_pointer(pcrefd->match_data);
if(ovector[0] > (PCRE2_SIZE)*length_p || ovector[1] > (PCRE2_SIZE)*length_p || ovector[1] < ovector[0]) break;
if(!(replace = pcrefd->replace) || param->nooverwritefilter) return pcrefd->action; if(!(replace = pcrefd->replace) || param->nooverwritefilter) return pcrefd->action;
replen = *length_p - ovector[1]; replen = *length_p - ovector[1];
@ -300,6 +304,8 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
num = atoi(replace); num = atoi(replace);
while(isnumber(*replace)) replace++; while(isnumber(*replace)) replace++;
if(num > (count - 1)) continue; if(num > (count - 1)) continue;
if(ovector[(num<<1)] == PCRE2_UNSET) continue;
if(ovector[(num<<1) + 1] > (PCRE2_SIZE)*length_p || ovector[(num<<1)] > ovector[(num<<1) + 1]) continue;
replen += (ovector[(num<<1) + 1] - ovector[(num<<1)]); replen += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
} }
else { else {
@ -319,6 +325,8 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
replace ++; replace ++;
num = atoi(replace); num = atoi(replace);
if(num > (count - 1)) continue; if(num > (count - 1)) continue;
if(ovector[(num<<1)] == PCRE2_UNSET) continue;
if(ovector[(num<<1) + 1] > (PCRE2_SIZE)*length_p || ovector[(num<<1)] > ovector[(num<<1) + 1]) continue;
memcpy(target, *buf_p + ovector[(num<<1)], ovector[(num<<1) + 1] - ovector[(num<<1)]); memcpy(target, *buf_p + ovector[(num<<1)], ovector[(num<<1) + 1] - ovector[(num<<1)]);
target += (ovector[(num<<1) + 1] - ovector[(num<<1)]); target += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
while(isnumber(*replace)) replace++; while(isnumber(*replace)) replace++;
@ -327,6 +335,7 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
*target++ = *replace++; *target++ = *replace++;
} }
} }
repsz = (int)(target - tmpbuf);
memcpy(target, *buf_p + ovector[1], *length_p - ovector[1]); memcpy(target, *buf_p + ovector[1], *length_p - ovector[1]);
if((ovector[0] + replen + 1) > *bufsize_p){ if((ovector[0] + replen + 1) > *bufsize_p){
newbuf = pl->mallocfunc(ovector[0] + replen + 1); newbuf = pl->mallocfunc(ovector[0] + replen + 1);
@ -343,10 +352,11 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
pl->freefunc(tmpbuf); pl->freefunc(tmpbuf);
(*buf_p)[ovector[0] + replen] = 0; (*buf_p)[ovector[0] + replen] = 0;
*length_p = ovector[0] + replen; *length_p = ovector[0] + replen;
if(ovector[0] + replen <= offset){ offset = ovector[0] + repsz;
break; if(ovector[1] == ovector[0] && offset <= (int)ovector[0]){
/* zero-width match with empty replacement: force progress */
offset = ovector[1] + 1;
} }
offset = ovector[0] + (int)strlen(pcrefd->replace);
} }
return nreplaces? pcrefd->action : CONTINUE; return nreplaces? pcrefd->action : CONTINUE;
#undef pcrefd #undef pcrefd
@ -442,6 +452,13 @@ static int h_pcre(int argc, unsigned char **argv){
flt->acl = acl; flt->acl = acl;
flt->replace = replace; flt->replace = replace;
flt->users = 1; flt->users = 1;
if(re){
flt->match_context = pcre2_match_context_create(NULL);
if(flt->match_context){
pcre2_set_match_limit(flt->match_context, 1000000);
pcre2_set_depth_limit(flt->match_context, 10000);
}
}
newf->instance = "pcre"; newf->instance = "pcre";
newf->data = flt; newf->data = flt;
newf->filter_open = pcre_filter_open; newf->filter_open = pcre_filter_open;
@ -549,6 +566,13 @@ static int h_pcre_rewrite(int argc, unsigned char **argv){
flt->acl = acl; flt->acl = acl;
flt->replace = replace; flt->replace = replace;
flt->users = 1; flt->users = 1;
if(re){
flt->match_context = pcre2_match_context_create(NULL);
if(flt->match_context){
pcre2_set_match_limit(flt->match_context, 1000000);
pcre2_set_depth_limit(flt->match_context, 10000);
}
}
newf->instance = "pcre"; newf->instance = "pcre";
newf->data = flt; newf->data = flt;
newf->filter_open = pcre_filter_open; newf->filter_open = pcre_filter_open;

View File

@ -51,8 +51,56 @@ void lower (char *string)
} }
#endif #endif
/* RFC 4514 escaping for DN attribute values. Returns dst, NULL on overflow. */
static char * ldap_escape_dn(const char *src, char *dst, int dstlen)
{
int j = 0;
unsigned char c;
for (; *src; src++){
c = (unsigned char)*src;
if(c == ',' || c == '+' || c == '"' || c == '\\' || c == '<' || c == '>' || c == ';' || c == '=' || c < 0x20 || c == 0x7f){
if(j + 3 >= dstlen) return NULL;
sprintf(dst + j, "\\%02X", c);
j += 3;
}
else {
if(j + 1 >= dstlen) return NULL;
dst[j++] = (char)c;
}
}
dst[j] = 0;
return dst;
}
/* RFC 4515 escaping for search filter values. Returns dst, NULL on overflow. */
static char * ldap_escape_filter(const char *src, char *dst, int dstlen)
{
int j = 0;
unsigned char c;
for (; *src; src++){
c = (unsigned char)*src;
if(c == '*' || c == '(' || c == ')' || c == '\\' || c == 0 || c < 0x20 || c >= 0x7f){
if(j + 3 >= dstlen) return NULL;
sprintf(dst + j, "\\%02X", c);
j += 3;
}
else {
if(j + 1 >= dstlen) return NULL;
dst[j++] = (char)c;
}
}
dst[j] = 0;
return dst;
}
/* reject names unsafe for use in filesystem paths */
static int unsafe_filename(const char *name)
{
return (strchr(name, '/') || strchr(name, '\\') || strstr(name, "..") || !*name);
}
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
int savecounters(void) int savecounters(void *v)
{ {
struct trafcount *tc=mypluginlink->conf->trafcounter; struct trafcount *tc=mypluginlink->conf->trafcounter;
struct trafcount *tcd; struct trafcount *tcd;
@ -67,8 +115,8 @@ int savecounters(void)
tcd = tc; tcd = tc;
tc = tc->next; tc = tc->next;
f=NULL; f=NULL;
if(strcmp(tcd->comment,"ldapcounters")==0) { if(strcmp(tcd->comment,"ldapcounters")==0 && !unsafe_filename(tcd->ace->users->user)) {
tmpbuf=malloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(tcd->ace->users->user)); tmpbuf=malloc(strlen(ldap_dircount)+strlen(tcd->ace->users->user)+sizeof(".lc"));
sprintf(tmpbuf,pat_file,ldap_dircount,tcd->ace->users->user); sprintf(tmpbuf,pat_file,ldap_dircount,tcd->ace->users->user);
f=fopen(tmpbuf,"w+b"); f=fopen(tmpbuf,"w+b");
fseek(f,0,SEEK_SET); fseek(f,0,SEEK_SET);
@ -100,6 +148,7 @@ static int ldapfunc(struct clientparam *param)
LDAPMessage *res = NULL; LDAPMessage *res = NULL;
int rc = -1; int rc = -1;
char tmpbuf[1024]; char tmpbuf[1024];
char escuser[512];
/* test proxy user auth ------------------------*/ /* test proxy user auth ------------------------*/
if(!param->username || !param->password) return 4; if(!param->username || !param->password) return 4;
@ -126,7 +175,12 @@ static int ldapfunc(struct clientparam *param)
/* create user for test auth */ /* create user for test auth */
sprintf(tmpbuf,"%.200s=%.200s,%.200s",attrs[0],param->username,ldap_userenv); if(!ldap_escape_dn(param->username, escuser, sizeof(escuser)))
{
ldap_unbind_s(ld);
return 5;
}
snprintf(tmpbuf, sizeof(tmpbuf), "%.200s=%.510s,%.200s",attrs[0],escuser,ldap_userenv);
rc = ldap_bind_s( ld, tmpbuf, param->password, LDAP_AUTH_SIMPLE ); rc = ldap_bind_s( ld, tmpbuf, param->password, LDAP_AUTH_SIMPLE );
@ -162,7 +216,12 @@ static int ldapfunc(struct clientparam *param)
/* test enter user in filter ------------------------------ /* test enter user in filter ------------------------------
create filter for search*/ create filter for search*/
sprintf(tmpbuf,"(&(%.200s=%.200s)(%.200s=%.200s))",attrs[0],param->username, if(!ldap_escape_filter(param->username, escuser, sizeof(escuser)))
{
ldap_unbind_s(ld);
return 5;
}
snprintf(tmpbuf, sizeof(tmpbuf), "(&(%.200s=%.510s)(%.200s=%.200s))",attrs[0],escuser,
ldap_group_attr,ldap_access); ldap_group_attr,ldap_access);
@ -326,7 +385,7 @@ int h_trafgroup(int argc, unsigned char ** argv)
while (rc > 0) while (rc > 0)
{ {
vals=ldap_get_values(ld, msg, getattr); vals=ldap_get_values(ld, msg, getattr);
if (vals != NULL && vals[0] != NULL ) if (vals != NULL && vals[0] != NULL && !unsafe_filename(vals[0]) )
{ {
/* -------------bandlim---------- /* -------------bandlim----------
@ -378,7 +437,7 @@ int h_trafgroup(int argc, unsigned char ** argv)
newtrafcount->traflim64 = traflimit; newtrafcount->traflim64 = traflimit;
newtrafcount->comment=(*mypluginlink->strdupfunc)("ldapcounters"); newtrafcount->comment=(*mypluginlink->strdupfunc)("ldapcounters");
newtrafcount->number=0; newtrafcount->number=0;
tmpbuf=malloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(vals[0])); tmpbuf=malloc(strlen(ldap_dircount)+strlen(vals[0])+sizeof(".lc"));
sprintf(tmpbuf,pat_file,ldap_dircount,vals[0]); sprintf(tmpbuf,pat_file,ldap_dircount,vals[0]);
f=NULL; f=NULL;
f=fopen(tmpbuf,"rb"); f=fopen(tmpbuf,"rb");

View File

@ -49,9 +49,13 @@ char **load_string(FILE *f,int max_count_str, int *countloadstr,
/*load from file new strings */ /*load from file new strings */
i=0; i=0;
while ( !feof(f) || i< max_count_str) while ( !feof(f) && i < max_count_str)
{ {
if(!fgets(tmpbuf1, 1023,f)) return NULL; if(!fgets(tmpbuf1, 1023,f)){
if(pt) free(pt);
free(old_table);
return NULL;
}
if ((strstr(tmpbuf1,stop))!=NULL) { break; } if ((strstr(tmpbuf1,stop))!=NULL) { break; }

View File

@ -240,6 +240,7 @@ void * proxychild(struct clientparam* param) {
int keepalive = 0; int keepalive = 0;
uint64_t contentlength64 = 0; uint64_t contentlength64 = 0;
int hascontent =0; int hascontent =0;
int clhdrofs = -1;
int isconnect = 0; int isconnect = 0;
int redirect = 0; int redirect = 0;
int prefix = 0, ckeepalive=0; int prefix = 0, ckeepalive=0;
@ -413,6 +414,10 @@ for(;;){
param->password = (unsigned char *)strdup((char *)sb+1); param->password = (unsigned char *)strdup((char *)sb+1);
param->pwtype = 0; param->pwtype = 0;
} }
else if(param->password){
free(param->password);
param->password = NULL;
}
if(param->username)free(param->username); if(param->username)free(param->username);
param->username = (unsigned char *)strdup((char *)username); param->username = (unsigned char *)strdup((char *)username);
continue; continue;
@ -458,13 +463,14 @@ for(;;){
if(parsehostname((char *)sb, param, 80)) RETURN(100); if(parsehostname((char *)sb, param, 80)) RETURN(100);
} }
newbuf = malloc(strlen((char *)req) + strlen((char *)(buf+inbuf)) + 8); newbuf = malloc(strlen((char *)req) + strlen((char *)(buf+inbuf)) + 8);
if(newbuf){
sp = (unsigned char *)strchr((char *)req+1, '/'); sp = (unsigned char *)strchr((char *)req+1, '/');
if(newbuf && sp){
memcpy(newbuf, req, (sp - req)); memcpy(newbuf, req, (sp - req));
sprintf((char*)newbuf + (sp - req), "http://%s%s",sb,sp); sprintf((char*)newbuf + (sp - req), "http://%s%s",sb,sp);
free(req); free(req);
req = newbuf; req = newbuf;
} }
else if(newbuf) free(newbuf);
if(se)*se = c; if(se)*se = c;
} }
if(ftp && i > 13 && (!strncasecmp((char *)(buf+inbuf), "authorization", 13))){ if(ftp && i > 13 && (!strncasecmp((char *)(buf+inbuf), "authorization", 13))){
@ -485,6 +491,10 @@ for(;;){
if(param->extpassword)free(param->extpassword); if(param->extpassword)free(param->extpassword);
param->extpassword = (unsigned char *)strdup((char *)sb+1); param->extpassword = (unsigned char *)strdup((char *)sb+1);
} }
else if(param->extpassword){
free(param->extpassword);
param->extpassword = NULL;
}
if(param->extusername)free(param->extusername); if(param->extusername)free(param->extusername);
param->extusername = (unsigned char *)strdup((char *)username); param->extusername = (unsigned char *)strdup((char *)username);
continue; continue;
@ -565,7 +575,7 @@ for(;;){
if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) { if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) {
param->nolongdatfilter = 1; param->nolongdatfilter = 1;
} }
else if(param->ndatfilterscli > 0 && contentlength64 > 0){ else if(param->ndatfilterscli > 0 && contentlength64 > 0 && contentlength64 == (uint64_t)(unsigned long)contentlength64){
uint64_t newlen64; uint64_t newlen64;
newlen64 = (uint64_t) sockfillbuffcli(param, (unsigned long)contentlength64, CONNECTION_S); newlen64 = (uint64_t) sockfillbuffcli(param, (unsigned long)contentlength64, CONNECTION_S);
if(newlen64 == contentlength64) { if(newlen64 == contentlength64) {
@ -921,6 +931,7 @@ for(;;){
authenticate = 0; authenticate = 0;
param->chunked = 0; param->chunked = 0;
hascontent = 0; hascontent = 0;
clhdrofs = -1;
while( (i = sockgetlinebuf(param, SERVER, buf + inbuf, LINESIZE - 1, '\n', conf.timeouts[(res)?STRING_S:STRING_L])) > 2) { while( (i = sockgetlinebuf(param, SERVER, buf + inbuf, LINESIZE - 1, '\n', conf.timeouts[(res)?STRING_S:STRING_L])) > 2) {
if(!res && i>9)param->status = res = atoi((char *)buf + inbuf + 9); if(!res && i>9)param->status = res = atoi((char *)buf + inbuf + 9);
@ -942,6 +953,7 @@ for(;;){
authenticate = 1; authenticate = 1;
} }
else if(i > 15 && (!strncasecmp((char *)(buf+inbuf), "content-length", 14))){ else if(i > 15 && (!strncasecmp((char *)(buf+inbuf), "content-length", 14))){
if(param->chunked) continue;
buf[inbuf+i]=0; buf[inbuf+i]=0;
sb = (unsigned char *)strchr((char *)(buf+inbuf), ':'); sb = (unsigned char *)strchr((char *)(buf+inbuf), ':');
if(!sb)continue; if(!sb)continue;
@ -949,6 +961,7 @@ for(;;){
while(isspace(*sb))sb++; while(isspace(*sb))sb++;
sscanf((char *)sb, "%"SCNu64"", &contentlength64); sscanf((char *)sb, "%"SCNu64"", &contentlength64);
hascontent = 1; hascontent = 1;
clhdrofs = inbuf;
if(param->unsafefilter && param->ndatfilterssrv > 0) { if(param->unsafefilter && param->ndatfilterssrv > 0) {
hascontent = 2; hascontent = 2;
continue; continue;
@ -965,6 +978,12 @@ for(;;){
while(isspace(*sb))sb++; while(isspace(*sb))sb++;
if(!strncasecmp((char *)sb, "chunked", 7)){ if(!strncasecmp((char *)sb, "chunked", 7)){
param->chunked = 1; param->chunked = 1;
if(clhdrofs >= 0){
buf[clhdrofs] = 'X';
clhdrofs = -1;
contentlength64 = 0;
hascontent = 0;
}
} }
} }
inbuf += i; inbuf += i;
@ -1009,7 +1028,7 @@ for(;;){
if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) { if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) {
param->nolongdatfilter = 1; param->nolongdatfilter = 1;
} }
else if(param->ndatfilterssrv > 0 && contentlength64 > 0 && param->operation != HTTP_HEAD && res != 204 && res != 304){ else if(param->ndatfilterssrv > 0 && contentlength64 > 0 && contentlength64 == (uint64_t)(unsigned long)contentlength64 && param->operation != HTTP_HEAD && res != 204 && res != 304){
uint64_t newlen; uint64_t newlen;
newlen = (uint64_t)sockfillbuffsrv(param, (unsigned long) contentlength64, CONNECTION_S); newlen = (uint64_t)sockfillbuffsrv(param, (unsigned long) contentlength64, CONNECTION_S);
if(newlen == contentlength64) { if(newlen == contentlength64) {

View File

@ -233,9 +233,10 @@ void * smtppchild(struct clientparam* param) {
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(682);} if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(682);}
*username = 0; *username = 0;
i = (int)strlen((char *)param->extusername) + 1; 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);}
memcpy(username+1, param->extusername, i); memcpy(username+1, param->extusername, i);
i++; i++;
res = (int)strlen((char *)param->extpassword);
memcpy(username + i, param->extpassword, res); memcpy(username + i, param->extpassword, res);
i+=res; i+=res;
en64(username, buf, i); en64(username, buf, i);

View File

@ -69,7 +69,7 @@ int parsehello(int type, unsigned char *hello, unsigned len, char *sni, int * sn
elen = size16(hello+offset); elen = size16(hello+offset);
offset += 2; offset += 2;
if(elen+offset != len) return -9; if(elen+offset != len) return -9;
while(elen > 1){ while(elen > 3){
unsigned xlen; unsigned xlen;
xlen = size16(hello+offset+2); xlen = size16(hello+offset+2);
if(xlen+4 > elen) return -10; if(xlen+4 > elen) return -10;