LCOV - code coverage report
Current view: top level - src - sbuf.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 126 144 87.5 %
Date: 2022-12-03 01:09:05 Functions: 14 16 87.5 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "sbuf.h"
       3             : #include "alloc.h"
       4             : #include "asfd.h"
       5             : #include "attribs.h"
       6             : #include "cmd.h"
       7             : #include "conf.h"
       8             : #include "handy.h"
       9             : #include "log.h"
      10             : #include "msg.h"
      11             : #include "pathcmp.h"
      12             : 
      13       32346 : struct sbuf *sbuf_alloc()
      14             : {
      15             :         struct sbuf *sb;
      16       32346 :         if(!(sb=(struct sbuf *)calloc_w(1, sizeof(struct sbuf), __func__)))
      17             :                 return NULL;
      18       32346 :         iobuf_init(&sb->path);
      19       32346 :         iobuf_init(&sb->attr);
      20       32346 :         sb->attr.cmd=CMD_ATTRIBS;
      21       32346 :         iobuf_init(&sb->link);
      22       32346 :         iobuf_init(&sb->endfile);
      23       32346 :         sb->compression=-1;
      24       32346 :         sb->use_winapi=1;
      25       32346 :         sb->datapth.cmd=CMD_DATAPTH;
      26             : 
      27       32346 :         return sb;
      28             : }
      29             : 
      30       59651 : void sbuf_free_content(struct sbuf *sb)
      31             : {
      32       59651 :         iobuf_free_content(&sb->path);
      33       59651 :         iobuf_free_content(&sb->attr);
      34       59651 :         iobuf_free_content(&sb->link);
      35       59651 :         iobuf_free_content(&sb->endfile);
      36       59651 :         memset(&(sb->statp), 0, sizeof(sb->statp));
      37       59651 :         sb->compression=-1;
      38       59651 :         sb->winattr=0;
      39       59651 :         sb->use_winapi=1;
      40       59651 :         sb->flags=0;
      41             : 
      42       59651 :         memset(&sb->rsbuf, 0, sizeof(sb->rsbuf));
      43       59651 :         if(sb->sigjob) { rs_job_free(sb->sigjob); sb->sigjob=NULL; }
      44       59651 :         rs_filebuf_free(&sb->infb);
      45       59651 :         rs_filebuf_free(&sb->outfb);
      46       59651 :         fzp_close(&sb->sigfzp);
      47       59651 :         fzp_close(&sb->fzp);
      48       59651 :         sb->salt=0;
      49       59651 :         iobuf_free_content(&sb->datapth);
      50       59651 :         sb->datapth.cmd=CMD_DATAPTH;
      51       59651 : }
      52             : 
      53       32367 : void sbuf_free(struct sbuf **sb)
      54             : {
      55       32367 :         if(!sb || !*sb) return;
      56       32346 :         sbuf_free_content(*sb);
      57       32346 :         free_v((void **)sb);
      58             : }
      59             : 
      60          26 : int sbuf_is_link(struct sbuf *sb)
      61             : {
      62          26 :         return iobuf_is_link(&sb->path);
      63             : }
      64             : 
      65       24462 : int sbuf_is_filedata(struct sbuf *sb)
      66             : {
      67       32744 :         return iobuf_is_filedata(&sb->path);
      68             : }
      69             : 
      70        5060 : int sbuf_is_vssdata(struct sbuf *sb)
      71             : {
      72        5158 :         return iobuf_is_vssdata(&sb->path);
      73             : }
      74             : 
      75          38 : int sbuf_is_encrypted(struct sbuf *sb)
      76             : {
      77          38 :         return iobuf_is_encrypted(&sb->path);
      78             : }
      79             : 
      80           0 : int sbuf_is_metadata(struct sbuf *sb)
      81             : {
      82           0 :         return iobuf_is_metadata(&sb->path);
      83             : }
      84             : 
      85           0 : int sbuf_is_estimatable(struct sbuf *sb)
      86             : {
      87           0 :         return iobuf_is_estimatable(&sb->path);
      88             : }
      89             : 
      90       11932 : int sbuf_to_manifest(struct sbuf *sb, struct fzp *fzp)
      91             : {
      92       11932 :         if(!sb->path.buf) return 0;
      93             : 
      94       11932 :         if(sb->datapth.buf
      95        6324 :           && iobuf_send_msg_fzp(&(sb->datapth), fzp))
      96             :                 return -1;
      97             : 
      98       11932 :         if(iobuf_send_msg_fzp(&sb->attr, fzp))
      99             :                 return -1;
     100       11932 :         if(iobuf_send_msg_fzp(&sb->path, fzp))
     101             :                 return -1;
     102       11932 :         if(sb->link.buf
     103        1426 :           && iobuf_send_msg_fzp(&sb->link, fzp))
     104             :                 return -1;
     105       11932 :         if(sb->endfile.buf
     106        6324 :           && iobuf_send_msg_fzp(&sb->endfile, fzp))
     107             :                 return -1;
     108             : 
     109             :         return 0;
     110             : }
     111             : 
     112          84 : int sbuf_to_manifest_cntr(struct sbuf *sb, struct fzp *fzp,
     113             :         enum cntr_manio what)
     114             : {
     115          84 :         if(!sb->path.buf) return 0;
     116          84 :         fzp_printf(fzp, "%c", (char)what);
     117          84 :         return iobuf_send_msg_fzp(&sb->path, fzp);
     118             : }
     119             : 
     120             : // Like pathcmp, but sort entries that have the same paths so that metadata
     121             : // comes later, and vss comes earlier, and trailing vss comes later.
     122          17 : int sbuf_pathcmp(struct sbuf *a, struct sbuf *b)
     123             : {
     124          17 :         return iobuf_pathcmp(&a->path, &b->path);
     125             : }
     126             : 
     127             : enum parse_ret
     128             : {
     129             :         PARSE_RET_ERROR=-1,
     130             :         PARSE_RET_NEED_MORE=0,
     131             :         PARSE_RET_COMPLETE=1,
     132             :         PARSE_RET_FINISHED=2,
     133             : };
     134             : 
     135       45359 : static enum parse_ret parse_cmd(struct sbuf *sb, struct asfd *asfd,
     136             :         struct iobuf *rbuf, struct cntr *cntr)
     137             : {
     138       45359 :         switch(rbuf->cmd)
     139             :         {
     140             :                 case CMD_ATTRIBS:
     141       13677 :                         if(sb->datapth.buf)
     142        8316 :                                 iobuf_free_content(&sb->attr);
     143             :                         else
     144        5361 :                                 sbuf_free_content(sb);
     145       13677 :                         iobuf_move(&sb->attr, rbuf);
     146       13677 :                         attribs_decode(sb);
     147       13677 :                         return PARSE_RET_NEED_MORE;
     148             : 
     149             :                 case CMD_FILE:
     150             :                 case CMD_DIRECTORY:
     151             :                 case CMD_SOFT_LINK:
     152             :                 case CMD_HARD_LINK:
     153             :                 case CMD_SPECIAL:
     154             :                 // Stuff not currently supported in burp-2, but OK
     155             :                 // to find in burp-1.
     156             :                 case CMD_ENC_FILE:
     157             :                 case CMD_METADATA:
     158             :                 case CMD_ENC_METADATA:
     159             :                 case CMD_EFS_FILE:
     160             :                 case CMD_VSS:
     161             :                 case CMD_ENC_VSS:
     162             :                 case CMD_VSS_T:
     163             :                 case CMD_ENC_VSS_T:
     164       15064 :                         if(!sb->attr.buf)
     165             :                         {
     166           1 :                                 log_and_send(asfd, "read cmd with no attribs");
     167           1 :                                 return PARSE_RET_ERROR;
     168             :                         }
     169       15063 :                         if(sb->flags & SBUF_NEED_LINK)
     170             :                         {
     171        1396 :                                 if(cmd_is_link(rbuf->cmd))
     172             :                                 {
     173        1396 :                                         iobuf_free_content(&sb->link);
     174        1396 :                                         iobuf_move(&sb->link, rbuf);
     175        1396 :                                         sb->flags &= ~SBUF_NEED_LINK;
     176        1396 :                                         return PARSE_RET_COMPLETE;
     177             :                                 }
     178             :                                 else
     179             :                                 {
     180           0 :                                         log_and_send(asfd, "got non-link after link in manifest");
     181           0 :                                         return PARSE_RET_NEED_MORE;
     182             :                                 }
     183             :                         }
     184             :                         else
     185             :                         {
     186       13667 :                                 if(iobuf_relative_path_attack(rbuf))
     187             :                                         return PARSE_RET_ERROR;
     188             : 
     189       13667 :                                 iobuf_free_content(&sb->path);
     190       13667 :                                 iobuf_move(&sb->path, rbuf);
     191       13667 :                                 if(cmd_is_link(rbuf->cmd))
     192             :                                 {
     193        1396 :                                         sb->flags |= SBUF_NEED_LINK;
     194        1396 :                                         return PARSE_RET_NEED_MORE;
     195             :                                 }
     196       12271 :                                 else if(sb->datapth.buf)
     197             :                                 {
     198             :                                         // Restore reads CMD_APPEND and
     199             :                                         // CMD_END_FILE in the calling
     200             :                                         // function, so pretend it is
     201             :                                         // complete if we have the hack flag.
     202        8316 :                                         if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
     203             :                                                 return PARSE_RET_COMPLETE;
     204        8312 :                                         return PARSE_RET_NEED_MORE;
     205             :                                 }
     206             :                                 return PARSE_RET_COMPLETE;
     207             :                         }
     208             :                 case CMD_MESSAGE:
     209             :                 case CMD_WARNING:
     210           0 :                         log_recvd(rbuf, cntr, 1);
     211           0 :                         return PARSE_RET_NEED_MORE;
     212             :                 case CMD_GEN:
     213          19 :                         if(!strcmp(rbuf->buf, "restoreend")
     214          17 :                           || !strcmp(rbuf->buf, "phase1end")
     215           1 :                           || !strcmp(rbuf->buf, "backupphase2")
     216           1 :                           || !strcmp(rbuf->buf, "backupend")
     217           1 :                           || !strcmp(rbuf->buf, "estimateend"))
     218             :                                 return PARSE_RET_FINISHED;
     219           1 :                         iobuf_log_unexpected(rbuf, __func__);
     220           1 :                         return PARSE_RET_ERROR;
     221             :                 case CMD_MANIFEST:
     222           0 :                         if(iobuf_relative_path_attack(rbuf))
     223             :                                 return PARSE_RET_ERROR;
     224           0 :                         iobuf_free_content(&sb->path);
     225           0 :                         iobuf_move(&sb->path, rbuf);
     226           0 :                         return PARSE_RET_COMPLETE;
     227             :                 case CMD_ERROR:
     228           0 :                         logp("got error: %s\n", rbuf->buf);
     229           0 :                         return PARSE_RET_ERROR;
     230             :                 case CMD_DATAPTH:
     231        8317 :                         if(iobuf_relative_path_attack(rbuf))
     232             :                                 return PARSE_RET_ERROR;
     233             : 
     234        8317 :                         if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
     235             :                         {
     236           5 :                                 sbuf_free_content(sb);
     237           5 :                                 sb->flags |= SBUF_CLIENT_RESTORE_HACK;
     238             :                         }
     239             :                         else
     240        8312 :                                 sbuf_free_content(sb);
     241             :                         
     242        8317 :                         iobuf_move(&sb->datapth, rbuf);
     243        8317 :                         return PARSE_RET_NEED_MORE;
     244             :                 case CMD_END_FILE:
     245        8282 :                         iobuf_free_content(&sb->endfile);
     246        8282 :                         iobuf_move(&sb->endfile, rbuf);
     247        8282 :                         if(!sb->attr.buf
     248        8282 :                           || !sb->datapth.buf
     249        8282 :                           || (!sbuf_is_filedata(sb)
     250          98 :                                 && !sbuf_is_vssdata(sb)))
     251             :                         {
     252           0 :                                 logp("got unexpected cmd_endfile");
     253           0 :                                 return PARSE_RET_ERROR;
     254             :                         }
     255             :                         return PARSE_RET_COMPLETE;
     256             :                 default:
     257           0 :                         iobuf_log_unexpected(rbuf, __func__);
     258           0 :                         return PARSE_RET_ERROR;
     259             :         }
     260             :         logp("Fell out of switch unexpectedly in %s()\n", __func__);
     261             :         return PARSE_RET_ERROR;
     262             : }
     263             : 
     264       13791 : static int sbuf_fill(struct sbuf *sb, struct asfd *asfd, struct fzp *fzp,
     265             :         struct cntr *cntr)
     266             : {
     267             :         static struct iobuf *rbuf;
     268             :         static struct iobuf localrbuf;
     269       13791 :         int ret=-1;
     270             : 
     271       13791 :         if(asfd) rbuf=asfd->rbuf;
     272             :         else
     273             :         {
     274             :                 // If not given asfd, use our own iobuf.
     275       13777 :                 memset(&localrbuf, 0, sizeof(struct iobuf));
     276       13777 :                 rbuf=&localrbuf;
     277             :         }
     278             :         while(1)
     279             :         {
     280       77195 :                 iobuf_free_content(rbuf);
     281       45493 :                 if(fzp)
     282             :                 {
     283       45461 :                         if((ret=iobuf_fill_from_fzp(rbuf, fzp)))
     284             :                                 goto end;
     285             :                 }
     286             :                 else
     287             :                 {
     288          32 :                         if(asfd->read(asfd))
     289             :                         {
     290           1 :                                 logp("error in async_read\n");
     291           1 :                                 break;
     292             :                         }
     293             :                 }
     294       45359 :                 switch(parse_cmd(sb, asfd, rbuf, cntr))
     295             :                 {
     296             :                         case PARSE_RET_NEED_MORE:
     297       31702 :                                 continue;
     298             :                         case PARSE_RET_COMPLETE:
     299             :                                 return 0;
     300             :                         case PARSE_RET_FINISHED:
     301             :                                 ret=1;
     302             :                                 goto end;
     303             :                         case PARSE_RET_ERROR:
     304             :                         default:
     305           2 :                                 ret=-1;
     306           2 :                                 goto end;
     307             :                 }
     308             :         }
     309             : end:
     310         154 :         iobuf_free_content(rbuf);
     311         154 :         return ret;
     312             : }
     313             : 
     314          14 : int sbuf_fill_from_net(struct sbuf *sb, struct asfd *asfd,
     315             :         struct cntr *cntr)
     316             : {
     317          14 :         return sbuf_fill(sb, asfd, NULL, cntr);
     318             : }
     319             : 
     320       13777 : int sbuf_fill_from_file(struct sbuf *sb, struct fzp *fzp)
     321             : {
     322       13777 :         return sbuf_fill(sb, NULL, fzp, NULL);
     323             : }

Generated by: LCOV version 1.13