diff --git a/src/dnspr.c b/src/dnspr.c index 06f596d..10fc8ed 100644 --- a/src/dnspr.c +++ b/src/dnspr.c @@ -122,8 +122,8 @@ void * dnsprchild(struct clientparam* param) { len+=(type==1?16:28); } else if(type == 0x0c) { - unsigned a, b, c, d; - sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d); + unsigned a = 0, b = 0, c = 0, d = 0; + if(sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) a = b = c = d = 0; ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a); if(*SAFAMILY(¶m->sincl) == AF_INET && ip == *(uint32_t *)SAADDR(¶m->sincl)){ buf[2] = 0x85; diff --git a/src/imapp.c b/src/imapp.c index 6d46124..de6402e 100644 --- a/src/imapp.c +++ b/src/imapp.c @@ -157,7 +157,7 @@ void * imappchild(struct clientparam* param) { i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]); if( i < 4 ) {RETURN(695);} srvbuf[i] = 0; - if(strncasecmp((char *)srvbuf, "* OK", 4)||strstr((char *)srvbuf, "IMAP4rev1 Proxy Ready")){RETURN(696);} + if(strncasecmp((char *)srvbuf, "* OK", 4)){RETURN(696);} if((se = (unsigned char *)strstr((char *)srvbuf, "[CAPABILITY "))){ if(hascap(se, "AUTH=PLAIN")) caps |= CAP_PLAIN; if(hascap(se, "AUTH=LOGIN")) caps |= CAP_LOGIN; diff --git a/src/proxy.c b/src/proxy.c index 5779a09..e0b269a 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -956,7 +956,13 @@ for(;;){ } smallbuf[i] = 0; contentlength64 = 0; - sscanf((char *)smallbuf, "%"SCNx64"", &contentlength64); + if(sscanf((char *)smallbuf, "%"SCNx64"", &contentlength64) != 1) RETURN(537); + /* chunk-size line may be longer than smallbuf: drain and relay the + remainder up to LF so client/backend framing stays in sync */ + while(i > 0 && smallbuf[i-1] != '\n'){ + if((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', conf.timeouts[STRING_S])) <= 0) RETURN(537); + if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536); + } if(contentlength64 == 0) chunkedcli = 2; else { param->waitclient64 = contentlength64; @@ -1144,7 +1150,16 @@ for(;;){ } smallbuf[i] = 0; contentlength64 = 0; - sscanf((char *)smallbuf, "%"SCNx64"", &contentlength64); + if(sscanf((char *)smallbuf, "%"SCNx64"", &contentlength64) != 1) { + keepalive = 0; + break; + } + /* chunk-size line may be longer than smallbuf: drain and relay the + remainder up to LF so client/backend framing stays in sync */ + while(i > 0 && smallbuf[i-1] != '\n'){ + if((i = sockgetlinebuf(param, SERVER, smallbuf, 30, '\n', conf.timeouts[STRING_S])) <= 0) RETURN(534); + if (socksend(param, param->clisock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(535); + } if(contentlength64 == 0) { param->chunked = 2; } diff --git a/src/tlspr.c b/src/tlspr.c index 3047dbb..561d1dc 100644 --- a/src/tlspr.c +++ b/src/tlspr.c @@ -243,7 +243,7 @@ int parsehello(int type, unsigned char *hello, unsigned len, char *sni, int * sn unsigned xlen; xlen = size16(hello+offset+2); if(xlen+4 > elen) return -10; - if(type == 1 && hello[offset] == 0 && hello[offset+1] == 0){ + if(type == 1 && xlen >= 5 && hello[offset] == 0 && hello[offset+1] == 0){ snllen=size16(hello+offset+4); if(snllen>3){ if(snllen+2 != xlen) return -12; @@ -265,7 +265,7 @@ int parsehello(int type, unsigned char *hello, unsigned len, char *sni, int * sn *lv = hello[offset+5]; } } - else if(hello[offset] == 0 && hello[offset+1] == 16){ + else if(xlen >= 3 && hello[offset] == 0 && hello[offset+1] == 16){ alpnlen=hello[offset+6]; if(alpnlen+7>elen) return -16; if(alpnlen+1>PROTOLEN) return -17;