Example #1
0
static int write_all(struct asfd *asfd)
{
	int ret=-1;
	size_t w=0;
	size_t len=0;
	const unsigned char *buf;
	struct iobuf wbuf;

	yajl_gen_get_buf(yajl, &buf, &len);
	while(len)
	{
		w=len;
		if(w>ASYNC_BUF_LEN) w=ASYNC_BUF_LEN;
		iobuf_set(&wbuf, CMD_GEN /* not used */, (char *)buf, w);
		if((ret=asfd->write(asfd, &wbuf)))
			break;
		buf+=w;
		len-=w;
	}
	if(!ret && !pretty_print)
	{
		iobuf_set(&wbuf, CMD_GEN /* not used */, (char *)"\n", 1);
		ret=asfd->write(asfd, &wbuf);
	}

	yajl_gen_clear(yajl);
	return ret;
}
Example #2
0
static void setup_asfds_proto1_stuff(struct asfd *asfd, struct slist *slist)
{
	int r=0; int w=0;
	struct sbuf *s;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_link(s))
		{
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->link);
		}
		else if(sbuf_is_filedata(s))
		{
			struct iobuf wbuf;
			// The string "data" gzipped.
			unsigned char gzipped_data1[10] = {
				0x1f, 0x8b, 0x08, 0, 0,
				0, 0, 0, 0x02, 0x03
			};
			unsigned char gzipped_data2[14] = {
				0x4b, 0x49, 0x2c, 0x49, 0x04, 0x00, 0x63,
				0xf3, 0xf3, 0xad, 0x04, 0x00, 0x00, 0x00
			};
			asfd_assert_write_iobuf(asfd, &w,
				0, &s->protocol1->datapth);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
			if(sbuf_is_encrypted(s))
			{
				// Encrypted files get sent as is.
				asfd_assert_write(asfd, &w, 0, CMD_APPEND,
					"data");
				asfd_assert_write(asfd, &w, 0, CMD_END_FILE,
					"4:8d777f385d3dfec8815d20f7496026dc");
				continue;
			}
			// Protocol1 always sends it gzipped.
			iobuf_set(&wbuf, CMD_APPEND,
				(char *)gzipped_data1, sizeof(gzipped_data1));
			asfd_assert_write_iobuf(asfd, &w, 0, &wbuf);
			iobuf_set(&wbuf, CMD_APPEND,
				(char *)gzipped_data2, sizeof(gzipped_data2));
			asfd_assert_write_iobuf(asfd, &w, 0, &wbuf);
			asfd_assert_write(asfd, &w, 0, CMD_END_FILE,
				"4:8d777f385d3dfec8815d20f7496026dc");
		}
		else
		{
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
		}
	}
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend");
	asfd_mock_read_no_op(asfd, &r, 100);
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend_ok");
}
Example #3
0
File: blk.c Project: vanElden/burp
void blk_to_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
{
	static union { char c[16]; uint64_t v[2]; } buf;
	buf.v[0]=HTOE(blk->index);
	buf.v[1]=HTOE(blk->savepath);
	iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
}
Example #4
0
static DWORD WINAPI write_efs(PBYTE pbData,
	PVOID pvCallbackContext, ULONG ulLength)
{
	struct iobuf wbuf;
	struct winbuf *mybuf=(struct winbuf *)pvCallbackContext;
	(*(mybuf->bytes))+=ulLength;
	if(!MD5_Update(mybuf->md5, pbData, ulLength))
	{
		logp("MD5_Update() failed\n");
		return ERROR_FUNCTION_FAILED;
	}
	iobuf_set(&wbuf, CMD_APPEND, (char *)pbData, (size_t)ulLength);
	if(mybuf->asfd->write(mybuf->asfd, &wbuf))
	{
		return ERROR_FUNCTION_FAILED;
	}
	if(mybuf->quick_read)
	{
		int qr;
		if((qr=do_quick_read(mybuf->asfd,
				mybuf->datapth, mybuf->cntr))<0)
			return ERROR_FUNCTION_FAILED;
		if(qr) // client wants to interrupt
			return ERROR_FUNCTION_FAILED;
	}
	return ERROR_SUCCESS;
}
Example #5
0
static void get_wbuf_from_data(struct conf **confs,
	struct iobuf *wbuf, struct slist *slist, uint8_t end_flags)
{
	struct blk *blk;
	struct blist *blist=slist->blist;

	for(blk=blist->last_sent; blk; blk=blk->next)
	{
		if(blk->requested)
		{
			iobuf_set(wbuf, CMD_DATA, blk->data, blk->length);
			blk->requested=0;
			blist->last_sent=blk;
			cntr_add(get_cntr(confs), CMD_DATA, 1);
			break;
		}
		else
		{
			cntr_add_same(get_cntr(confs), CMD_DATA);
			if(end_flags&END_BLK_REQUESTS)
			{
				// Force onwards when the server has said that
				// there are no more blocks to request.
				blist->last_sent=blk;
				continue;
			}
		}
		if(blk==blist->last_requested) break;
	}
	// Need to free stuff that is no longer needed.
	free_stuff(slist);
}
Example #6
0
static int mock_asfd_assert_write_str(struct asfd *asfd,
	enum cmd wcmd, const char *wsrc)
{
	struct iobuf wbuf;
	iobuf_set(&wbuf, wcmd, (char *)wsrc, strlen(wsrc));
	return do_asfd_assert_write(asfd, &wbuf);
}
Example #7
0
File: blk.c Project: vanElden/burp
void blk_to_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
{
	static union { char c[24]; uint64_t v[3]; } buf;
	buf.v[0]=HTOE(blk->fingerprint);
	memcpy(&buf.c[8], blk->md5sum, 8);
	memcpy(&buf.c[16], blk->md5sum+8, 8);
	iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
}
Example #8
0
static int send_data(struct asfd *asfd, struct blk *blk,
	enum action act, struct sbuf *need_data, struct cntr *cntr)
{
	struct iobuf wbuf;

	switch(act)
	{
		case ACTION_RESTORE:
			iobuf_set(&wbuf, CMD_DATA, blk->data, blk->length);
			if(asfd->write(asfd, &wbuf)) return -1;
			return 0;
		case ACTION_VERIFY:
			// Need to check that the block has the correct
			// checksums.
			switch(blk_verify(blk))
			{
				case 1:
					iobuf_set(&wbuf, CMD_DATA, (char *)"0", 1);
					if(asfd->write(asfd, &wbuf)) return -1;
					cntr_add(cntr, CMD_DATA, 0);
					break; // All OK.
				case 0:
				{
					char msg[256];
					snprintf(msg, sizeof(msg), "Checksum mismatch in block for %c:%s:%s\n", need_data->path.cmd, need_data->path.buf, uint64_to_savepathstr_with_sig(blk->savepath));
					logw(asfd, cntr, msg);
					break;
		
				}
				default:
				{
					char msg[256];
					snprintf(msg, sizeof(msg), "Error when attempting  to verify block for %c:%s:%s\n", need_data->path.cmd, need_data->path.buf, uint64_to_savepathstr_with_sig(blk->savepath));
					return -1;
				}
			}
			return 0;
		default:
			logp("unknown action in %s: %d\n", __func__, act);
			return -1;
	}
}
Example #9
0
static void iobuf_from_blk_data(struct iobuf *wbuf, struct blk *blk)
{
	static char buf[CHECKSUM_LEN];
// FIX THIS: Check return of this - maybe should be done elsewhere.
	blk_md5_update(blk);

	// FIX THIS: consider endian-ness.
	memcpy(buf, &blk->fingerprint, FINGERPRINT_LEN);
	memcpy(buf+FINGERPRINT_LEN, blk->md5sum, MD5_DIGEST_LENGTH);
	iobuf_set(wbuf, CMD_SIG, buf, CHECKSUM_LEN);
}
Example #10
0
// Deal with a hack where the index is stripped off the beginning of the
// attributes when protocol2 saves to the manifest.
static void hack_protocol2_attr(struct iobuf *attr)
{
	char *cp=NULL;
	char *copy=NULL;
	size_t newlen;
	fail_unless((cp=strchr(attr->buf, ' '))!=NULL);
	fail_unless((copy=strdup_w(cp, __func__))!=NULL);
	newlen=attr->buf-cp+attr->len;
	iobuf_free_content(attr);
	iobuf_set(attr, CMD_ATTRIBS, copy, newlen);
}
Example #11
0
static int deal_with_client_rbuf(struct asfd *asfd, const char *directory,
	struct scores *scores)
{
	if(asfd->rbuf->cmd==CMD_GEN)
	{
		if(!strncmp_w(asfd->rbuf->buf, "cname:"))
		{
			struct iobuf wbuf;
			free_w(&asfd->desc);
			if(!(asfd->desc=strdup_w(asfd->rbuf->buf
				+strlen("cname:"), __func__)))
					goto error;
			logp("%s: fd %d\n", asfd->desc, asfd->fd);
			iobuf_set(&wbuf, CMD_GEN,
				(char *)"cname ok", strlen("cname ok"));

			if(asfd->write(asfd, &wbuf))
				goto error;
		}
		else if(!strncmp_w(asfd->rbuf->buf, "sigs_end"))
		{
			//printf("Was told no more sigs\n");
			if(deduplicate(asfd, directory, scores)<0)
				goto error;
		}
		else
		{
			iobuf_log_unexpected(asfd->rbuf, __func__);
			goto error;
		}
	}
	else if(asfd->rbuf->cmd==CMD_SIG)
	{
		if(champ_server_deal_with_rbuf_sig(asfd, directory, scores))
			goto error;
	}
	else if(asfd->rbuf->cmd==CMD_MANIFEST)
	{
		// Client has completed a manifest file. Want to start using
		// it as a dedup candidate now.
		if(candidate_add_fresh(asfd->rbuf->buf, directory, scores))
			goto error;
	}
	else
	{
		iobuf_log_unexpected(asfd->rbuf, __func__);
		goto error;
	}
	iobuf_free_content(asfd->rbuf);
	return 0;
error:
	iobuf_free_content(asfd->rbuf);
	return -1;
}
Example #12
0
int write_status(enum cntr_status cntr_status,
	const char *path, struct cntr *cntr)
{
	time_t now=0;
	time_t diff=0;
	static time_t lasttime=0;
	static size_t l=0;
	static struct iobuf *wbuf=NULL;

	if(!wasfd) return 0;
	if(!cntr || !cntr->bno)
		return 0;

	// Only update every 2 seconds.
	now=time(NULL);
	diff=now-lasttime;
	if(diff<2)
	{
		// Might as well do this in case they fiddled their
		// clock back in time.
		if(diff<0) lasttime=now;
		return 0;
	}
	lasttime=now;

	// Only get a new string if we did not manage to write the previous
	// one.
	if(!l)
	{
		cntr->cntr_status=cntr_status;
		if(!(l=cntr_to_str(cntr, path))) goto error;
		if(!wbuf && !(wbuf=iobuf_alloc())) goto error;
		iobuf_set(wbuf, CMD_APPEND, cntr->str, l);
	}

	switch(wasfd->append_all_to_write_buffer(wasfd, wbuf))
	{
		case APPEND_OK:
			l=0; // Fall through.
		case APPEND_BLOCKED:
			return 0;
		default:
			break;
	}
error:
	iobuf_free(&wbuf);
	return -1;
}
Example #13
0
static int restore_sbuf(struct asfd *asfd, struct sbuf *sb, enum action act,
	enum cstat_status status, struct conf *conf, int *need_data)
{
	//logp("%s: %s\n", act==ACTION_RESTORE?"restore":"verify", sb->path.buf);
	if(write_status(status, sb->path.buf, conf)) return -1;

	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->burp2->bstart)
	{
		// This will restore directory data on Windows.
		struct blk *b=NULL;
		struct blk *n=NULL;
		b=sb->burp2->bstart;
		while(b)
		{
			struct iobuf wbuf;
			iobuf_set(&wbuf, CMD_DATA, b->data, b->length);
			if(asfd->write(asfd, &wbuf)) return -1;
			n=b->next;
			blk_free(&b);
			b=n;
		}
		sb->burp2->bstart=sb->burp2->bend=NULL;
	}

	switch(sb->path.cmd)
	{
		case CMD_FILE:
		case CMD_ENC_FILE:
		case CMD_METADATA:
		case CMD_ENC_METADATA:
		case CMD_EFS_FILE:
			*need_data=1;
			return 0;
		default:
			cntr_add(conf->cntr, sb->path.cmd, 0);
			return 0;
	}
}
Example #14
0
static int do_encryption(struct asfd *asfd, EVP_CIPHER_CTX *ctx,
	uint8_t *inbuf, int inlen, uint8_t *outbuf, int *outlen,
	MD5_CTX *md5)
{
	if(!inlen) return 0;
	if(!EVP_CipherUpdate(ctx, outbuf, outlen, inbuf, inlen))
	{
		logp("Encryption failure.\n");
		return -1;
	}
	if(*outlen>0)
	{
		struct iobuf wbuf;
		iobuf_set(&wbuf, CMD_APPEND, (char *)outbuf, *outlen);
		if(asfd->write(asfd, &wbuf))
			return -1;
		if(!MD5_Update(md5, outbuf, *outlen))
		{
			logp("MD5_Update() failed\n");
			return -1;
		}
	}
	return 0;
}
Example #15
0
static void setup_proto1_some_things(struct asfd *asfd, struct slist *slist)
{
	struct sbuf *s;
	struct stat statp_dir;
	struct stat statp_file;
	int r=0; int w=0;
	fail_unless(!lstat(BASE, &statp_dir));
	fail_unless(!lstat(BASE "/burp.conf", &statp_file));
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore :");
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "ok");
	for(s=slist->head; s; s=s->next)
	{
		s->winattr=0;
		s->compression=0;
		if(s->path.cmd==CMD_DIRECTORY)
		{
			memcpy(&s->statp, &statp_dir, sizeof(statp_dir));
			attribs_encode(s);
		}
		if(sbuf_is_link(s))
		{
			char path[256];
			if(s->path.cmd==CMD_HARD_LINK)
				snprintf(path, sizeof(path), "%s", s->link.buf);
			else
			{
				char *cp;
				snprintf(path, sizeof(path), "%s", s->path.buf);
				fail_unless((cp=strrchr(path, '/'))!=NULL);
				cp++;
				snprintf(cp, strlen(s->link.buf)+1, "%s",
					s->link.buf);
			}
			build_file(path, NULL);
			
			memcpy(&s->statp, &statp_file, sizeof(statp_file));
			attribs_encode(s);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->attr);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->path);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->link);
		}
		else if(sbuf_is_filedata(s))
		{
			struct iobuf rbuf;
			// The string "data" gzipped.
			unsigned char gzipped_data[27] = {
				0x1f, 0x8b, 0x08, 0x08, 0xb4, 0x1e, 0x7f, 0x56,
				0x00, 0x03, 0x79, 0x00, 0x4b, 0x49, 0x2c, 0x49,
				0xe4, 0x02, 0x00, 0x82, 0xc5, 0xc1, 0xe6, 0x05,
				0x00, 0x00, 0x00
			};
			memcpy(&s->statp, &statp_file, sizeof(statp_file));
			attribs_encode(s);
			asfd_mock_read(asfd, &r,
				0, CMD_DATAPTH, s->path.buf);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->attr);
			asfd_mock_read_iobuf(asfd, &r,
				0, &s->path);
			// Protocol1 always sends it gzipped.
			iobuf_set(&rbuf, CMD_APPEND,
				(char *)gzipped_data, sizeof(gzipped_data));
			asfd_mock_read_iobuf(asfd, &r, 0, &rbuf);
			asfd_mock_read(asfd, &r,
				0, CMD_END_FILE, "0:19201273128");
		}
	}
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend");
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend ok");
}
Example #16
0
int send_whole_filel(struct asfd *asfd,
#ifdef HAVE_WIN32
	enum cmd cmd,
#endif
	const char *datapth,
	int quick_read, uint64_t *bytes, struct cntr *cntr,
	struct BFILE *bfd, const char *extrameta, size_t elen)
{
	int ret=0;
	size_t s=0;
	MD5_CTX md5;
	char buf[4096]="";
	struct iobuf wbuf;

	if(!bfd)
	{
		logp("No bfd in %s()\n", __func__);
		return -1;
	}

	if(!MD5_Init(&md5))
	{
		logp("MD5_Init() failed\n");
		return -1;
	}

	if(extrameta)
	{
		size_t metalen=0;
		const char *metadata=NULL;

		metadata=extrameta;
		metalen=elen;

		// Send metadata in chunks, rather than all at once.
		while(metalen>0)
		{
			if(metalen>ZCHUNK) s=ZCHUNK;
			else s=metalen;

			if(!MD5_Update(&md5, metadata, s))
			{
				logp("MD5_Update() failed\n");
				ret=-1;
			}
			iobuf_set(&wbuf, CMD_APPEND, (char *)metadata, s);
			if(asfd->write(asfd, &wbuf))
			{
				ret=-1;
			}

			metadata+=s;
			metalen-=s;

			*bytes+=s;
		}
	}
	else
	{
#ifdef HAVE_WIN32
		if(!ret && cmd==CMD_EFS_FILE)
		{
			struct winbuf mybuf;
			mybuf.md5=&md5;
			mybuf.quick_read=quick_read;
			mybuf.datapth=datapth;
			mybuf.cntr=cntr;
			mybuf.bytes=bytes;
			mybuf.asfd=asfd;
			// The EFS read function, ReadEncryptedFileRaw(),
			// works in an annoying way. You have to give it a
			// function that it calls repeatedly every time the
			// read buffer is called.
			// So ReadEncryptedFileRaw() will not return until
			// it has read the whole file. I have no idea why
			// they do not have a plain 'read()' function for it.

			ReadEncryptedFileRaw((PFE_EXPORT_FUNC)write_efs,
				&mybuf, bfd->pvContext);
		}
		else
#endif

		if(!ret)
		{
#ifdef HAVE_WIN32
		  int do_known_byte_count=0;
		  size_t datalen=bfd->datalen;
		  if(datalen>0) do_known_byte_count=1;
#endif
		  while(1)
		  {
#ifdef HAVE_WIN32
			if(do_known_byte_count)
			{
				s=(uint32_t)bfd->read(bfd,
					buf, min((size_t)4096, datalen));
				datalen-=s;
			}
			else
			{
#endif
				s=(uint32_t)bfd->read(bfd, buf, 4096);
#ifdef HAVE_WIN32
			}
#endif
			if(s<=0) break;

			*bytes+=s;
			if(!MD5_Update(&md5, buf, s))
			{
				logp("MD5_Update() failed\n");
				ret=-1;
				break;
			}
			iobuf_set(&wbuf, CMD_APPEND, buf, s);
			if(asfd->write(asfd, &wbuf))
			{
				ret=-1;
				break;
			}
			if(quick_read)
			{
				int qr;
				if((qr=do_quick_read(asfd, datapth, cntr))<0)
				{
					ret=-1;
					break;
				}
				if(qr)
				{
					// client wants to interrupt
					break;
				}
			}
#ifdef HAVE_WIN32
			// Windows VSS headers tell us how many bytes to
			// expect.
			if(do_known_byte_count && datalen<=0) break;
#endif
		  }
		}
	}
	if(!ret)
	{
		uint8_t checksum[MD5_DIGEST_LENGTH];
		if(!MD5_Final(checksum, &md5))
		{
			logp("MD5_Final() failed\n");
			return -1;
		}
		return write_endfile(asfd, *bytes, checksum);
	}
	return ret;
}
Example #17
0
/* OK, this function is getting a bit out of control.
   One problem is that, if you give deflateInit2 compression=0, it still
   writes gzip headers and footers, so I had to add extra
   if(compression) and if(!compression) bits all over the place that would
   skip the actual compression.
   This is needed for the case where encryption is on and compression is off.
   Encryption off and compression off uses send_whole_file().
   Perhaps a separate function is needed for encryption on compression off.
*/
int send_whole_file_gzl(struct asfd *asfd, const char *datapth,
	int quick_read, uint64_t *bytes, const char *encpassword,
	struct cntr *cntr, int compression, struct BFILE *bfd,
	const char *extrameta, size_t elen)
{
	int ret=0;
	int zret=0;
	MD5_CTX md5;
	size_t metalen=0;
	const char *metadata=NULL;
	struct iobuf wbuf;

	int have;
	z_stream strm;
	int flush=Z_NO_FLUSH;
	uint8_t in[ZCHUNK];
	uint8_t out[ZCHUNK];

	int eoutlen;
	uint8_t eoutbuf[ZCHUNK+EVP_MAX_BLOCK_LENGTH];

	EVP_CIPHER_CTX *enc_ctx=NULL;
#ifdef HAVE_WIN32
	int do_known_byte_count=0;
	size_t datalen=bfd->datalen;
	if(datalen>0) do_known_byte_count=1;
#endif

	if(encpassword && !(enc_ctx=enc_setup(1, encpassword)))
		return -1;

	if(!MD5_Init(&md5))
	{
		logp("MD5_Init() failed\n");
		return -1;
	}

//logp("send_whole_file_gz: %s%s\n", fname, extrameta?" (meta)":"");

	if((metadata=extrameta))
	{
		metalen=elen;
	}

	/* allocate deflate state */
	strm.zalloc = Z_NULL;
	strm.zfree = Z_NULL;
	strm.opaque = Z_NULL;
	if((zret=deflateInit2(&strm, compression, Z_DEFLATED, (15+16),
		8, Z_DEFAULT_STRATEGY))!=Z_OK)

	{
		return -1;
	}

	do
	{
		if(metadata)
		{
			if(metalen>ZCHUNK)
				strm.avail_in=ZCHUNK;
			else
				strm.avail_in=metalen;
			memcpy(in, metadata, strm.avail_in);
			metadata+=strm.avail_in;
			metalen-=strm.avail_in;
		}
		else
		{
			// Windows VSS headers give us how much data to
			// expect to read.
#ifdef HAVE_WIN32
			if(do_known_byte_count)
			{
				if(datalen<=0) strm.avail_in=0;
				else strm.avail_in=
					(uint32_t)bfd->read(bfd, in,
						min((size_t)ZCHUNK, datalen));
				datalen-=strm.avail_in;
			}
			else
#endif
				strm.avail_in=
					(uint32_t)bfd->read(bfd, in, ZCHUNK);
		}
		if(!compression && !strm.avail_in) break;

		*bytes+=strm.avail_in;

		// The checksum needs to be later if encryption is being used.
		if(!enc_ctx)
		{
			if(!MD5_Update(&md5, in, strm.avail_in))
			{
				logp("MD5_Update() failed\n");
				ret=-1;
				break;
			}
		}

#ifdef HAVE_WIN32
		if(do_known_byte_count && datalen<=0) flush=Z_FINISH;
		else
#endif
		if(strm.avail_in) flush=Z_NO_FLUSH;
		else flush=Z_FINISH;

		strm.next_in=in;

		/* run deflate() on input until output buffer not full, finish
			compression if all of source has been read in */
		do
		{
			if(compression)
			{
				strm.avail_out = ZCHUNK;
				strm.next_out = out;
				zret = deflate(&strm, flush); /* no bad return value */
				if(zret==Z_STREAM_ERROR) /* state not clobbered */
				{
					logp("z_stream_error\n");
					ret=-1;
					break;
				}
				have = ZCHUNK-strm.avail_out;
			}
			else
			{
				have=strm.avail_in;
				memcpy(out, in, have);
			}

			if(enc_ctx)
			{
				if(do_encryption(asfd, enc_ctx, out, have,
					eoutbuf, &eoutlen, &md5))
				{
					ret=-1;
					break;
				}
			}
			else
			{
				iobuf_set(&wbuf, CMD_APPEND, (char *)out, have);
				if(asfd->write(asfd, &wbuf))
				{
					ret=-1;
					break;
				}
			}
			if(quick_read && datapth)
			{
				int qr;
				if((qr=do_quick_read(asfd, datapth, cntr))<0)
				{
					ret=-1;
					break;
				}
				if(qr) // client wants to interrupt
				{
					goto cleanup;
				}
			}
			if(!compression) break;
		} while (!strm.avail_out);

		if(ret) break;

		if(!compression) continue;

		if(strm.avail_in) /* all input will be used */
		{
			ret=-1;
			logp("strm.avail_in=%d\n", strm.avail_in);
			break;
		}
	} while(flush!=Z_FINISH);

	if(!ret)
	{
		if(compression && zret!=Z_STREAM_END)
		{
			logp("ret OK, but zstream not finished: %d\n", zret);
			ret=-1;
		}
		else if(enc_ctx)
		{
			if(!EVP_CipherFinal_ex(enc_ctx, eoutbuf, &eoutlen))
			{
				logp("Encryption failure at the end\n");
				ret=-1;
			}
			else if(eoutlen>0)
			{
			  iobuf_set(&wbuf, CMD_APPEND,
				(char *)eoutbuf, (size_t)eoutlen);
			  if(asfd->write(asfd, &wbuf))
				ret=-1;
			  else if(!MD5_Update(&md5, eoutbuf, eoutlen))
			  {
				logp("MD5_Update() failed\n");
				ret=-1;
			  }
			}
		}
	}

cleanup:
	deflateEnd(&strm);

	if(enc_ctx)
	{
		EVP_CIPHER_CTX_cleanup(enc_ctx);
		free(enc_ctx);
	}

	if(!ret)
	{
		uint8_t checksum[MD5_DIGEST_LENGTH];
		if(!MD5_Final(checksum, &md5))
		{
			logp("MD5_Final() failed\n");
			return -1;
		}

		return write_endfile(asfd, *bytes, checksum);
	}
//logp("end of send\n");
	return ret;
}
Example #18
0
File: iobuf.c Project: jkniiv/burp
void iobuf_from_str(struct iobuf *iobuf, char cmd, char *str)
{
	iobuf_set(iobuf, cmd, str, strlen(str));
}
Example #19
0
File: iobuf.c Project: jkniiv/burp
void iobuf_copy(struct iobuf *dst, struct iobuf *src)
{
	iobuf_set(dst, src->cmd, src->buf, src->len);
}
Example #20
0
File: iobuf.c Project: jkniiv/burp
void iobuf_init(struct iobuf *iobuf)
{
	iobuf_set(iobuf, CMD_ERROR, NULL, 0);
}
Example #21
0
File: blk.c Project: vanElden/burp
static void to_iobuf_uint64(struct iobuf *iobuf, enum cmd cmd, uint64_t val)
{
	static union { char c[8]; uint64_t v; } buf;
	buf.v=HTOE(val);
	iobuf_set(iobuf, cmd, buf.c, sizeof(buf));
}
Example #22
0
static int copy_input_to_output(struct asfd *in, struct asfd *out)
{
	struct iobuf wbuf;
	iobuf_set(&wbuf, CMD_GEN, in->rbuf->buf, in->rbuf->len);
	return out->write(out, &wbuf);
}