LCOV - code coverage report
Current view: top level - src/client - extra_comms.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 105 105 100.0 %
Date: 2016-07-31 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../asfd.h"
       3             : #include "../async.h"
       4             : #include "../cmd.h"
       5             : #include "../conf.h"
       6             : #include "../conffile.h"
       7             : #include "../handy.h"
       8             : #include "../incexc_recv.h"
       9             : #include "../incexc_send.h"
      10             : #include "../iobuf.h"
      11             : #include "../log.h"
      12             : #include "autoupgrade.h"
      13             : 
      14             : #ifndef HAVE_WIN32
      15             : #include <sys/utsname.h>
      16             : #endif
      17             : 
      18             : static const char *server_supports(const char *feat, const char *wanted)
      19             : {
      20             :         return strstr(feat, wanted);
      21             : }
      22             : 
      23          22 : static const char *server_supports_autoupgrade(const char *feat)
      24             : {
      25             :         // 1.3.0 servers did not list the features, but the only feature
      26             :         // that was supported was autoupgrade.
      27          22 :         if(!strcmp(feat, "extra_comms_begin ok")) return "ok";
      28          22 :         return server_supports(feat, ":autoupgrade:");
      29             : }
      30             : 
      31             : #include <librsync.h>
      32             : 
      33          25 : int extra_comms(struct async *as, struct conf **confs,
      34             :         enum action *action, char **incexc)
      35             : {
      36          25 :         int ret=-1;
      37          25 :         char *feat=NULL;
      38             :         struct asfd *asfd;
      39             :         struct iobuf *rbuf;
      40          25 :         const char *orig_client=get_string(confs[OPT_ORIG_CLIENT]);
      41          25 :         asfd=as->asfd;
      42          25 :         rbuf=asfd->rbuf;
      43             : 
      44          25 :         if(asfd->write_str(asfd, CMD_GEN, "extra_comms_begin"))
      45             :         {
      46           1 :                 logp("Problem requesting extra_comms_begin\n");
      47           1 :                 goto end;
      48             :         }
      49             :         // Servers greater than 1.3.0 will list the extra_comms
      50             :         // features they support.
      51          24 :         if(asfd->read(asfd))
      52             :         {
      53           1 :                 logp("Problem reading response to extra_comms_begin\n");
      54           1 :                 goto end;
      55             :         }
      56          23 :         feat=rbuf->buf;
      57          23 :         rbuf->buf=NULL;
      58          46 :         if(rbuf->cmd!=CMD_GEN
      59          23 :           || strncmp_w(feat, "extra_comms_begin ok"))
      60             :         {
      61           1 :                 iobuf_log_unexpected(rbuf, __func__);
      62           1 :                 goto end;
      63             :         }
      64          22 :         logp("%s\n", feat);
      65          22 :         iobuf_init(rbuf);
      66             : 
      67             :         // Can add extra bits here. The first extra bit is the
      68             :         // autoupgrade stuff.
      69          44 :         if(server_supports_autoupgrade(feat)
      70           1 :           && get_string(confs[OPT_AUTOUPGRADE_DIR])
      71           1 :           && get_string(confs[OPT_AUTOUPGRADE_OS])
      72          23 :           && autoupgrade_client(as, confs))
      73             :                 goto end;
      74             : 
      75             : 
      76             :         // :srestore: means that the server wants to do a restore.
      77          42 :         if(server_supports(feat, ":srestore:"))
      78             :         {
      79           3 :                 logp("Server wants to initiate a restore\n");
      80           3 :                 if(*action==ACTION_MONITOR)
      81             :                 {
      82           1 :                         logp("Client is in monitor mode, so ignoring\n");
      83             :                 }
      84           2 :                 else if(get_int(confs[OPT_SERVER_CAN_RESTORE]))
      85             :                 {
      86           1 :                         logp("Client accepts.\n");
      87           1 :                         if(incexc_recv_client_restore(asfd, incexc, confs))
      88             :                                 goto end;
      89           1 :                         if(*incexc)
      90             :                         {
      91           1 :                                 if(conf_parse_incexcs_buf(confs, *incexc))
      92             :                                         goto end;
      93           1 :                                 *action=ACTION_RESTORE;
      94           1 :                                 log_restore_settings(confs, 1);
      95             :                         }
      96             :                 }
      97             :                 else
      98             :                 {
      99           1 :                         logp("Client configuration says no\n");
     100           1 :                         if(asfd->write_str(asfd, CMD_GEN, "srestore not ok"))
     101             :                                 goto end;
     102             :                 }
     103             :         }
     104             : 
     105          21 :         if(orig_client)
     106             :         {
     107           3 :                 char str[512]="";
     108             :                 snprintf(str, sizeof(str), "orig_client=%s", orig_client);
     109           6 :                 if(!server_supports(feat, ":orig_client:"))
     110             :                 {
     111           1 :                         logp("Server does not support switching client.\n");
     112           1 :                         goto end;
     113             :                 }
     114           4 :                 if(asfd->write_str(asfd, CMD_GEN, str)
     115           2 :                   || asfd_read_expect(asfd, CMD_GEN, "orig_client ok"))
     116             :                 {
     117           1 :                         logp("Problem requesting %s\n", str);
     118           1 :                         goto end;
     119             :                 }
     120           1 :                 logp("Switched to client %s\n", orig_client);
     121             :         }
     122             : 
     123             :         // :sincexc: is for the server giving the client the
     124             :         // incexc config.
     125          19 :         if(*action==ACTION_BACKUP
     126          19 :           || *action==ACTION_BACKUP_TIMED
     127          19 :           || *action==ACTION_TIMER_CHECK)
     128             :         {
     129          34 :                 if(!*incexc && server_supports(feat, ":sincexc:"))
     130             :                 {
     131           2 :                         logp("Server is setting includes/excludes.\n");
     132           2 :                         if(get_int(confs[OPT_SERVER_CAN_OVERRIDE_INCLUDES]))
     133             :                         {
     134           1 :                                 logp("Client accepts.\n");
     135           1 :                                 if(incexc_recv_client(asfd, incexc, confs))
     136             :                                         goto end;
     137           2 :                                 if(*incexc && conf_parse_incexcs_buf(confs,
     138           1 :                                         *incexc)) goto end;
     139             :                         }
     140             :                         else
     141             :                         {
     142           1 :                                 logp("Client configuration says no\n");
     143             :                         }
     144             :                 }
     145             :         }
     146             : 
     147          38 :         if(server_supports(feat, ":counters_json:"))
     148             :         {
     149           1 :                 if(asfd->write_str(asfd, CMD_GEN, "counters_json ok"))
     150             :                         goto end;
     151           1 :                 set_int(confs[OPT_SEND_CLIENT_CNTR], 1);
     152             :         }
     153             : 
     154             :         // :incexc: is for the client sending the server the
     155             :         // incexc conf so that it better knows what to do on
     156             :         // resume.
     157          38 :         if(server_supports(feat, ":incexc:")
     158          19 :           && incexc_send_client(asfd, confs))
     159             :                 goto end;
     160             : 
     161          38 :         if(server_supports(feat, ":uname:"))
     162             :         {
     163           1 :                 const char *clientos=NULL;
     164             : #ifdef HAVE_WIN32
     165             : #ifdef _WIN64
     166             :                 clientos="Windows 64bit";
     167             : #else
     168             :                 clientos="Windows 32bit";
     169             : #endif
     170             : #else
     171             :                 struct utsname utsname;
     172           1 :                 if(!uname(&utsname))
     173           1 :                         clientos=(const char *)utsname.sysname;
     174             : #endif
     175           1 :                 if(clientos)
     176             :                 {
     177           1 :                         char msg[128]="";
     178             :                         snprintf(msg, sizeof(msg),
     179             :                                 "uname=%s", clientos);
     180           1 :                         if(asfd->write_str(asfd, CMD_GEN, msg))
     181             :                                 goto end;
     182             :                 }
     183             :         }
     184             : 
     185          38 :         if(server_supports(feat, ":csetproto:"))
     186             :         {
     187           3 :                 char msg[128]="";
     188             :                 // Use protocol1 if no choice has been made on client side.
     189           3 :                 if(get_protocol(confs)==PROTO_AUTO)
     190             :                 {
     191           1 :                         logp("Server has protocol=0 (auto)\n");
     192           1 :                         set_protocol(confs, PROTO_1);
     193             :                 }
     194             :                 // Send choice to server.
     195             :                 snprintf(msg, sizeof(msg), "protocol=%d",
     196           3 :                         get_protocol(confs));
     197           3 :                 if(asfd->write_str(asfd, CMD_GEN, msg))
     198             :                         goto end;
     199             :                 logp("Using protocol=%d\n",
     200           3 :                         get_protocol(confs));
     201             :         }
     202          32 :         else if(server_supports(feat, ":forceproto=1:"))
     203             :         {
     204           2 :                 logp("Server is forcing protocol 1\n");
     205           4 :                 if(get_protocol(confs)!=PROTO_AUTO
     206           2 :                   && get_protocol(confs)!=PROTO_1)
     207             :                 {
     208             :                         logp("But client has set protocol=%d!\n",
     209           1 :                                 get_protocol(confs));
     210           1 :                         goto end;
     211             :                 }
     212           1 :                 set_protocol(confs, PROTO_1);
     213             :         }
     214          28 :         else if(server_supports(feat, ":forceproto=2:"))
     215             :         {
     216           2 :                 logp("Server is forcing protocol 2\n");
     217           4 :                 if(get_protocol(confs)!=PROTO_AUTO
     218           2 :                   && get_protocol(confs)!=PROTO_2)
     219             :                 {
     220             :                         logp("But client has set protocol=%d!\n",
     221           1 :                                 get_protocol(confs));
     222           1 :                         goto end;
     223             :                 }
     224           1 :                 set_protocol(confs, PROTO_2);
     225             :         }
     226             : 
     227          34 :         if(server_supports(feat, ":msg:"))
     228             :         {
     229           1 :                 set_int(confs[OPT_MESSAGE], 1);
     230           1 :                 if(asfd->write_str(asfd, CMD_GEN, "msg"))
     231             :                         goto end;
     232             :         }
     233             : 
     234             : #ifndef RS_DEFAULT_STRONG_LEN
     235             :         if(server_supports(feat, ":rshash=blake2:"))
     236             :         {
     237             :                 set_e_rshash(confs[OPT_RSHASH], RSHASH_BLAKE2);
     238             :                 // Send choice to server.
     239             :                 if(asfd->write_str(asfd, CMD_GEN, "rshash=blake2"))
     240             :                         goto end;
     241             :         }
     242             :         else
     243             : #endif
     244          17 :                 set_e_rshash(confs[OPT_RSHASH], RSHASH_MD4);
     245             : 
     246          34 :         if(asfd->write_str(asfd, CMD_GEN, "extra_comms_end")
     247          17 :           || asfd_read_expect(asfd, CMD_GEN, "extra_comms_end ok"))
     248             :         {
     249           1 :                 logp("Problem requesting extra_comms_end\n");
     250           1 :                 goto end;
     251             :         }
     252             : 
     253             :         ret=0;
     254             : end:
     255          25 :         free_w(&feat);
     256          25 :         return ret;
     257             : }

Generated by: LCOV version 1.10