Beispiel #1
0
static void get_wbuf_from_scan(struct iobuf *wbuf, struct slist *flist)
{
	struct sbuf *sb=flist->head;
	if(!sb) return;
	if(!(sb->flags & SBUF_SENT_STAT))
	{
		iobuf_copy(wbuf, &sb->attr);
		sb->flags |= SBUF_SENT_STAT;
	}
	else if(!(sb->flags & SBUF_SENT_PATH))
	{
		iobuf_copy(wbuf, &sb->path);
		sb->flags |= SBUF_SENT_PATH;
	}
	else if(sb->link.buf && !(sb->flags & SBUF_SENT_LINK))
	{
		iobuf_copy(wbuf, &sb->link);
		sb->flags |= SBUF_SENT_LINK;
	}
	else
	{
		flist->head=flist->head->next;
		sbuf_free(&sb);
		if(flist->head)
		{
			// Go ahead and get the next one from the list.
			get_wbuf_from_scan(wbuf, flist);
		}
		else
		{
			flist->tail=NULL;
			iobuf_from_str(wbuf, CMD_GEN, (char *)"scan_end");
		}
	}
}
Beispiel #2
0
static int do_sbufl_fill_from_file(struct sbuf *sb, FILE *fp, gzFile zp,
	int phase1, struct cntr *cntr)
{
	int ars;
	struct iobuf rbuf;
	//free_sbufl(sb);
	iobuf_init(&rbuf);
	if((ars=read_stat(NULL /* no async */,
		&rbuf, fp, zp, sb, cntr))) return ars;
	if((ars=read_fp(fp, zp, &rbuf))) return ars;
	iobuf_copy(&sb->path, &rbuf);
	if(sbuf_is_link(sb))
	{
		if((ars=read_fp(fp, zp, &rbuf))) return ars;
		iobuf_copy(&sb->link, &rbuf);
		if(!cmd_is_link(rbuf.cmd))
			return unexpected(&rbuf, __func__);
	}
	else if(!phase1 && sbuf_is_filedata(sb))
	{
		if((ars=read_fp(fp, zp, &rbuf))) return ars;
		iobuf_copy(&(sb->burp1->endfile), &rbuf);
		if(!cmd_is_endfile(rbuf.cmd))
			return unexpected(&rbuf, __func__);
	}
	return 0;
}
Beispiel #3
0
static int read_stat(struct asfd *asfd, struct iobuf *rbuf, FILE *fp,
	gzFile zp, struct sbuf *sb, struct cntr *cntr)
{
	while(1)
	{
		iobuf_free_content(rbuf);
		if(fp || zp)
		{
			int asr;
			if((asr=read_fp(fp, zp, rbuf)))
			{
				//logp("read_fp returned: %d\n", asr);
				return asr;
			}
			if(rbuf->buf[rbuf->len]=='\n')
				rbuf->buf[rbuf->len]='\0';
		}
		else
		{
			if(asfd->read(asfd))
			{
				break;
			}
			if(rbuf->cmd==CMD_WARNING)
			{
				logp("WARNING: %s\n", rbuf->buf);
				cntr_add(cntr, rbuf->cmd, 0);
				continue;
			}
		}
		if(rbuf->cmd==CMD_DATAPTH)
		{
			iobuf_copy(&(sb->burp1->datapth), rbuf);
			rbuf->buf=NULL;
		}
		else if(rbuf->cmd==CMD_ATTRIBS)
		{
			iobuf_copy(&sb->attr, rbuf);
			rbuf->buf=NULL;
			attribs_decode(sb);

			return 0;
		}
		else if((rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "backupend"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "restoreend"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "phase1end"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "backupphase2"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "estimateend")))
		{
			iobuf_free_content(rbuf);
			return 1;
		}
		else
			return unexpected(rbuf, __func__);
	}
	iobuf_free_content(rbuf);
	return -1;
}
Beispiel #4
0
// Return 1 if there is still stuff needing to be sent.
static int do_stuff_to_send(struct asfd *asfd,
	struct sbuf *p1b, char **last_requested)
{
	static struct iobuf wbuf;
	if(p1b->flags & SBUFL_SEND_DATAPTH)
	{
		iobuf_copy(&wbuf, &p1b->burp1->datapth);
		if(asfd->append_all_to_write_buffer(asfd, &wbuf))
			return 1;
		p1b->flags &= ~SBUFL_SEND_DATAPTH;
	}
	if(p1b->flags & SBUFL_SEND_STAT)
	{
		iobuf_copy(&wbuf, &p1b->attr);
		if(asfd->append_all_to_write_buffer(asfd, &wbuf))
			return 1;
		p1b->flags &= ~SBUFL_SEND_STAT;
	}
	if(p1b->flags & SBUFL_SEND_PATH)
	{
		iobuf_copy(&wbuf, &p1b->path);
		if(asfd->append_all_to_write_buffer(asfd, &wbuf))
			return 1;
		p1b->flags &= ~SBUFL_SEND_PATH;
		if(*last_requested) free(*last_requested);
		if(!(*last_requested=strdup_w(p1b->path.buf, __func__)))
			return -1;
	}
	if(p1b->burp1->sigjob && !(p1b->flags & SBUFL_SEND_ENDOFSIG))
	{
		rs_result sigresult;

		sigresult=rs_async(p1b->burp1->sigjob, &(p1b->burp1->rsbuf),
			p1b->burp1->infb, p1b->burp1->outfb);

		if(sigresult==RS_DONE)
		{
			p1b->flags |= SBUFL_SEND_ENDOFSIG;
		}
		else if(sigresult==RS_BLOCKED || sigresult==RS_RUNNING)
		{
			// keep going round the loop.
			return 1;
		}
		else
		{
			logp("error in rs_async: %d\n", sigresult);
			return -1;
		}
	}
	if(p1b->flags & SBUFL_SEND_ENDOFSIG)
	{
		iobuf_from_str(&wbuf, CMD_END_FILE, (char *)"endfile");
		if(asfd->append_all_to_write_buffer(asfd, &wbuf)) return 1;
		p1b->flags &= ~SBUFL_SEND_ENDOFSIG;
	}
	return 0;
}
Beispiel #5
0
static void get_wbuf_from_files(struct iobuf *wbuf, struct slist *slist,
	struct manios *manios, uint8_t *end_flags, uint64_t *file_no)
{
	struct sbuf *sb=slist->last_requested;
	if(!sb)
	{
		if(!manios->phase1 && !((*end_flags)&END_REQUESTS))
		{
			iobuf_from_str(wbuf, CMD_GEN, (char *)"requests_end");
			(*end_flags)|=END_REQUESTS;
		}
		return;
	}

	if(sb->flags & SBUF_SENT_PATH || !(sb->flags & SBUF_NEED_DATA))
	{
		slist->last_requested=sb->next;
		return;
	}

	// Only need to request the path at this stage.
	iobuf_copy(wbuf, &sb->path);
	sb->flags |= SBUF_SENT_PATH;
	sb->protocol2->index=(*file_no)++;
}
Beispiel #6
0
static void get_wbuf_from_files(struct iobuf *wbuf, struct slist *slist, struct manio *p1manio, int *requests_end)
{
	static uint64_t file_no=1;
	struct sbuf *sb=slist->last_requested;
	if(!sb)
	{
		if(manio_closed(p1manio) && !*requests_end)
		{
			iobuf_from_str(wbuf, CMD_GEN, (char *)"requests_end");
			*requests_end=1;
		}
		return;
	}

	if(sb->flags & SBUF_SENT_PATH || !(sb->flags & SBUF_NEED_DATA))
	{
		slist->last_requested=sb->next;
		return;
	}

	// Only need to request the path at this stage.
	iobuf_copy(wbuf, &sb->path);
	sb->flags |= SBUF_SENT_PATH;
	sb->burp2->index=file_no++;
}
Beispiel #7
0
static int do_sbufl_fill_from_net(struct sbuf *sb, struct asfd *asfd,
	struct cntr *cntr)
{
	int ars;
	static struct iobuf *rbuf=NULL;
	rbuf=asfd->rbuf;
	iobuf_free_content(rbuf);
	if((ars=read_stat(asfd, rbuf, NULL, NULL, sb, cntr))
	  || (ars=asfd->read(asfd))) return ars;
	iobuf_copy(&sb->path, rbuf);
	rbuf->buf=NULL;
	if(sbuf_is_link(sb))
	{
		if((ars=asfd->read(asfd))) return ars;
		iobuf_copy(&sb->link, rbuf);
		rbuf->buf=NULL;
		if(!cmd_is_link(rbuf->cmd))
			return unexpected(rbuf, __func__);
	}
	return 0;
}
Beispiel #8
0
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
	struct sbuf *rb, FILE *p2fp, struct conf *cconf, char **last_requested)
{
	static char *cp=NULL;
	static struct iobuf *rbuf;
	rbuf=asfd->rbuf;
	// Finished the file.
	// Write it to the phase2 file, and free the buffers.

	if(close_fp(&(rb->burp1->fp)))
	{
		logp("error closing delta for %s in receive\n", rb->path);
		goto error;
	}
	if(gzclose_fp(&(rb->burp1->zp)))
	{
		logp("error gzclosing delta for %s in receive\n", rb->path);
		goto error;
	}
	iobuf_copy(&rb->burp1->endfile, rbuf);
	rbuf->buf=NULL;
	if(rb->flags & SBUFL_RECV_DELTA && finish_delta(sdirs, rb))
		goto error;

	if(sbufl_to_manifest(rb, p2fp, NULL))
		goto error;

	if(rb->flags & SBUFL_RECV_DELTA)
		cntr_add_changed(cconf->cntr, rb->path.cmd);
	else
		cntr_add(cconf->cntr, rb->path.cmd, 0);

	if(*last_requested && !strcmp(rb->path.buf, *last_requested))
	{
		free(*last_requested);
		*last_requested=NULL;
	}

	cp=strchr(rb->burp1->endfile.buf, ':');
	if(rb->burp1->endfile.buf)
		cntr_add_bytes(cconf->cntr,
			strtoull(rb->burp1->endfile.buf, NULL, 10));
	if(cp)
	{
		// checksum stuff goes here
	}

	sbuf_free_content(rb);
	return 0;
error:
	sbuf_free_content(rb);
	return -1;
}
Beispiel #9
0
static int add_to_file_requests(struct slist *slist, struct iobuf *rbuf,
	struct conf *conf)
{
	static uint64_t file_no=1;
	struct sbuf *sb;

	if(!(sb=sbuf_alloc(conf))) return -1;

	iobuf_copy(&sb->path, rbuf);
	rbuf->buf=NULL;
	// Give it a number to simplify tracking.
	sb->burp2->index=file_no++;
	slist_add_sbuf(slist, sb);

	return 0;
}
Beispiel #10
0
static int parse_rbuf(struct asfd *asfd, struct sbuf *sb,
	BFILE *bfd, size_t *datalen, struct conf *conf)
{
	static struct iobuf *rbuf;
	rbuf=asfd->rbuf;
	//logp("now: %c:%s\n", rbuf->cmd, rbuf->buf);
	if(rbuf->cmd==CMD_DATAPTH)
	{
		iobuf_copy(&(sb->burp1->datapth), rbuf);
		rbuf->buf=NULL;
	}
	else if(rbuf->cmd==CMD_ATTRIBS)
	{
		// Ignore the stat data - we will fill it
		// in again. Some time may have passed by now,
		// and it is best to make it as fresh as
		// possible.
	}
	else if(rbuf->cmd==CMD_FILE
	  || rbuf->cmd==CMD_ENC_FILE
	  || rbuf->cmd==CMD_METADATA
	  || rbuf->cmd==CMD_ENC_METADATA
	  || rbuf->cmd==CMD_VSS
	  || rbuf->cmd==CMD_ENC_VSS
	  || rbuf->cmd==CMD_VSS_T
	  || rbuf->cmd==CMD_ENC_VSS_T
	  || rbuf->cmd==CMD_EFS_FILE)
	{
		if(deal_with_data(asfd, sb, bfd, datalen, conf))
			return -1;
	}
	else if(rbuf->cmd==CMD_WARNING)
	{
		cntr_add(conf->cntr, rbuf->cmd, 0);
	}
	else
	{
		iobuf_log_unexpected(rbuf, __func__);
		return -1;
	}
	return 0;
}
Beispiel #11
0
int restore_sbuf_protocol2(struct asfd *asfd, struct sbuf *sb, enum action act,
	struct cntr *cntr, struct sbuf *need_data)
{
	if(asfd->write(asfd, &sb->attr)
	  || asfd->write(asfd, &sb->path))
		return -1;
	if(sbuf_is_link(sb)
	  && asfd->write(asfd, &sb->link))
		return -1;

	if(sb->protocol2->bstart)
	{
		// This will restore directory data on Windows.
		struct blk *b=NULL;
		struct blk *n=NULL;
		b=sb->protocol2->bstart;
		while(b)
		{
			if(send_data(asfd, b, act, need_data, cntr))
				return -1;
			n=b->next;
			blk_free(&b);
			b=n;
		}
		sb->protocol2->bstart=sb->protocol2->bend=NULL;
	}

	if(sbuf_is_filedata(sb))
	{
		if(need_data)
		{
			iobuf_copy(&need_data->path, &sb->path);
			sb->path.buf=NULL;
		}
	}
	else
		cntr_add(cntr, sb->path.cmd, 0);
	return 0;
}
Beispiel #12
0
static int get_wbuf_from_blks(struct iobuf *wbuf,
	struct slist *slist, uint8_t *end_flags)
{
	struct sbuf *sb=slist->blks_to_send;

	if(!sb)
	{
		if((*end_flags)&END_REQUESTS && !((*end_flags)&END_SIGS))
		{
			iobuf_from_str(wbuf, CMD_GEN, (char *)"sigs_end");
			(*end_flags)|=END_SIGS;
		}
		return 0;
	}
	if(!sb->protocol2->bsighead) return 0;

	if(!(sb->flags & SBUF_SENT_STAT))
	{
		iobuf_copy(wbuf, &sb->attr);
		wbuf->cmd=CMD_ATTRIBS_SIGS; // hack
		sb->flags |= SBUF_SENT_STAT;
		return 0;
	}

	if(iobuf_from_blk_data(wbuf, sb->protocol2->bsighead)) return -1;

	// Move on.
	if(sb->protocol2->bsighead==sb->protocol2->bend)
	{
		slist->blks_to_send=sb->next;
		sb->protocol2->bsighead=sb->protocol2->bstart;
	}
	else
	{
		sb->protocol2->bsighead=sb->protocol2->bsighead->next;
	}
	return 0;
}
Beispiel #13
0
static void get_wbuf_from_blks(struct iobuf *wbuf,
	struct slist *slist, int requests_end, int *sigs_end)
{
	struct sbuf *sb=slist->blks_to_send;

	if(!sb)
	{
		if(requests_end && !*sigs_end)
		{
			iobuf_from_str(wbuf, CMD_GEN, (char *)"sigs_end");
			*sigs_end=1;
		}
		return;
	}
	if(!sb->burp2->bsighead) return;

	if(!(sb->flags & SBUF_SENT_STAT))
	{
		iobuf_copy(wbuf, &sb->attr);
		wbuf->cmd=CMD_ATTRIBS_SIGS; // hack
		sb->flags |= SBUF_SENT_STAT;
		return;
	}

	iobuf_from_blk_data(wbuf, sb->burp2->bsighead);

	// Move on.
	if(sb->burp2->bsighead==sb->burp2->bend)
	{
		slist->blks_to_send=sb->next;
		sb->burp2->bsighead=sb->burp2->bstart;
	}
	else
	{
		sb->burp2->bsighead=sb->burp2->bsighead->next;
	}
}
Beispiel #14
0
static int deal_with_read(struct iobuf *rbuf,
	struct slist *slist, struct blist *blist, struct conf *conf,
	int *sigs_end, int *backup_end, struct dpth *dpth)
{
	int ret=0;
	static struct sbuf *inew=NULL;

	if(!inew && !(inew=sbuf_alloc(conf))) goto error;

	switch(rbuf->cmd)
	{
		/* Incoming block data. */
		case CMD_DATA:
			if(add_data_to_store(conf, blist, rbuf, dpth))
				goto error;
			goto end;

		/* Incoming block signatures. */
		case CMD_ATTRIBS_SIGS:
			// New set of stuff incoming. Clean up.
			if(inew->attr.buf) free(inew->attr.buf);
			iobuf_copy(&inew->attr, rbuf);
			inew->burp2->index=decode_file_no(&inew->attr);
			rbuf->buf=NULL;

			// Need to go through slist to find the matching
			// entry.
			if(set_up_for_sig_info(slist, blist, inew)) goto error;
			return 0;
		case CMD_SIG:
			if(add_to_sig_list(slist, blist,
				rbuf, dpth, conf))
					goto error;
			goto end;

		/* Incoming control/message stuff. */
		case CMD_WARNING:
			logp("WARNING: %s\n", rbuf);
			cntr_add(conf->cntr, rbuf->cmd, 0);
			goto end;
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "sigs_end"))
			{
				*sigs_end=1;
				goto end;
			}
			else if(!strcmp(rbuf->buf, "backup_end"))
			{
				*backup_end=1;
				goto end;
			}
			break;
	}

	iobuf_log_unexpected(rbuf, __func__);
error:
	ret=-1;
	sbuf_free(&inew);
end:
	if(rbuf->buf) { free(rbuf->buf); rbuf->buf=NULL; }
	return ret;
}
Beispiel #15
0
/****************
 * Decrypt the data, specified by ED with the key DEK.
 */
int
decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
{
  decode_filter_ctx_t dfx;
  byte *p;
  int rc=0, c, i;
  byte temp[32];
  unsigned blocksize;
  unsigned nprefix;

  dfx = xtrycalloc (1, sizeof *dfx);
  if (!dfx)
    return gpg_error_from_syserror ();
  dfx->refcount = 1;

  if ( opt.verbose && !dek->algo_info_printed )
    {
      if (!openpgp_cipher_test_algo (dek->algo))
        log_info (_("%s encrypted data\n"),
                  openpgp_cipher_algo_name (dek->algo));
      else
        log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
      dek->algo_info_printed = 1;
    }

  {
    char buf[20];

    snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo);
    write_status_text (STATUS_DECRYPTION_INFO, buf);
  }

  if (opt.show_session_key)
    {
      char numbuf[25];
      char *hexbuf;

      snprintf (numbuf, sizeof numbuf, "%d:", dek->algo);
      hexbuf = bin2hex (dek->key, dek->keylen, NULL);
      if (!hexbuf)
        {
          rc = gpg_error_from_syserror ();
          goto leave;
        }
      log_info ("session key: '%s%s'\n", numbuf, hexbuf);
      write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL);
      xfree (hexbuf);
    }

  rc = openpgp_cipher_test_algo (dek->algo);
  if (rc)
    goto leave;
  blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
  if ( !blocksize || blocksize > 16 )
    log_fatal ("unsupported blocksize %u\n", blocksize );
  nprefix = blocksize;
  if ( ed->len && ed->len < (nprefix+2) )
    {
       /* An invalid message.  We can't check that during parsing
          because we may not know the used cipher then.  */
      rc = gpg_error (GPG_ERR_INV_PACKET);
      goto leave;
    }

  if ( ed->mdc_method )
    {
      if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
        BUG ();
      if ( DBG_HASHING )
        gcry_md_debug (dfx->mdc_hash, "checkmdc");
    }

  rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
			    GCRY_CIPHER_MODE_CFB,
			    (GCRY_CIPHER_SECURE
			     | ((ed->mdc_method || dek->algo >= 100)?
				0 : GCRY_CIPHER_ENABLE_SYNC)));
  if (rc)
    {
      /* We should never get an error here cause we already checked
       * that the algorithm is available.  */
      BUG();
    }


  /* log_hexdump( "thekey", dek->key, dek->keylen );*/
  rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
  if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
    {
      log_info(_("WARNING: message was encrypted with"
                 " a weak key in the symmetric cipher.\n"));
      rc=0;
    }
  else if( rc )
    {
      log_error("key setup failed: %s\n", gpg_strerror (rc) );
      goto leave;
    }

  if (!ed->buf)
    {
      log_error(_("problem handling encrypted packet\n"));
      goto leave;
    }

  gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);

  if ( ed->len )
    {
      for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
        {
          if ( (c=iobuf_get(ed->buf)) == -1 )
            break;
          else
            temp[i] = c;
        }
    }
  else
    {
      for (i=0; i < (nprefix+2); i++ )
        if ( (c=iobuf_get(ed->buf)) == -1 )
          break;
        else
          temp[i] = c;
    }

  gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
  gcry_cipher_sync (dfx->cipher_hd);
  p = temp;
  /* log_hexdump( "prefix", temp, nprefix+2 ); */
  if (dek->symmetric
      && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
    {
      rc = gpg_error (GPG_ERR_BAD_KEY);
      goto leave;
    }

  if ( dfx->mdc_hash )
    gcry_md_write (dfx->mdc_hash, temp, nprefix+2);

  dfx->refcount++;
  dfx->partial = ed->is_partial;
  dfx->length = ed->len;
  if ( ed->mdc_method )
    iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
  else
    iobuf_push_filter ( ed->buf, decode_filter, dfx );

  if (opt.unwrap_encryption)
    {
      char *filename;
      estream_t fp;
      rc = get_output_file ("", 0, ed->buf, &filename, &fp);
      if (! rc)
        {
          iobuf_t output = iobuf_esopen (fp, "w", 0);
          armor_filter_context_t *afx = NULL;

          if (opt.armor)
            {
              afx = new_armor_context ();
              push_armor_filter (afx, output);
            }

          iobuf_copy (output, ed->buf);
          if ((rc = iobuf_error (ed->buf)))
            log_error (_("error reading '%s': %s\n"),
                       filename, gpg_strerror (rc));
          else if ((rc = iobuf_error (output)))
            log_error (_("error writing '%s': %s\n"),
                       filename, gpg_strerror (rc));

          iobuf_close (output);
          if (afx)
            release_armor_context (afx);
        }
    }
  else
    proc_packets (ctrl, procctx, ed->buf );

  ed->buf = NULL;
  if (dfx->eof_seen > 1 )
    rc = gpg_error (GPG_ERR_INV_PACKET);
  else if ( ed->mdc_method )
    {
      /* We used to let parse-packet.c handle the MDC packet but this
         turned out to be a problem with compressed packets: With old
         style packets there is no length information available and
         the decompressor uses an implicit end.  However we can't know
         this implicit end beforehand (:-) and thus may feed the
         decompressor with more bytes than actually needed.  It would
         be possible to unread the extra bytes but due to our weird
         iobuf system any unread is non reliable due to filters
         already popped off.  The easy and sane solution is to care
         about the MDC packet only here and never pass it to the
         packet parser.  Fortunatley the OpenPGP spec requires a
         strict format for the MDC packet so that we know that 22
         bytes are appended.  */
      int datalen = gcry_md_get_algo_dlen (ed->mdc_method);

      log_assert (dfx->cipher_hd);
      log_assert (dfx->mdc_hash);
      gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
      gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
      gcry_md_final (dfx->mdc_hash);

      if (   dfx->defer[0] != '\xd3'
          || dfx->defer[1] != '\x14'
          || datalen != 20
          || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->defer+2, datalen))
        rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
      /* log_printhex("MDC message:", dfx->defer, 22); */
      /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
    }


 leave:
  release_dfx_context (dfx);
  return rc;
}
Beispiel #16
0
int do_list_client(struct asfd *asfd, enum action act, struct conf **confs)
{
	int ret=-1;
	char msg[512]="";
	struct sbuf *sb=NULL;
	struct iobuf *rbuf=asfd->rbuf;
	const char *backup=get_string(confs[OPT_BACKUP]);
	const char *backup2=get_string(confs[OPT_BACKUP2]);
	const char *browsedir=get_string(confs[OPT_BROWSEDIR]);
	const char *regex=get_string(confs[OPT_REGEX]);
//logp("in do_list\n");

	switch(act)
	{
		case ACTION_LIST:
		case ACTION_LIST_LONG:
			if(browsedir && regex)
			{
				logp("You cannot specify both a directory and a regular expression when listing.\n");
				goto end;
			}
			if(browsedir)
				snprintf(msg, sizeof(msg), "listb %s:%s",
					backup?backup:"", browsedir);
			else
				snprintf(msg, sizeof(msg), "list %s:%s",
					backup?backup:"", regex?regex:"");
			break;
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			snprintf(msg, sizeof(msg), "diff %s:%s",
				backup?backup:"", backup2?backup2:"");
			break;
		default:
			logp("unknown action %d\n", act);
			goto end;
	}
	if(asfd->write_str(asfd, CMD_GEN, msg)
	  || asfd_read_expect(asfd, CMD_GEN, "ok"))
		goto end;

	if(!(sb=sbuf_alloc(get_protocol(confs)))) goto end;
	iobuf_init(&sb->path);
	iobuf_init(&sb->link);
	iobuf_init(&sb->attr);

	// This should probably should use the sbuf stuff.
	while(1)
	{
		sbuf_free_content(sb);

		iobuf_free_content(rbuf);
		if(asfd->read(asfd)) break;
		if(rbuf->cmd==CMD_MESSAGE)
		{
			printf("%s\n", rbuf->buf);
			if(!strcmp(rbuf->buf, "no backups"))
				ret=0;
			goto end;
		}
		else if(rbuf->cmd==CMD_TIMESTAMP)
		{
			// A backup timestamp, just print it.
			printf("Backup: %s\n", rbuf->buf);
			if(browsedir)
				printf("Listing directory: %s\n",
				       browsedir);
			if(regex)
				printf("With regex: %s\n",
				       regex);
			continue;
		}
		else if(rbuf->cmd!=CMD_ATTRIBS)
		{
			iobuf_log_unexpected(rbuf, __func__);
			goto end;
		}
		iobuf_copy(&sb->attr, rbuf);
		iobuf_init(rbuf);

		attribs_decode(sb);

		if(asfd->read(asfd))
		{
			logp("got stat without an object\n");
			goto end;
		}
		iobuf_copy(&sb->path, rbuf);
		iobuf_init(rbuf);

		if(sb->path.cmd==CMD_DIRECTORY
			|| sb->path.cmd==CMD_FILE
			|| sb->path.cmd==CMD_ENC_FILE
			|| sb->path.cmd==CMD_EFS_FILE
			|| sb->path.cmd==CMD_SPECIAL)
		{
			list_item(act, sb);
		}
		else if(cmd_is_link(sb->path.cmd)) // symlink or hardlink
		{
			if(asfd->read(asfd)
			  || rbuf->cmd!=sb->path.cmd)
			{
				logp("could not get link %s\n",
					iobuf_to_printable(&sb->path));
				goto end;
			}
			iobuf_copy(&sb->link, rbuf);
			iobuf_init(rbuf);
			list_item(act, sb);
		}
		else
		{
			logp("unlistable %s\n", iobuf_to_printable(&sb->path));
		}
	}

	ret=0;
end:
	sbuf_free(&sb);
	if(!ret) logp("List finished ok\n");
	return ret;
}
Beispiel #17
0
static int process_changed_file(struct asfd *asfd,
	struct sdirs *sdirs, struct conf *cconf,
	struct sbuf *cb, struct sbuf *p1b,
	const char *adir)
{
	size_t blocklen=0;
	char *curpath=NULL;
	//logp("need to process changed file: %s (%s)\n", cb->path, cb->datapth);

	// Move datapth onto p1b.
	iobuf_copy(&p1b->burp1->datapth, &cb->burp1->datapth);
	cb->burp1->datapth.buf=NULL;

	if(!(curpath=prepend_s(adir, p1b->burp1->datapth.buf)))
	{
		log_out_of_memory(__func__);
		return -1;
	}
	if(dpthl_is_compressed(cb->compression, curpath))
		p1b->burp1->sigzp=gzopen_file(curpath, "rb");
	else
		p1b->burp1->sigfp=open_file(curpath, "rb");
	if(!p1b->burp1->sigzp && !p1b->burp1->sigfp)
	{
		logp("could not open %s: %s\n", curpath, strerror(errno));
		free(curpath);
		return -1;
	}
	free(curpath);

	blocklen=get_librsync_block_len(cb->burp1->endfile.buf);
	if(!(p1b->burp1->sigjob=rs_sig_begin(blocklen, RS_DEFAULT_STRONG_LEN)))
	{
		logp("could not start signature job.\n");
		return -1;
	}
	//logp("sig begin: %s\n", p1b->burp1->datapth.buf);
	if(!(p1b->burp1->infb=rs_filebuf_new(asfd, NULL,
		p1b->burp1->sigfp, p1b->burp1->sigzp,
		-1, blocklen, -1, cconf->cntr)))
	{
		logp("could not rs_filebuf_new for infb.\n");
		return -1;
	}
	if(!(p1b->burp1->outfb=rs_filebuf_new(asfd, NULL, NULL, NULL,
		asfd->fd, ASYNC_BUF_LEN, -1, cconf->cntr)))
	{
		logp("could not rs_filebuf_new for in_outfb.\n");
		return -1;
	}

	// Flag the things that need to be sent (to the client)
	p1b->flags |= SBUFL_SEND_DATAPTH;
	p1b->flags |= SBUFL_SEND_STAT;
	p1b->flags |= SBUFL_SEND_PATH;

	//logp("sending sig for %s\n", p1b->path);
	//logp("(%s)\n", p1b->datapth);

	return 0;
}
Beispiel #18
0
/** Copy all the data from an \c ibuf to an \c obuf, and flush the
    \c obuf after writing is completed. */
int iobuf_copyflush(ibuf* in, obuf* out)
{
  if (!iobuf_copy(in, out)) return 0;
  return obuf_flush(out);
}
Beispiel #19
0
// returns 1 for finished ok.
static int do_stuff_to_receive(struct asfd *asfd,
	struct sdirs *sdirs, struct conf *cconf,
	struct sbuf *rb, FILE *p2fp, struct dpthl *dpthl, char **last_requested)
{
	struct iobuf *rbuf=asfd->rbuf;

	iobuf_free_content(rbuf);
	// This also attempts to write anything in the write buffer.
	if(asfd->as->rw(asfd->as))
	{
		logp("error in async_rw\n");
		return -1;
	}

	if(!rbuf->buf) return 0;

	if(rbuf->cmd==CMD_WARNING)
	{
		logp("WARNING: %s\n", rbuf->buf);
		cntr_add(cconf->cntr, rbuf->cmd, 0);
	}
	else if(rb->burp1->fp || rb->burp1->zp)
	{
		// Currently writing a file (or meta data)
		if(rbuf->cmd==CMD_APPEND)
		{
			if(deal_with_receive_append(asfd, rb, cconf))
				goto error;
		}
		else if(rbuf->cmd==CMD_END_FILE)
		{
			if(deal_with_receive_end_file(asfd, sdirs, rb, p2fp,
				cconf, last_requested)) goto error;
		}
		else
		{
			iobuf_log_unexpected(rbuf, __func__);
			goto error;
		}
	}
	// Otherwise, expecting to be told of a file to save.
	else if(rbuf->cmd==CMD_DATAPTH)
	{
		iobuf_copy(&rb->burp1->datapth, rbuf);
		rbuf->buf=NULL;
	}
	else if(rbuf->cmd==CMD_ATTRIBS)
	{
		iobuf_copy(&rb->attr, rbuf);
		rbuf->buf=NULL;
	}
	else if(filedata(rbuf->cmd))
	{
		iobuf_copy(&rb->path, rbuf);
		rbuf->buf=NULL;

		if(rb->burp1->datapth.buf)
		{
			// Receiving a delta.
			if(start_to_receive_delta(sdirs, cconf, rb))
			{
				logp("error in start_to_receive_delta\n");
				goto error;
			}
		}
		else
		{
			// Receiving a whole new file.
			if(start_to_receive_new_file(asfd,
				sdirs, cconf, rb, dpthl))
			{
				logp("error in start_to_receive_new_file\n");
				goto error;
			}
		}
	}
	else if(rbuf->cmd==CMD_GEN
	  && !strcmp(rbuf->buf, "okbackupphase2end"))
		goto end_phase2;
	else if(rbuf->cmd==CMD_INTERRUPT)
	{
		// Interrupt - forget about the last requested file
		// if it matches. Otherwise, we can get stuck on the
		// select in the async stuff, waiting for something
		// that will never arrive.
		if(*last_requested && !strcmp(rbuf->buf, *last_requested))
		{
			free(*last_requested);
			*last_requested=NULL;
		}
	}
	else
	{
		iobuf_log_unexpected(rbuf, __func__);
		goto error;
	}

	return 0;
end_phase2:
	return 1;
error:
	return -1;
}
Beispiel #20
0
void iobuf_move(struct iobuf *dst, struct iobuf *src)
{
	iobuf_copy(dst, src);
	src->buf=NULL;
}
Beispiel #21
0
// Return 1 if there is still stuff needing to be sent.
// FIX THIS: lots of repeated code.
static int do_stuff_to_send(struct asfd *asfd,
	struct sbuf *p1b, char **last_requested)
{
	static struct iobuf wbuf;
	if(p1b->flags & SBUF_SEND_DATAPTH)
	{
		iobuf_copy(&wbuf, &p1b->protocol1->datapth);
		switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
		{
			case APPEND_OK: break;
			case APPEND_BLOCKED: return 1;
			default: return -1;
		}
		p1b->flags &= ~SBUF_SEND_DATAPTH;
	}
	if(p1b->flags & SBUF_SEND_STAT)
	{
		iobuf_copy(&wbuf, &p1b->attr);
		switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
		{
			case APPEND_OK: break;
			case APPEND_BLOCKED: return 1;
			default: return -1;
		}
		p1b->flags &= ~SBUF_SEND_STAT;
	}
	if(p1b->flags & SBUF_SEND_PATH)
	{
		iobuf_copy(&wbuf, &p1b->path);
		switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
		{
			case APPEND_OK: break;
			case APPEND_BLOCKED: return 1;
			default: return -1;
		}
		p1b->flags &= ~SBUF_SEND_PATH;
		free_w(last_requested);
		if(!(*last_requested=strdup_w(p1b->path.buf, __func__)))
			return -1;
	}
	if(p1b->protocol1->sigjob && !(p1b->flags & SBUF_SEND_ENDOFSIG))
	{
		rs_result sigresult;

		switch((sigresult=rs_async(p1b->protocol1->sigjob,
			&(p1b->protocol1->rsbuf),
			p1b->protocol1->infb, p1b->protocol1->outfb)))
		{
			case RS_DONE:
				p1b->flags |= SBUF_SEND_ENDOFSIG;
				break;
			case RS_BLOCKED:
			case RS_RUNNING:
				// keep going round the loop.
				return 1;
			default:
				logp("error in rs_async: %d\n", sigresult);
				return -1;
		}
	}
	if(p1b->flags & SBUF_SEND_ENDOFSIG)
	{
		iobuf_from_str(&wbuf, CMD_END_FILE, (char *)"endfile");
		switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
		{
			case APPEND_OK: break;
			case APPEND_BLOCKED: return 1;
			default: return -1;
		}
		p1b->flags &= ~SBUF_SEND_ENDOFSIG;
	}
	return 0;
}
Beispiel #22
0
int do_list_client(struct asfd *asfd,
	struct conf *conf, enum action act, int json)
{
	int ret=-1;
	char msg[512]="";
	char *dpth=NULL;
	struct sbuf *sb=NULL;
	int json_started=0;
	struct iobuf *rbuf=asfd->rbuf;
//logp("in do_list\n");

	if(conf->browsedir)
	  snprintf(msg, sizeof(msg), "listb %s:%s",
		conf->backup?conf->backup:"", conf->browsedir);
	else
	  snprintf(msg, sizeof(msg), "list %s:%s",
		conf->backup?conf->backup:"", conf->regex?conf->regex:"");
	if(asfd->write_str(asfd, CMD_GEN, msg)
	  || asfd->read_expect(asfd, CMD_GEN, "ok"))
		goto end;

	if(!(sb=sbuf_alloc(conf))) goto end;
	iobuf_init(&sb->path);
	iobuf_init(&sb->link);
	iobuf_init(&sb->attr);

	if(json)
	{
		open_tag(0, NULL);
		open_tag(1, "backups");
		json_started++;
	}

	// This should probably should use the sbuf stuff.
	while(1)
	{
		sbuf_free_content(sb);

		iobuf_free_content(rbuf);
		if(asfd->read(asfd)) break;
		if(rbuf->cmd==CMD_TIMESTAMP)
		{
			// A backup timestamp, just print it.
			if(json) json_backup(rbuf->buf, conf);
			else
			{
				printf("Backup: %s\n", rbuf->buf);
				if(conf->browsedir)
					printf("Listing directory: %s\n",
					       conf->browsedir);
				if(conf->regex)
					printf("With regex: %s\n",
					       conf->regex);
			}
			continue;
		}
		else if(rbuf->cmd!=CMD_ATTRIBS)
		{
			iobuf_log_unexpected(rbuf, __func__);
			goto end;
		}
		iobuf_copy(&sb->attr, rbuf);
		iobuf_init(rbuf);

		attribs_decode(sb);

		if(asfd->read(asfd))
		{
			logp("got stat without an object\n");
			goto end;
		}
		iobuf_copy(&sb->path, rbuf);
		iobuf_init(rbuf);

		if(sb->path.cmd==CMD_DIRECTORY
			|| sb->path.cmd==CMD_FILE
			|| sb->path.cmd==CMD_ENC_FILE
			|| sb->path.cmd==CMD_EFS_FILE
			|| sb->path.cmd==CMD_SPECIAL)
		{
			list_item(json, act, sb);
		}
		else if(cmd_is_link(sb->path.cmd)) // symlink or hardlink
		{
			if(asfd->read(asfd)
			  || rbuf->cmd!=sb->path.cmd)
			{
				logp("could not get link %c:%s\n",
					sb->path.cmd, sb->path.buf);
				goto end;
			}
			iobuf_copy(&sb->link, rbuf);
			iobuf_init(rbuf);
			list_item(json, act, sb);
		}
		else
		{
			fprintf(stderr, "unlistable %c:%s\n",
				sb->path.cmd, sb->path.buf?sb->path.buf:"");
		}
	}

	ret=0;
end:
	if(json && json_started) close_tag(0);
	printf("\n");
	iobuf_free_content(&sb->path);
	iobuf_free_content(&sb->link);
	iobuf_free_content(&sb->attr);
	if(dpth) free(dpth);
	sbuf_free(&sb);
	if(!ret) logp("List finished ok\n");
	return ret;
}
Beispiel #23
0
static int deal_with_data(struct asfd *asfd, struct sbuf *sb,
	BFILE *bfd, size_t *datalen, struct conf *conf)
{
	int ret=-1;
	int forget=0;
	FILE *fp=NULL;
	size_t elen=0;
	char *extrameta=NULL;
	unsigned long long bytes=0;

	sb->compression=conf->compression;

	iobuf_copy(&sb->path, asfd->rbuf);
	iobuf_init(asfd->rbuf);

#ifdef HAVE_WIN32
	if(win32_lstat(sb->path.buf, &sb->statp, &sb->winattr))
#else
	if(lstat(sb->path.buf, &sb->statp))
#endif
	{
		logw(asfd, conf, "Path has vanished: %s", sb->path.buf);
		if(forget_file(asfd, sb, conf)) goto error;
		goto end;
	}

	if(size_checks(asfd, sb, conf)) forget++;

	if(!forget)
	{
		sb->compression=in_exclude_comp(conf->excom,
			sb->path.buf, conf->compression);
		if(attribs_encode(sb)) goto error;
		else if(open_file_for_sendl(asfd,
#ifdef HAVE_WIN32
			bfd, NULL,
#else
			NULL, &fp,
#endif
			sb->path.buf, sb->winattr, datalen, conf->atime, conf))
				forget++;
	}

	if(forget)
	{
		if(forget_file(asfd, sb, conf)) goto error;
		goto end;
	}

	if(sb->path.cmd==CMD_METADATA
	  || sb->path.cmd==CMD_ENC_METADATA
	  || sb->path.cmd==CMD_VSS
	  || sb->path.cmd==CMD_ENC_VSS
#ifdef HAVE_WIN32
	  || conf->strip_vss
#endif
	  )
	{
		if(get_extrameta(asfd,
#ifdef HAVE_WIN32
			bfd,
#endif
			sb->path.buf, &sb->statp, &extrameta, &elen,
			sb->winattr, conf, datalen))
		{
			logw(asfd, conf, "Meta data error for %s", sb->path.buf);
			goto end;
		}
		if(extrameta)
		{
#ifdef HAVE_WIN32
			if(conf->strip_vss)
			{
				free(extrameta);
				extrameta=NULL;
				elen=0;
			}
#endif
		}
		else
		{
			logw(asfd, conf,
				"No meta data after all: %s", sb->path.buf);
			goto end;
		}
	}

	if(sb->path.cmd==CMD_FILE
	  && sb->burp1->datapth.buf)
	{
		unsigned long long sentbytes=0;
		// Need to do sig/delta stuff.
		if(asfd->write(asfd, &(sb->burp1->datapth))
		  || asfd->write(asfd, &sb->attr)
		  || asfd->write(asfd, &sb->path)
		  || load_signature_and_send_delta(asfd, bfd, fp,
			&bytes, &sentbytes, conf, *datalen))
		{
			logp("error in sig/delta for %s (%s)\n",
				sb->path.buf, sb->burp1->datapth.buf);
			goto end;
		}
		else
		{
			cntr_add(conf->cntr, CMD_FILE_CHANGED, 1);
			cntr_add_bytes(conf->cntr, bytes);
			cntr_add_sentbytes(conf->cntr, sentbytes);
		}
	}
	else
	{
		//logp("need to send whole file: %s\n", sb.path);
		// send the whole file.

		if((asfd->write(asfd, &sb->attr)
		  || asfd->write(asfd, &sb->path))
		  || send_whole_file_w(asfd, sb, NULL, 0, &bytes,
			conf->encryption_password, conf, sb->compression,
			bfd, fp, extrameta, elen, *datalen))
				goto end;
		else
		{
			cntr_add(conf->cntr, sb->path.cmd, 1);
			cntr_add_bytes(conf->cntr, bytes);
			cntr_add_sentbytes(conf->cntr, bytes);
		}
	}

end:
	ret=0;
error:
#ifdef HAVE_WIN32
	// If using Windows do not close bfd - it needs
	// to stay open to read VSS/file data/VSS.
	// It will get closed either when given a
	// different file path, or when this function
	// exits.
#else
	close_file_for_sendl(NULL, &fp, asfd);
#endif
	sbuf_free_content(sb);
	if(extrameta) free(extrameta);
	return ret;
}