LCOV - code coverage report
Current view: top level - src - fzp.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 157 216 72.7 %
Date: 2019-06-30 22:47:48 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        4386 :         return (struct fzp *)calloc_w(1, sizeof(struct fzp), __func__);
      16             : }
      17             : 
      18        4386 : static void fzp_free(struct fzp **fzp)
      19             : {
      20        4386 :         if(!fzp || !*fzp) return;
      21        4386 :         free_w(&(*fzp)->buf);
      22        4386 :         free_v((void **)fzp);
      23             : }
      24             : 
      25        3094 : static FILE *open_fp(const char *fname, const char *mode)
      26             : {
      27        3094 :         FILE *fp=NULL;
      28        3094 :         if(!(fp=fopen(fname, mode)))
      29          51 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      30        3094 :         return fp;
      31             : }
      32             : 
      33        1251 : static gzFile open_zp(const char *fname, const char *mode)
      34             : {
      35        1251 :         gzFile zp=NULL;
      36             : 
      37        1251 :         if(!(zp=gzopen(fname, mode)))
      38           3 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      39        1251 :         return zp;
      40             : }
      41             : 
      42        3135 : static int close_fp(FILE **fp)
      43             : {
      44        3135 :         int ret=0;
      45        3135 :         if(!*fp) return ret;
      46        3084 :         if(fclose(*fp))
      47             :         {
      48           0 :                 logp("fclose failed: %s\n", strerror(errno));
      49           0 :                 ret=-1;
      50             :         }
      51        3084 :         *fp=NULL;
      52        3084 :         return ret;
      53             : }
      54             : 
      55        1251 : static int close_zp(gzFile *zp)
      56             : {
      57             :         int e;
      58        1251 :         int ret=0;
      59        1251 :         if(!*zp) return ret;
      60        1248 :         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        4345 : static struct fzp *fzp_do_open(const char *path, const char *mode,
      85             :         enum fzp_type type)
      86             : {
      87        4345 :         struct fzp *fzp=NULL;
      88             : 
      89        4345 :         if(!(fzp=fzp_alloc())) goto error;
      90        4345 :         fzp->type=type;
      91        4345 :         switch(type)
      92             :         {
      93             :                 case FZP_FILE:
      94        3094 :                         if(!(fzp->fp=open_fp(path, mode)))
      95             :                                 goto error;
      96        3043 :                         return fzp;
      97             :                 case FZP_COMPRESSED:
      98        1251 :                         if(!(fzp->zp=open_zp(path, mode)))
      99             :                                 goto error;
     100        1248 :                         return fzp;
     101             :                 default:
     102           0 :                         unknown_type(fzp->type, __func__);
     103             :                         goto error;
     104             :         }
     105             : error:
     106          54 :         fzp_close(&fzp);
     107          54 :         return NULL;
     108             : }
     109             : 
     110        3094 : struct fzp *fzp_open(const char *path, const char *mode)
     111             : {
     112        3094 :         return fzp_do_open(path, mode, FZP_FILE);
     113             : }
     114             : 
     115        1251 : struct fzp *fzp_gzopen(const char *path, const char *mode)
     116             : {
     117        1251 :         return fzp_do_open(path, mode, FZP_COMPRESSED);
     118             : }
     119             : 
     120      124334 : int fzp_close(struct fzp **fzp)
     121             : {
     122      124334 :         int ret=-1;
     123      124334 :         if(!fzp || !*fzp) return 0;
     124        4386 :         switch((*fzp)->type)
     125             :         {
     126             :                 case FZP_FILE:
     127        3135 :                         ret=close_fp(&((*fzp)->fp));
     128        3135 :                         break;
     129             :                 case FZP_COMPRESSED:
     130        1251 :                         ret=close_zp(&((*fzp)->zp));
     131        1251 :                         break;
     132             :                 default:
     133           0 :                         unknown_type((*fzp)->type, __func__);
     134             :                         break;
     135             :         }
     136        4386 :         fzp_free(fzp);
     137        4386 :         return ret;
     138             : }
     139             : 
     140      740035 : int fzp_read(struct fzp *fzp, void *ptr, size_t nmemb)
     141             : {
     142      740035 :         if(fzp) switch(fzp->type)
     143             :         {
     144             :                 case FZP_FILE:
     145      459720 :                         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 :         if(!path)
     280             :         {
     281             :                 // Avoids a valgrind complaint in one of the tests.
     282           1 :                 errno=ENOENT;
     283           1 :                 goto error;
     284             :         }
     285         208 :         switch(type)
     286             :         {
     287             :                 case FZP_FILE:
     288         204 :                         return truncate(path, length);
     289             :                 case FZP_COMPRESSED:
     290           4 :                         return gztruncate(path, length, compression);
     291             :                 default:
     292             :                         unknown_type(type, __func__);
     293             :                         goto error;
     294             :         }
     295             : error:
     296             :         return -1;
     297             : }
     298             : #endif
     299             : 
     300      942704 : int fzp_printf(struct fzp *fzp, const char *format, ...)
     301             : {
     302      942704 :         int ret=-1;
     303             :         int n;
     304             : 
     305      942704 :         if(!fzp)
     306             :         {
     307           1 :                 not_open(__func__);
     308           1 :                 return ret;
     309             :         }
     310             : 
     311      942703 :         if(!fzp->buf)
     312             :         {
     313        1561 :                 fzp->s=128;
     314        1561 :                 if(!(fzp->buf=(char *)malloc_w(fzp->s, __func__)))
     315             :                         return ret;
     316             :         }
     317             : 
     318             :         // Avoid fixed size buffer.
     319             :         while(1)
     320             :         {
     321             :                 va_list ap;
     322      942703 :                 va_start(ap, format);
     323      942703 :                 n=vsnprintf(fzp->buf, fzp->s, format, ap);
     324      942703 :                 va_end(ap);
     325      942703 :                 if(n<0)
     326             :                 {
     327           0 :                         logp("Failed to vsnprintf in %s: %s\n",
     328           0 :                                 __func__, strerror(errno));
     329           0 :                         return ret;
     330             :                 }
     331      942703 :                 if(fzp->s<(size_t)n)
     332             :                 {
     333           0 :                         fzp->s*=2;
     334           0 :                         if(!(fzp->buf=(char *)
     335           0 :                                 realloc_w(fzp->buf, fzp->s, __func__)))
     336             :                                         return ret;
     337           0 :                         continue;
     338             :                 }
     339             : 
     340      942703 :                 break;
     341             :         }
     342             : 
     343      942703 :         switch(fzp->type)
     344             :         {
     345             :                 case FZP_FILE:
     346      589759 :                         ret=fprintf(fzp->fp, "%s", fzp->buf);
     347      589759 :                         break;
     348             :                 case FZP_COMPRESSED:
     349      352944 :                         ret=gzprintf(fzp->zp, "%s", fzp->buf);
     350      352944 :                         break;
     351             :                 default:
     352           0 :                         unknown_type(fzp->type, __func__);
     353             :                         break;
     354             :         }
     355             : 
     356             :         return ret;
     357             : }
     358             : 
     359          13 : void fzp_setlinebuf(struct fzp *fzp)
     360             : {
     361             : #ifndef HAVE_WIN32
     362          13 :         if(fzp) switch(fzp->type)
     363             :         {
     364             :                 case FZP_FILE:
     365          12 :                         setlinebuf(fzp->fp);
     366          12 :                         return;
     367             :                 case FZP_COMPRESSED:
     368           0 :                         logp("gzsetlinebuf() does not exist in %s\n", __func__);
     369           0 :                         return;
     370             :                 default:
     371           0 :                         unknown_type(fzp->type, __func__);
     372             :                         return;
     373             :         }
     374             :         not_open(__func__);
     375             : #endif
     376             : }
     377             : 
     378        1221 : char *fzp_gets(struct fzp *fzp, char *s, int size)
     379             : {
     380        1221 :         if(fzp) switch(fzp->type)
     381             :         {
     382             :                 case FZP_FILE:
     383        1220 :                         return fgets(s, size, fzp->fp);
     384             :                 case FZP_COMPRESSED:
     385           0 :                         return gzgets(fzp->zp, s, size);
     386             :                 default:
     387           0 :                         unknown_type(fzp->type, __func__);
     388             :                         goto error;
     389             :         }
     390             :         not_open(__func__);
     391             : error:
     392             :         return NULL;
     393             : }
     394             : 
     395          12 : extern int fzp_fileno(struct fzp *fzp)
     396             : {
     397          12 :         if(fzp) switch(fzp->type)
     398             :         {
     399             :                 case FZP_FILE:
     400          11 :                         return fileno(fzp->fp);
     401             :                 case FZP_COMPRESSED:
     402           0 :                         logp("gzfileno() does not exist in %s\n", __func__);
     403           0 :                         goto error;
     404             :                 default:
     405           0 :                         unknown_type(fzp->type, __func__);
     406             :                         goto error;
     407             :         }
     408             :         not_open(__func__);
     409             : error:
     410             :         return -1;
     411             : }
     412             : 
     413          41 : static struct fzp *fzp_do_dopen(int fd, const char *mode,
     414             :         enum fzp_type type)
     415             : {
     416          41 :         struct fzp *fzp=NULL;
     417             : 
     418          41 :         if(!(fzp=fzp_alloc())) goto error;
     419          41 :         fzp->type=type;
     420          41 :         switch(type)
     421             :         {
     422             :                 case FZP_FILE:
     423          41 :                         if(!(fzp->fp=fdopen(fd, mode)))
     424             :                                 goto error;
     425          41 :                         return fzp;
     426             :                 case FZP_COMPRESSED:
     427           0 :                         if(!(fzp->zp=gzdopen(fd, mode)))
     428             :                                 goto error;
     429           0 :                         return fzp;
     430             :                 default:
     431           0 :                         unknown_type(fzp->type, __func__);
     432             :                         goto error;
     433             :         }
     434             : error:
     435           0 :         fzp_close(&fzp);
     436           0 :         return NULL;
     437             : }
     438             : 
     439          41 : struct fzp *fzp_dopen(int fd, const char *mode)
     440             : {
     441          41 :         return fzp_do_dopen(fd, mode, FZP_FILE);
     442             : }
     443             : 
     444           0 : struct fzp *fzp_gzdopen(int fd, const char *mode)
     445             : {
     446           0 :         return fzp_do_dopen(fd, mode, FZP_COMPRESSED);
     447             : }
     448             : 
     449           1 : void fzp_ERR_print_errors_fp(struct fzp *fzp)
     450             : {
     451           1 :         if(fzp) switch(fzp->type)
     452             :         {
     453             :                 case FZP_FILE:
     454           0 :                         ERR_print_errors_fp(fzp->fp);
     455           0 :                         break;
     456             :                 case FZP_COMPRESSED:
     457           0 :                         logp("ERR_print_errors_zp() does not exist in %s\n",
     458             :                                 __func__);
     459           0 :                         break;
     460             :                 default:
     461           0 :                         unknown_type(fzp->type, __func__);
     462             :                         break;
     463             :         }
     464           1 : }
     465             : 
     466           1 : X509 *fzp_PEM_read_X509(struct fzp *fzp)
     467             : {
     468           1 :         if(fzp) switch(fzp->type)
     469             :         {
     470             :                 case FZP_FILE:
     471           0 :                         return PEM_read_X509(fzp->fp, NULL, NULL, NULL);
     472             :                 case FZP_COMPRESSED:
     473           0 :                         logp("PEM_read_X509() does not exist in %s\n",
     474             :                                 __func__);
     475           0 :                         goto error;
     476             :                 default:
     477           0 :                         unknown_type(fzp->type, __func__);
     478             :                         goto error;
     479             :         }
     480             :         not_open(__func__);
     481             : error:
     482             :         return NULL;
     483             : }
     484             : 
     485             : static void pass_msg(size_t nmemb, size_t got, int pass)
     486             : {
     487          59 :         logp("Tried to read %lu bytes, got %lu by pass %d\n",
     488             :                 (unsigned long)nmemb, (unsigned long)got, pass);
     489             : }
     490             : 
     491      736226 : int fzp_read_ensure(struct fzp *fzp, void *ptr, size_t nmemb, const char *func)
     492             : {
     493             :         static int f;
     494             :         static int r;
     495             :         static size_t got;
     496             :         static int pass;
     497     1471900 :         for(r=0, got=0, pass=0; got!=nmemb; pass++)
     498             :         {
     499      736285 :                 r=fzp_read(fzp, ((char *)ptr)+got, nmemb-got);
     500      736285 :                 if(r>0)
     501             :                 {
     502      735674 :                         got+=r;
     503      735674 :                         continue;
     504             :                 }
     505         611 :                 if(r<0)
     506             :                 {
     507           0 :                         pass_msg(nmemb, got, pass);
     508           0 :                         logp("Error in %s, called from %s: %s\n",
     509           0 :                                 __func__, func, strerror(errno));
     510           0 :                         return -1;
     511             :                 }
     512         611 :                 f=fzp_eof(fzp);
     513         611 :                 if(!f) continue; // Not yet end of file, keep trying.
     514         611 :                 if(f>0)
     515             :                 {
     516             :                         // End of file.
     517         611 :                         if(!got) return 1;
     518         118 :                         pass_msg(nmemb, got, pass);
     519          59 :                         logp("Error in %s, called from %s: %lu bytes, eof\n",
     520             :                                 __func__, func, (unsigned long)got);
     521          59 :                         return -1;
     522             :                 }
     523             :                 else
     524             :                 {
     525           0 :                         pass_msg(nmemb, got, pass);
     526           0 :                         logp("Error in %s by fzp_feof, called from %s: %s\n",
     527           0 :                                 __func__, func, strerror(errno));
     528           0 :                         return -1;
     529             :                 }
     530             :         }
     531             :         return 0;
     532             : }

Generated by: LCOV version 1.13