C:/fscan/HTTPCore/Modules/Encoding_Deflate.cpp

Go to the documentation of this file.
00001 //#define _DBG_
00010 #ifdef _ZLIB_SUPPORT_
00011 
00012 #include "Encoding_Deflate.h"
00013 #include "../CallBack.h"
00014 #include "../IoFunctions.h"
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <assert.h>
00019 
00020 
00021  #ifdef __WIN32__RELEASE__
00022     #pragma comment(lib, "zdll.lib")
00023         #include "../../Includes/Zlib/include/zlib.h"
00024         #include "../../Includes/Zlib/include/zconf.h"
00025  #else
00026         #include <zlib.h>
00027         #include <zconf.h>
00028  #endif
00029 
00030 #define CHUNK 16384
00031 /******************************************************************************/
00033 
00037 /******************************************************************************/
00038 
00039 __inline static int get_byte(z_stream *strm)
00040 {
00041  if (strm->avail_in==0) {
00042      return EOF;
00043  }
00044   strm->avail_in--;
00045   return *(strm->next_in)++;
00046 }
00047 
00048 /******************************************************************************/
00050 
00059 /******************************************************************************/
00060 static char *gunzip(char *in, int inSize, int *total, int what)
00061 {
00062         int ret;
00063     unsigned have;
00064         z_stream strm;
00065         unsigned char out[CHUNK];
00066         //unsigned char *decoded=NULL;
00067         unsigned long lpBufferSize;
00068         PHTTPIOMapping HTTPIoMapping = NULL;//GetFileMapping(0,NULL);
00069 
00070 
00071 
00072         if ( (!inSize) || (!in) ) {
00073                 return(NULL);
00074         }
00075 
00076         /* allocate inflate state */
00077         strm.zalloc = Z_NULL;
00078         strm.zfree =  Z_NULL;
00079         strm.opaque = Z_NULL;
00080     strm.avail_in = strm.avail_out = 0;
00081         strm.next_in  = strm.next_out  = 0;
00082 
00083         strm.avail_in = inSize;
00084         strm.next_in=(Bytef*)in;
00085 
00086         if (what == GZIP_DATA )
00087         {
00088                 unsigned int len;
00089                 int c;
00090                 ret = inflateInit2(&strm,-MAX_WBITS);
00091                 if (ret != Z_OK) return(NULL);
00092 
00093                 memset(out,0,sizeof(out));
00094                 /* Peek ahead to check the gzip magic header */
00095                 if (strm.next_in[0] != 0x1f ||
00096                         strm.next_in[1] != 0x8b) {
00097                         #ifdef _DBG_
00098                                 printf("gunzip(): INVALID Magic gzip header\n");
00099                         #endif
00100                 inflateEnd(&strm);
00101                                 return (NULL);;
00102                 }
00103                 strm.avail_in -= 2;
00104                 strm.next_in += 2;
00105 
00106                 int method= get_byte(&strm);/* method byte */
00107                 int flags = get_byte(&strm);/* flags byte */
00108 
00109                 /* gzip flag byte */
00110                 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
00111                 #define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
00112                 #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
00113                 #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
00114                 #define COMMENT      0x10 /* bit 4 set: file comment present */
00115                 #define RESERVED     0xE0 /* bits 5..7: reserved */
00116 
00117                 if (method != Z_DEFLATED || (flags & RESERVED) != 0)
00118                 {
00119                 #ifdef _DBG_
00120                         printf("gunzip(): Method or flags error: %i - %i\n",method,flags);
00121                 #endif
00122                 inflateEnd(&strm);
00123                         return NULL;
00124                 }
00125                 /* Discard time, xflags and OS code: */
00126                 strm.avail_in-=6;
00127                 strm.next_in+=6;
00128 
00129                 if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
00130                         len  =  (uInt)get_byte(&strm);
00131                         len += ((uInt)get_byte(&strm))<<8;
00132                         /* len is garbage if EOF but the loop below will quit anyway */
00133                         while (len-- != 0 && get_byte(&strm) != EOF) ;
00134                 }
00135 
00136                 if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
00137                         while ((c = get_byte(&strm)) != 0 && c != EOF) ;
00138                 }
00139                 if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
00140                         while ((c = get_byte(&strm)) != 0 && c != EOF) ;
00141                 }
00142                 if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
00143                         for (len = 0; len < 2; len++) (void)get_byte(&strm);
00144                 }
00145    }  else if (what == DEFLATE_DATA )
00146    {
00147                 ret = inflateInit(&strm);
00148                 if (ret != Z_OK) return(NULL);
00149     }   else return (NULL);
00150 
00151         *total=0;
00152 
00153         /* run inflate() on input until output buffer not full */
00154         do {
00155             strm.avail_out = sizeof(out);
00156             strm.next_out = out;
00157             ret = inflate(&strm, Z_NO_FLUSH);
00158             assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
00159             switch (ret) {
00160             case Z_NEED_DICT:
00161                 ret = Z_DATA_ERROR;     /* and fall through */
00162             case Z_DATA_ERROR:
00163                         case Z_MEM_ERROR:
00164                                 (void)inflateEnd(&strm);/*
00165                                 if (decoded) {
00166                                         free(decoded);
00167                                 }*/
00168                                 if (HTTPIoMapping)
00169                                 {
00170 #ifdef __WIN32__RELEASE__
00171                                         CloseHandle(HTTPIoMapping->hTmpFilename);
00172                                         DeleteFile(HTTPIoMapping->BufferedFileName);
00173 #else
00174                                         close(HTTPIoMapping->hTmpFilename);
00175                                         rmdir(HTTPIoMapping->BufferedFileName);
00176 #endif
00177                                         HTTPIoMapping->assigned=0;
00178                                 }
00179                                 return(NULL);
00180                         }
00181                         have = CHUNK - strm.avail_out;
00182                         if (have>0) {
00183                                 /*
00184                                 decoded=(unsigned char*)realloc(decoded, *total+ have +1);
00185                                 memcpy(decoded+ *total,out,have);
00186                                 */
00187 
00188                                 if (!HTTPIoMapping){
00189                                         HTTPIoMapping = GetFileMapping(0,NULL);
00190                                         if (!HTTPIoMapping) return(NULL);
00191                                 }
00192                                 if (HTTPIoMapping) {
00193 #ifdef __WIN32__RELEASE__
00194                                         WriteFile(HTTPIoMapping->hTmpFilename,out,have,&lpBufferSize,NULL);
00195 #else
00196                                         //fwrite(out,have,1,HTTPIoMapping->hTmpFilename);
00197                                         write(HTTPIoMapping->hTmpFilename,out,have);
00198 #endif
00199                                         HTTPIoMapping->MemoryLenght+=have;
00200                                 }
00201 
00202                                 //HTTPIoMapping->
00203                                 *total+=have;
00204                                 //decoded[*total]='\0';
00205                                 //DeleteFileMapping
00206                         }
00207         } while (strm.avail_out == 0);
00208 
00209         (void)inflateEnd(&strm);
00210 #ifdef __WIN32__RELEASE__
00211         WriteFile(HTTPIoMapping->hTmpFilename,"\x00",1,&lpBufferSize,NULL);
00212         HTTPIoMapping->hMapping = CreateFileMapping (HTTPIoMapping->hTmpFilename,
00213                            NULL,
00214                            PAGE_READWRITE,
00215                            0,
00216                            HTTPIoMapping->MemoryLenght+1,
00217                            NULL);
00218         HTTPIoMapping->BufferedPtr = (char*) MapViewOfFile (HTTPIoMapping->hMapping , FILE_MAP_ALL_ACCESS, 0,0,0);
00219         //printf("ptr: %x\n",HTTPIoMapping->BufferedPtr);
00220 #else
00221         write(HTTPIoMapping->hTmpFilename,"\x00",1);
00222         HTTPIoMapping->BufferedPtr = (char*) mmap (0, *total +1, PROT_READ | PROT_WRITE, MAP_SHARED, HTTPIoMapping->hTmpFilename, 0);
00223 #endif
00224         return(HTTPIoMapping->BufferedPtr);
00225         //return ( decoded);
00226 
00227 }
00228 /******************************************************************************/
00230 
00238 /******************************************************************************/
00239 int CBDeflate(int cbType,HTTPHANDLE HTTPHandle,PHTTP_DATA *prequest,PHTTP_DATA *presponse)
00240 {
00241 
00242 PHTTP_DATA response = *presponse;
00243 PHTTP_DATA request =  *prequest;
00244 
00245 
00246 //Accept-Encoding: gzip, deflate\r\n
00247         if (cbType == CBTYPE_CLIENT_REQUEST)
00248         {
00249                 if (request)
00250                 {
00251                         AddHeader(request,"Accept-Encoding: gzip, deflate\r\n");
00252                 }
00253                 return (CBRET_STATUS_NEXT_CB_CONTINUE);
00254         } else  if (cbType == CBTYPE_CLIENT_RESPONSE)
00255         {
00256                 int total= 0;
00257                 int type = NORMAL_DATA;
00258                 //char *opt= NULL;
00259                 if ( (!response) || (!response->HeaderSize) || (!response->Header) )  {
00260                    return (CBRET_STATUS_NEXT_CB_CONTINUE);
00261                 }
00262 
00263                 char *encoding=GetHeaderValue(response->Header,"Content-Encoding: ",0);
00264                 if (!encoding)
00265                         return(CBRET_STATUS_NEXT_CB_CONTINUE);
00266 
00267                 char *p = strstr(encoding,"deflate");
00268                 if (p)
00269                         type= DEFLATE_DATA;
00270                 else {
00271                    p = strstr(encoding,"gzip");
00272                    if (p)  type= GZIP_DATA;
00273 
00274                 }
00275 
00276                 if (type != NORMAL_DATA)
00277                 {
00278                         char *decoded = (char *) gunzip(response->Data, response->DataSize, &total, type);
00279                         if (decoded) {
00280                         #ifdef _DBG_
00281                                 printf("CBDeflate(): uncompressed %i bytes to %i. Data: %s\n",response->DataSize,total,p);
00282                         #endif
00283                                 printf("Liberando memoria..\n");
00284                                 response->Data = DeleteFileMapping(response->Data);
00285                                 if (response->Data)
00286                                 {
00287                                         printf("[Encoding_Deflate CB: Unable to delete mapping against response->Data. Memory leak here\n");
00288                                         free(response->Data);
00289 
00290                                 }
00291                                 response->Data=decoded;
00292                                 response->DataSize=total;
00293                                 RemoveHeader(response,"Content-Encoding:");
00294                                 RemoveHeader(response,"Content-Length:");
00295                                 char tmp[256];
00296                                 sprintf(tmp,"Content-Length: %i\r\n",total);
00297                                 AddHeader(response,tmp);
00298                         } else {
00299                         #ifdef _DBG_
00300                                 printf("CBDeflate(): Error decoding buffer with %s\n",p);
00301                         #endif
00302                         }
00303                 }
00304                 free(encoding);
00305         }
00306         return (CBRET_STATUS_NEXT_CB_CONTINUE);
00307 
00308 }
00309 #endif
00310 

Generated on Sun Jan 18 00:32:04 2009 for Fast HTTP Vulnerability Scanner by  doxygen 1.5.4