LCOV - code coverage report
Current view: top level - src - fzp.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 154 215 71.6 %
Date: 2018-09-29 15:42:53 Functions: 26 27 96.3 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "cmd.h"
       4             : #include "fsops.h"
       5             : #include "fzp.h"
       6             : #include "log.h"
       7             : #include "prepend.h"
       8             : #ifndef HAVE_WIN32
       9             : #include "server/compress.h"
      10             : #include "server/protocol1/zlibio.h"
      11             : #endif
      12             : 
      13             : static struct fzp *fzp_alloc(void)
      14             : {
      15        4377 :         return (struct fzp *)calloc_w(1, sizeof(struct fzp), __func__);
      16             : }
      17             : 
      18        4377 : static void fzp_free(struct fzp **fzp)
      19             : {
      20        4377 :         if(!fzp || !*fzp) return;
      21        4377 :         free_w(&(*fzp)->buf);
      22        4377 :         free_v((void **)fzp);
      23             : }
      24             : 
      25        3086 : static FILE *open_fp(const char *fname, const char *mode)
      26             : {
      27        3086 :         FILE *fp=NULL;
      28        3086 :         if(!(fp=fopen(fname, mode)))
      29          52 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      30        3086 :         return fp;
      31             : }
      32             : 
      33        1250 : static gzFile open_zp(const char *fname, const char *mode)
      34             : {
      35        1250 :         gzFile zp=NULL;
      36             : 
      37        1250 :         if(!(zp=gzopen(fname, mode)))
      38           3 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      39        1250 :         return zp;
      40             : }
      41             : 
      42        3127 : static int close_fp(FILE **fp)
      43             : {
      44        3127 :         int ret=0;
      45        3127 :         if(!*fp) return ret;
      46        3075 :         if(fclose(*fp))
      47             :         {
      48           0 :                 logp("fclose failed: %s\n", strerror(errno));
      49           0 :                 ret=-1;
      50             :         }
      51        3075 :         *fp=NULL;
      52        3075 :         return ret;
      53             : }
      54             : 
      55        1250 : static int close_zp(gzFile *zp)
      56             : {
      57             :         int e;
      58        1250 :         int ret=0;
      59        1250 :         if(!*zp) return ret;
      60        1247 :         if((e=gzclose(*zp))
      61             :         // Can return Z_BUF_ERROR if the last read ended in the middle
      62             :         // of a gzip stream. I saw this happening in utests on OpenBSD.
      63           0 :           && e!=Z_BUF_ERROR)
      64             :         {
      65           0 :                 const char *str=NULL;
      66           0 :                 if(e==Z_ERRNO)
      67           0 :                         str=strerror(errno);
      68           0 :                 logp("gzclose failed: %d (%s)\n", e, str?:"");
      69           0 :                 ret=-1;
      70             :         }
      71             :         return ret;
      72             : }
      73             : 
      74             : static void unknown_type(enum fzp_type type, const char *func)
      75             : {
      76           0 :         logp("unknown type in %s: %d\n", func, type);
      77             : }
      78             : 
      79             : static void not_open(const char *func)
      80             : {
      81          11 :         logp("File pointer not open in %s\n", func);
      82             : }
      83             : 
      84        4336 : static struct fzp *fzp_do_open(const char *path, const char *mode,
      85             :         enum fzp_type type)
      86             : {
      87        4336 :         struct fzp *fzp=NULL;
      88             : 
      89        4336 :         if(!(fzp=fzp_alloc())) goto error;
      90        4336 :         fzp->type=type;
      91        4336 :         switch(type)
      92             :         {
      93             :                 case FZP_FILE:
      94        3086 :                         if(!(fzp->fp=open_fp(path, mode)))
      95             :                                 goto error;
      96        3034 :                         return fzp;
      97             :                 case FZP_COMPRESSED:
      98        1250 :                         if(!(fzp->zp=open_zp(path, mode)))
      99             :                                 goto error;
     100        1247 :                         return fzp;
     101             :                 default:
     102           0 :                         unknown_type(fzp->type, __func__);
     103             :                         goto error;
     104             :         }
     105             : error:
     106          55 :         fzp_close(&fzp);
     107          55 :         return NULL;
     108             : }
     109             : 
     110        3086 : struct fzp *fzp_open(const char *path, const char *mode)
     111             : {
     112        3086 :         return fzp_do_open(path, mode, FZP_FILE);
     113             : }
     114             : 
     115        1250 : struct fzp *fzp_gzopen(const char *path, const char *mode)
     116             : {
     117        1250 :         return fzp_do_open(path, mode, FZP_COMPRESSED);
     118             : }
     119             : 
     120      124323 : int fzp_close(struct fzp **fzp)
     121             : {
     122      124323 :         int ret=-1;
     123      124323 :         if(!fzp || !*fzp) return 0;
     124        4377 :         switch((*fzp)->type)
     125             :         {
     126             :                 case FZP_FILE:
     127        3127 :                         ret=close_fp(&((*fzp)->fp));
     128        3127 :                         break;
     129             :                 case FZP_COMPRESSED:
     130        1250 :                         ret=close_zp(&((*fzp)->zp));
     131        1250 :                         break;
     132             :                 default:
     133           0 :                         unknown_type((*fzp)->type, __func__);
     134             :                         break;
     135             :         }
     136        4377 :         fzp_free(fzp);
     137        4377 :         return ret;
     138             : }
     139             : 
     140      740034 : int fzp_read(struct fzp *fzp, void *ptr, size_t nmemb)
     141             : {
     142      740034 :         if(fzp) switch(fzp->type)
     143             :         {
     144             :                 case FZP_FILE:
     145      459719 :                         return (int)fread(ptr, 1, nmemb, fzp->fp);
     146             :                 case FZP_COMPRESSED:
     147      280314 :                         return gzread(fzp->zp, ptr, (unsigned)nmemb);
     148             :                 default:
     149           0 :                         unknown_type(fzp->type, __func__);
     150             :                         goto error;
     151             :         }
     152             :         not_open(__func__);
     153             : error:
     154             :         return 0;
     155             : }
     156             : 
     157      479067 : size_t fzp_write(struct fzp *fzp, const void *ptr, size_t nmemb)
     158             : {
     159      479067 :         if(fzp) switch(fzp->type)
     160             :         {
     161             :                 case FZP_FILE:
     162      302624 :                         return fwrite(ptr, 1, nmemb, fzp->fp);
     163             :                 case FZP_COMPRESSED:
     164      176442 :                         return gzwrite(fzp->zp, ptr, (unsigned)nmemb);
     165             :                 default:
     166           0 :                         unknown_type(fzp->type, __func__);
     167             :                         goto error;
     168             :         }
     169             :         not_open(__func__);
     170             : error:
     171             :         return 0;
     172             : }
     173             : 
     174         649 : int fzp_eof(struct fzp *fzp)
     175             : {
     176         649 :         if(fzp) switch(fzp->type)
     177             :         {
     178             :                 case FZP_FILE:
     179         294 :                         return feof(fzp->fp);
     180             :                 case FZP_COMPRESSED:
     181         354 :                         return gzeof(fzp->zp);
     182             :                 default:
     183           0 :                         unknown_type(fzp->type, __func__);
     184             :                         goto error;
     185             :         }
     186             :         not_open(__func__);
     187             : error:
     188             :         // Non-zero means end of file. Should be OK to use -1 here.
     189             :         return -1;
     190             : }
     191             : 
     192          22 : int fzp_flush(struct fzp *fzp)
     193             : {
     194          22 :         if(fzp) switch(fzp->type)
     195             :         {
     196             :                 case FZP_FILE:
     197          15 :                         return fflush(fzp->fp);
     198             :                 case FZP_COMPRESSED:
     199           6 :                         return gzflush(fzp->zp, Z_FINISH);
     200             :                 default:
     201           0 :                         unknown_type(fzp->type, __func__);
     202             :                         goto error;
     203             :         }
     204             :         not_open(__func__);
     205             : error:
     206             :         return EOF;
     207             : }
     208             : 
     209         267 : int fzp_seek(struct fzp *fzp, off_t offset, int whence)
     210             : {
     211         267 :         if(fzp) switch(fzp->type)
     212             :         {
     213             :                 case FZP_FILE:
     214          15 :                         return fseeko(fzp->fp, offset, whence);
     215             :                 case FZP_COMPRESSED:
     216             :                         // Notice that gzseek returns the new offset.
     217         251 :                         if(gzseek(fzp->zp, offset, whence)==offset)
     218             :                                 return 0;
     219             :                         goto error;
     220             :                 default:
     221           0 :                         unknown_type(fzp->type, __func__);
     222             :                         goto error;
     223             :         }
     224             :         not_open(__func__);
     225             : error:
     226             :         return -1;
     227             : }
     228             : 
     229       13001 : off_t fzp_tell(struct fzp *fzp)
     230             : {
     231       13001 :         if(fzp) switch(fzp->type)
     232             :         {
     233             :                 case FZP_FILE:
     234       12895 :                         return ftello(fzp->fp);
     235             :                 case FZP_COMPRESSED:
     236         105 :                         return gztell(fzp->zp);
     237             :                 default:
     238           0 :                         unknown_type(fzp->type, __func__);
     239             :                         goto error;
     240             :         }
     241             :         not_open(__func__);
     242             : error:
     243             :         return -1;
     244             : }
     245             : 
     246             : #ifndef HAVE_WIN32
     247             : // There is no zlib gztruncate. Inflate it, truncate it, recompress it.
     248           4 : static int gztruncate(const char *path, off_t length, int compression)
     249             : {
     250           4 :         int ret=1;
     251             :         char tmp[16];
     252           4 :         char *dest=NULL;
     253           4 :         char *dest2=NULL;
     254           4 :         snprintf(tmp, sizeof(tmp), ".%d", getpid());
     255           4 :         if(!(dest=prepend(path, tmp))
     256           4 :           || !(dest2=prepend(dest, "-2"))
     257           4 :           || zlib_inflate(NULL, path, dest, NULL))
     258             :                 goto end;
     259           4 :         if(truncate(dest, length))
     260             :         {
     261           0 :                 logp("truncate of %s failed in %s\n", dest, __func__);
     262           0 :                 goto end;
     263             :         }
     264           4 :         if(compress_file(dest, dest2, compression))
     265             :                 goto end;
     266           4 :         unlink(dest);
     267           4 :         ret=do_rename(dest2, path);
     268             : end:
     269           4 :         if(dest) unlink(dest);
     270           4 :         if(dest2) unlink(dest2);
     271           4 :         free_w(&dest);
     272           4 :         free_w(&dest2);
     273           4 :         return ret;
     274             : }
     275             : 
     276         209 : int fzp_truncate(const char *path, enum fzp_type type, off_t length,
     277             :         int compression)
     278             : {
     279         209 :         switch(type)
     280             :         {
     281             :                 case FZP_FILE:
     282         205 :                         return truncate(path, length);
     283             :                 case FZP_COMPRESSED:
     284           4 :                         return gztruncate(path, length, compression);
     285             :                 default:
     286           0 :                         unknown_type(type, __func__);
     287             :                         goto error;
     288             :         }
     289             : error:
     290           0 :         return -1;
     291             : }
     292             : #endif
     293             : 
     294      942695 : int fzp_printf(struct fzp *fzp, const char *format, ...)
     295             : {
     296      942695 :         int ret=-1;
     297             :         int n;
     298             : 
     299      942695 :         if(!fzp)
     300             :         {
     301           1 :                 not_open(__func__);
     302           1 :                 return ret;
     303             :         }
     304             : 
     305      942694 :         if(!fzp->buf)
     306             :         {
     307        1552 :                 fzp->s=128;
     308        1552 :                 if(!(fzp->buf=(char *)malloc_w(fzp->s, __func__)))
     309             :                         return ret;
     310             :         }
     311             : 
     312             :         // Avoid fixed size buffer.
     313             :         while(1)
     314             :         {
     315             :                 va_list ap;
     316      942694 :                 va_start(ap, format);
     317      942694 :                 n=vsnprintf(fzp->buf, fzp->s, format, ap);
     318      942694 :                 va_end(ap);
     319      942694 :                 if(n<0)
     320             :                 {
     321           0 :                         logp("Failed to vsnprintf in %s: %s\n",
     322           0 :                                 __func__, strerror(errno));
     323           0 :                         return ret;
     324             :                 }
     325      942694 :                 if(fzp->s<(size_t)n)
     326             :                 {
     327           0 :                         fzp->s*=2;
     328           0 :                         if(!(fzp->buf=(char *)
     329           0 :                                 realloc_w(fzp->buf, fzp->s, __func__)))
     330             :                                         return ret;
     331           0 :                         continue;
     332             :                 }
     333             : 
     334      942694 :                 break;
     335             :         }
     336             : 
     337      942694 :         switch(fzp->type)
     338             :         {
     339             :                 case FZP_FILE:
     340      589751 :                         ret=fprintf(fzp->fp, "%s", fzp->buf);
     341      589751 :                         break;
     342             :                 case FZP_COMPRESSED:
     343      352943 :                         ret=gzprintf(fzp->zp, "%s", fzp->buf);
     344      352943 :                         break;
     345             :                 default:
     346           0 :                         unknown_type(fzp->type, __func__);
     347             :                         break;
     348             :         }
     349             : 
     350             :         return ret;
     351             : }
     352             : 
     353          13 : void fzp_setlinebuf(struct fzp *fzp)
     354             : {
     355             : #ifndef HAVE_WIN32
     356          13 :         if(fzp) switch(fzp->type)
     357             :         {
     358             :                 case FZP_FILE:
     359          12 :                         setlinebuf(fzp->fp);
     360          12 :                         return;
     361             :                 case FZP_COMPRESSED:
     362           0 :                         logp("gzsetlinebuf() does not exist in %s\n", __func__);
     363           0 :                         return;
     364             :                 default:
     365           0 :                         unknown_type(fzp->type, __func__);
     366             :                         return;
     367             :         }
     368             :         not_open(__func__);
     369             : #endif
     370             : }
     371             : 
     372        1221 : char *fzp_gets(struct fzp *fzp, char *s, int size)
     373             : {
     374        1221 :         if(fzp) switch(fzp->type)
     375             :         {
     376             :                 case FZP_FILE:
     377        1220 :                         return fgets(s, size, fzp->fp);
     378             :                 case FZP_COMPRESSED:
     379           0 :                         return gzgets(fzp->zp, s, size);
     380             :                 default:
     381           0 :                         unknown_type(fzp->type, __func__);
     382             :                         goto error;
     383             :         }
     384             :         not_open(__func__);
     385             : error:
     386             :         return NULL;
     387             : }
     388             : 
     389          12 : extern int fzp_fileno(struct fzp *fzp)
     390             : {
     391          12 :         if(fzp) switch(fzp->type)
     392             :         {
     393             :                 case FZP_FILE:
     394          11 :                         return fileno(fzp->fp);
     395             :                 case FZP_COMPRESSED:
     396           0 :                         logp("gzfileno() does not exist in %s\n", __func__);
     397           0 :                         goto error;
     398             :                 default:
     399           0 :                         unknown_type(fzp->type, __func__);
     400             :                         goto error;
     401             :         }
     402             :         not_open(__func__);
     403             : error:
     404             :         return -1;
     405             : }
     406             : 
     407          41 : static struct fzp *fzp_do_dopen(int fd, const char *mode,
     408             :         enum fzp_type type)
     409             : {
     410          41 :         struct fzp *fzp=NULL;
     411             : 
     412          41 :         if(!(fzp=fzp_alloc())) goto error;
     413          41 :         fzp->type=type;
     414          41 :         switch(type)
     415             :         {
     416             :                 case FZP_FILE:
     417          41 :                         if(!(fzp->fp=fdopen(fd, mode)))
     418             :                                 goto error;
     419          41 :                         return fzp;
     420             :                 case FZP_COMPRESSED:
     421           0 :                         if(!(fzp->zp=gzdopen(fd, mode)))
     422             :                                 goto error;
     423           0 :                         return fzp;
     424             :                 default:
     425           0 :                         unknown_type(fzp->type, __func__);
     426             :                         goto error;
     427             :         }
     428             : error:
     429           0 :         fzp_close(&fzp);
     430           0 :         return NULL;
     431             : }
     432             : 
     433          41 : struct fzp *fzp_dopen(int fd, const char *mode)
     434             : {
     435          41 :         return fzp_do_dopen(fd, mode, FZP_FILE);
     436             : }
     437             : 
     438           0 : struct fzp *fzp_gzdopen(int fd, const char *mode)
     439             : {
     440           0 :         return fzp_do_dopen(fd, mode, FZP_COMPRESSED);
     441             : }
     442             : 
     443           1 : void fzp_ERR_print_errors_fp(struct fzp *fzp)
     444             : {
     445           1 :         if(fzp) switch(fzp->type)
     446             :         {
     447             :                 case FZP_FILE:
     448           0 :                         ERR_print_errors_fp(fzp->fp);
     449           0 :                         break;
     450             :                 case FZP_COMPRESSED:
     451           0 :                         logp("ERR_print_errors_zp() does not exist in %s\n",
     452             :                                 __func__);
     453           0 :                         break;
     454             :                 default:
     455           0 :                         unknown_type(fzp->type, __func__);
     456             :                         break;
     457             :         }
     458           1 : }
     459             : 
     460           1 : X509 *fzp_PEM_read_X509(struct fzp *fzp)
     461             : {
     462           1 :         if(fzp) switch(fzp->type)
     463             :         {
     464             :                 case FZP_FILE:
     465           0 :                         return PEM_read_X509(fzp->fp, NULL, NULL, NULL);
     466             :                 case FZP_COMPRESSED:
     467           0 :                         logp("PEM_read_X509() does not exist in %s\n",
     468             :                                 __func__);
     469           0 :                         goto error;
     470             :                 default:
     471           0 :                         unknown_type(fzp->type, __func__);
     472             :                         goto error;
     473             :         }
     474             :         not_open(__func__);
     475             : error:
     476             :         return NULL;
     477             : }
     478             : 
     479             : static void pass_msg(size_t nmemb, size_t got, int pass)
     480             : {
     481          59 :         logp("Tried to read %lu bytes, got %lu by pass %d\n",
     482             :                 (unsigned long)nmemb, (unsigned long)got, pass);
     483             : }
     484             : 
     485      736226 : int fzp_read_ensure(struct fzp *fzp, void *ptr, size_t nmemb, const char *func)
     486             : {
     487             :         static int f;
     488             :         static int r;
     489             :         static size_t got;
     490             :         static int pass;
     491     1471900 :         for(r=0, got=0, pass=0; got!=nmemb; pass++)
     492             :         {
     493      736285 :                 r=fzp_read(fzp, ((char *)ptr)+got, nmemb-got);
     494      736285 :                 if(r>0)
     495             :                 {
     496      735674 :                         got+=r;
     497      735674 :                         continue;
     498             :                 }
     499         611 :                 if(r<0)
     500             :                 {
     501           0 :                         pass_msg(nmemb, got, pass);
     502           0 :                         logp("Error in %s, called from %s: %s\n",
     503           0 :                                 __func__, func, strerror(errno));
     504           0 :                         return -1;
     505             :                 }
     506         611 :                 f=fzp_eof(fzp);
     507         611 :                 if(!f) continue; // Not yet end of file, keep trying.
     508         611 :                 if(f>0)
     509             :                 {
     510             :                         // End of file.
     511         611 :                         if(!got) return 1;
     512         118 :                         pass_msg(nmemb, got, pass);
     513          59 :                         logp("Error in %s, called from %s: %lu bytes, eof\n",
     514             :                                 __func__, func, (unsigned long)got);
     515          59 :                         return -1;
     516             :                 }
     517             :                 else
     518             :                 {
     519           0 :                         pass_msg(nmemb, got, pass);
     520           0 :                         logp("Error in %s by fzp_feof, called from %s: %s\n",
     521           0 :                                 __func__, func, strerror(errno));
     522           0 :                         return -1;
     523             :                 }
     524             :         }
     525             :         return 0;
     526             : }

Generated by: LCOV version 1.13