LCOV - code coverage report
Current view: top level - src - transfer.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 51 104 49.0 %
Date: 2022-08-30 22:36:43 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "asfd.h"
       4             : #include "async.h"
       5             : #include "cmd.h"
       6             : #include "cntr.h"
       7             : #include "handy_extra.h"
       8             : #include "iobuf.h"
       9             : #include "log.h"
      10             : #include "prepend.h"
      11             : #include "sbuf.h"
      12             : #include "msg.h"
      13             : 
      14           4 : static int do_write(struct asfd *asfd,
      15             :         struct BFILE *bfd, uint8_t *out, size_t outlen,
      16             :         char **metadata, uint64_t *sent)
      17             : {
      18           4 :         int ret=0;
      19           4 :         if(metadata)
      20             :         {
      21             :                 // Append it to our metadata.
      22           0 :                 out[outlen]='\0';
      23             :                 //printf("\nadd outlen: %lu\n", outlen);
      24           0 :                 if(!(*metadata=prepend_len(*metadata, *sent,
      25             :                                 (const char *)out, outlen,
      26             :                                 "", 0, (size_t *)sent)))
      27             :                 {
      28           0 :                         logp("error when appending metadata\n");
      29           0 :                         asfd->write_str(asfd, CMD_ERROR,
      30             :                                 "error when appending metadata");
      31           0 :                         return -1;
      32             :                 }
      33             :         }
      34             :         else
      35             :         {
      36           4 :                 if((ret=bfd->write(bfd, out, outlen))<=0)
      37             :                 {
      38           0 :                         logp("error when appending %lu: %d\n",
      39             :                                 (unsigned long)outlen, ret);
      40           0 :                         asfd->write_str(asfd, CMD_ERROR, "write failed");
      41           0 :                         return -1;
      42             :                 }
      43           4 :                 *sent+=outlen;
      44             :         }
      45             :         return 0;
      46             : }
      47             : 
      48           4 : static int do_inflate(struct asfd *asfd,
      49             :         z_stream *zstrm, struct BFILE *bfd,
      50             :         uint8_t *out, uint8_t *buftouse, size_t lentouse,
      51             :         char **metadata, const char *encpassword, int enccompressed,
      52             :         uint64_t *sent)
      53             : {
      54           4 :         int zret=Z_OK;
      55           4 :         unsigned have=0;
      56             : 
      57             :         // Do not want to inflate encrypted data that was not compressed.
      58             :         // Just write it straight out.
      59           4 :         if(encpassword && !enccompressed)
      60           0 :                 return do_write(asfd, bfd, buftouse, lentouse, metadata, sent);
      61             : 
      62           4 :         zstrm->avail_in=lentouse;
      63           4 :         zstrm->next_in=buftouse;
      64             : 
      65             :         do
      66             :         {
      67           4 :                 zstrm->avail_out=ZCHUNK;
      68           4 :                 zstrm->next_out=out;
      69           4 :                 zret=inflate(zstrm, Z_NO_FLUSH);
      70           4 :                 switch(zret)
      71             :                 {
      72             :                         case Z_NEED_DICT:
      73           0 :                           zret=Z_DATA_ERROR;
      74             :                         case Z_DATA_ERROR:
      75             :                         case Z_MEM_ERROR:
      76           0 :                           logp("zstrm inflate error: %d\n", zret);
      77           0 :                           return -1;
      78             :                           break;
      79             :                 }
      80           4 :                 have=ZCHUNK-zstrm->avail_out;
      81           4 :                 if(!have) continue;
      82             : 
      83           4 :                 if(do_write(asfd, bfd, out, have, metadata, sent))
      84             :                         return -1;
      85           4 :         } while(!zstrm->avail_out);
      86             :         return 0;
      87             : }
      88             : 
      89             : #ifdef HAVE_WIN32
      90             : 
      91             : struct winbuf
      92             : {
      93             :         uint64_t *rcvd;
      94             :         uint64_t *sent;
      95             :         struct cntr *cntr;
      96             :         struct asfd *asfd;
      97             : };
      98             : 
      99             : static DWORD WINAPI read_efs(PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength)
     100             : {
     101             :         struct iobuf *rbuf;
     102             :         struct winbuf *mybuf=(struct winbuf *)pvCallbackContext;
     103             :         rbuf=mybuf->asfd->rbuf;
     104             : 
     105             :         while(1)
     106             :         {
     107             :                 if(mybuf->asfd->read(mybuf->asfd))
     108             :                         return ERROR_FUNCTION_FAILED;
     109             :                 (*(mybuf->rcvd))+=rbuf->len;
     110             : 
     111             :                 switch(rbuf->cmd)
     112             :                 {
     113             :                         case CMD_APPEND:
     114             :                                 memcpy(pbData, rbuf->buf, rbuf->len);
     115             :                                 *ulLength=(ULONG)rbuf->len;
     116             :                                 (*(mybuf->sent))+=rbuf->len;
     117             :                                 iobuf_free_content(rbuf);
     118             :                                 return ERROR_SUCCESS;
     119             :                         case CMD_END_FILE:
     120             :                                 *ulLength=0;
     121             :                                 iobuf_free_content(rbuf);
     122             :                                 return ERROR_SUCCESS;
     123             :                         case CMD_MESSAGE:
     124             :                                 logp("MESSAGE: %s\n", rbuf->buf);
     125             :                                 cntr_add(mybuf->cntr, rbuf->cmd, 0);
     126             :                                 iobuf_free_content(rbuf);
     127             :                                 continue;
     128             :                         case CMD_WARNING:
     129             :                                 logp("WARNING: %s\n", rbuf->buf);
     130             :                                 cntr_add(mybuf->cntr, rbuf->cmd, 0);
     131             :                                 iobuf_free_content(rbuf);
     132             :                                 continue;
     133             :                         default:
     134             :                                 iobuf_log_unexpected(rbuf, __func__);
     135             :                                 iobuf_free_content(rbuf);
     136             :                                 break;
     137             :                 }
     138             :         }
     139             :         return ERROR_FUNCTION_FAILED;
     140             : }
     141             : 
     142             : static int transfer_efs_in(struct asfd *asfd,
     143             :         struct BFILE *bfd, uint64_t *rcvd,
     144             :         uint64_t *sent, struct cntr *cntr)
     145             : {
     146             :         int ret=0;
     147             :         struct winbuf mybuf;
     148             :         mybuf.rcvd=rcvd;
     149             :         mybuf.sent=sent;
     150             :         mybuf.cntr=cntr;
     151             :         mybuf.asfd=asfd;
     152             :         if((ret=WriteEncryptedFileRaw((PFE_IMPORT_FUNC)read_efs,
     153             :                 &mybuf, bfd->pvContext)))
     154             :                         logp("WriteEncryptedFileRaw returned %d\n", ret);
     155             :         return ret;
     156             : }
     157             : 
     158             : #endif
     159             : 
     160           4 : int transfer_gzfile_inl(struct asfd *asfd,
     161             : #ifdef HAVE_WIN32
     162             :         struct sbuf *sb,
     163             : #endif
     164             :         struct BFILE *bfd,
     165             :         uint64_t *rcvd, uint64_t *sent,
     166             :         const char *encpassword, int enccompressed,
     167             :         struct cntr *cntr, char **metadata,
     168             :         int key_deriv, uint64_t salt)
     169             : {
     170           4 :         int quit=0;
     171           4 :         int ret=-1;
     172             :         uint8_t out[ZCHUNK];
     173           4 :         int doutlen=0;
     174             :         uint8_t doutbuf[ZCHUNK-EVP_MAX_BLOCK_LENGTH];
     175           4 :         struct iobuf *rbuf=asfd->rbuf;
     176             : 
     177             :         z_stream zstrm;
     178             : 
     179           4 :         EVP_CIPHER_CTX *enc_ctx=NULL;
     180             : 
     181             : #ifdef HAVE_WIN32
     182             :         if(sb && sb->path.cmd==CMD_EFS_FILE)
     183             :                 return transfer_efs_in(asfd, bfd, rcvd, sent, cntr);
     184             : #endif
     185             : 
     186           4 :         zstrm.zalloc=Z_NULL;
     187           4 :         zstrm.zfree=Z_NULL;
     188           4 :         zstrm.opaque=Z_NULL;
     189           4 :         zstrm.avail_in=0;
     190           4 :         zstrm.next_in=Z_NULL;
     191             : 
     192           4 :         if(inflateInit2(&zstrm, (15+16)))
     193             :         {
     194           0 :                 logp("unable to init inflate\n");
     195           0 :                 return -1;
     196             :         }
     197             : 
     198           4 :         if(encpassword
     199           0 :           && !(enc_ctx=enc_setup(0, encpassword, key_deriv, salt)))
     200             :         {
     201           0 :                 inflateEnd(&zstrm);
     202           0 :                 return -1;
     203             :         }
     204             : 
     205          12 :         while(!quit)
     206             :         {
     207           8 :                 iobuf_free_content(rbuf);
     208           8 :                 if(asfd->read(asfd))
     209             :                 {
     210           0 :                         if(enc_ctx)
     211             :                         {
     212           0 :                                 EVP_CIPHER_CTX_cleanup(enc_ctx);
     213           0 :                                 EVP_CIPHER_CTX_free(enc_ctx);
     214           0 :                                 enc_ctx=NULL;
     215             :                         }
     216           0 :                         inflateEnd(&zstrm);
     217           0 :                         return -1;
     218             :                 }
     219           8 :                 (*rcvd)+=rbuf->len;
     220             : 
     221           8 :                 switch(rbuf->cmd)
     222             :                 {
     223             :                         case CMD_APPEND: // append
     224           4 :                                 if(!bfd && !metadata)
     225             :                                 {
     226           0 :                                         logp("given append, but no file or metadata to write to\n");
     227           0 :                                         asfd->write_str(asfd, CMD_ERROR,
     228             :                                           "append with no file or metadata");
     229           0 :                                         quit++; ret=-1;
     230             :                                 }
     231             :                                 else
     232             :                                 {
     233             :                                         size_t lentouse;
     234           4 :                                         uint8_t *buftouse=NULL;
     235             :                                         // If doing decryption, it needs
     236             :                                         // to be done before uncompressing.
     237           4 :                                         if(enc_ctx)
     238             :                                         {
     239             :                                           // updating our checksum needs to
     240             :                                           // be done first
     241           0 :                                           if(!EVP_CipherUpdate(enc_ctx,
     242             :                                                 doutbuf, &doutlen,
     243           0 :                                                 (uint8_t *)rbuf->buf,
     244           0 :                                                 rbuf->len))
     245             :                                           {
     246           0 :                                                 logp("Decryption error\n");
     247           0 :                                                 quit++; ret=-1;
     248           0 :                                                 break;
     249             :                                           }
     250           0 :                                           if(!doutlen) break;
     251           0 :                                           lentouse=(size_t)doutlen;
     252           0 :                                           buftouse=doutbuf;
     253             :                                         }
     254             :                                         else
     255             :                                         {
     256           4 :                                           lentouse=rbuf->len;
     257           4 :                                           buftouse=(uint8_t *)rbuf->buf;
     258             :                                         }
     259             :                                         //logp("want to write: %d\n", zstrm.avail_in);
     260             : 
     261           4 :                                         if(do_inflate(asfd, &zstrm, bfd, out,
     262             :                                                 buftouse, lentouse, metadata,
     263             :                                                 encpassword,
     264             :                                                 enccompressed,
     265             :                                                 sent))
     266             :                                         {
     267           0 :                                                 ret=-1; quit++;
     268           0 :                                                 break;
     269             :                                         }
     270             :                                 }
     271             :                                 break;
     272             :                         case CMD_END_FILE: // finish up
     273           4 :                                 if(enc_ctx)
     274             :                                 {
     275           0 :                                         if(!EVP_CipherFinal_ex(enc_ctx,
     276             :                                                 doutbuf, &doutlen))
     277             :                                         {
     278           0 :                                                 logp("Decryption failure at the end.\n");
     279           0 :                                                 ret=-1; quit++;
     280           0 :                                                 break;
     281             :                                         }
     282           0 :                                         if(doutlen && do_inflate(asfd,
     283             :                                           &zstrm, bfd,
     284             :                                           out, doutbuf, (size_t)doutlen,
     285             :                                           metadata, encpassword,
     286             :                                           enccompressed, sent))
     287             :                                         {
     288           0 :                                                 ret=-1; quit++;
     289           0 :                                                 break;
     290             :                                         }
     291             :                                 }
     292           4 :                                 quit++;
     293           4 :                                 ret=0;
     294           4 :                                 break;
     295             :                         case CMD_MESSAGE:
     296             :                         case CMD_WARNING:
     297           0 :                                 log_recvd(rbuf, cntr, 0);
     298           0 :                                 break;
     299             :                         default:
     300           0 :                                 iobuf_log_unexpected(rbuf, __func__);
     301           0 :                                 quit++;
     302           0 :                                 ret=-1;
     303           0 :                                 break;
     304             :                 }
     305             :         }
     306           4 :         inflateEnd(&zstrm);
     307           4 :         if(enc_ctx)
     308             :         {
     309           0 :                 EVP_CIPHER_CTX_cleanup(enc_ctx);
     310           0 :                 EVP_CIPHER_CTX_free(enc_ctx);
     311           0 :                 enc_ctx=NULL;
     312             :         }
     313             : 
     314           4 :         iobuf_free_content(rbuf);
     315           4 :         if(ret) logp("transfer file returning: %d\n", ret);
     316             :         return ret;
     317             : }

Generated by: LCOV version 1.13