mirror of
https://github.com/3proxy/3proxy.git
synced 2026-07-23 12:10:11 +08:00
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
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:
parent
afb2ec0696
commit
d60ac723a5
26
src/auth.c
26
src/auth.c
@ -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:
|
||||||
|
|||||||
32
src/pcre.c
32
src/pcre.c
@ -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;
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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; }
|
||||||
|
|
||||||
|
|||||||
25
src/proxy.c
25
src/proxy.c
@ -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) {
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user