Exemplo n.º 1
0
int zlib_inflate(struct asfd *asfd, const char *source_path,
	const char *dest_path, struct conf **confs)
{
	int ret=-1;
	size_t b=0;
	uint8_t in[ZCHUNK];
	struct fzp *src=NULL;
	struct fzp *dst=NULL;

	if(!(src=fzp_gzopen(source_path, "rb")))
	{
		logw(asfd, confs, "could not gzopen %s in %s: %s\n",
			source_path, __func__, strerror(errno));
		goto end;
	}
	if(!(dst=fzp_open(dest_path, "wb")))
	{
		logw(asfd, confs, "could not open %s in %s: %s\n",
			dest_path, __func__, strerror(errno));
		goto end;
	}

	while((b=fzp_read(src, in, ZCHUNK))>0)
	{
		if(fzp_write(dst, in, b)!=b)
		{
			logw(asfd, confs,
				"error when writing to %s\n", dest_path);
			goto end;
		}
	}
	if(!fzp_eof(src))
	{
		logw(asfd, confs,
			"error while reading %s in %s\n",
				source_path, __func__);
		goto end;
	}
	if(fzp_close(&dst))
	{
		logw(asfd, confs,
			"error when closing %s in %s: %s\n",
				dest_path, __func__, strerror(errno));
		goto end;
	}
	ret=0;
end:
	fzp_close(&src);
	fzp_close(&dst);
	return ret;
}
Exemplo n.º 2
0
Arquivo: fzp.c Projeto: vanElden/burp
int fzp_read_ensure(struct fzp *fzp, void *ptr, size_t nmemb, const char *func)
{
	static int f;
	static int r;
	static size_t got;
	static int pass;
	for(r=0, got=0, pass=0; got!=nmemb; pass++)
	{
		r=fzp_read(fzp, ((char *)ptr)+got, nmemb-got);
		if(r>0)
		{
			got+=r;
			continue;
		}
		if(r<0)
		{
			pass_msg(nmemb, got, pass);
			logp("Error in %s, called from %s: %s\n",
				__func__, func, strerror(errno));
			return -1;
		}
		f=fzp_eof(fzp);
		if(!f) continue; // Not yet end of file, keep trying.
		if(f>0)
		{
			// End of file.
			if(!got) return 1;
			pass_msg(nmemb, got, pass);
			logp("Error in %s, called from %s: %u bytes, eof\n",
				__func__, func, got);
			return -1;
		}
		else
		{
			pass_msg(nmemb, got, pass);
			logp("Error in %s by fzp_feof, called from %s: %s\n",
				__func__, func, strerror(errno));
			return -1;
		}
	}
	return 0;
}
Exemplo n.º 3
0
static int verify_file(struct asfd *asfd, struct sbuf *sb,
	int patches, const char *best,
	uint64_t *bytes, struct cntr *cntr)
{
	MD5_CTX md5;
	size_t b=0;
	const char *cp=NULL;
	const char *newsum=NULL;
	uint8_t in[ZCHUNK];
	uint8_t checksum[MD5_DIGEST_LENGTH];
	uint64_t cbytes=0;
	struct fzp *fzp=NULL;

	if(!(cp=strrchr(sb->endfile.buf, ':')))
	{
		logw(asfd, cntr,
			"%s has no md5sum!\n", sb->protocol1->datapth.buf);
		return 0;
	}
	cp++;
	if(!MD5_Init(&md5))
	{
		logp("MD5_Init() failed\n");
		return -1;
	}
	if(patches
	  || sb->path.cmd==CMD_ENC_FILE
	  || sb->path.cmd==CMD_ENC_METADATA
	  || sb->path.cmd==CMD_EFS_FILE
	  || sb->path.cmd==CMD_ENC_VSS
	  || (!patches && !dpth_protocol1_is_compressed(sb->compression, best)))
		fzp=fzp_open(best, "rb");
	else
		fzp=fzp_gzopen(best, "rb");

	if(!fzp)
	{
		logw(asfd, cntr, "could not open %s\n", best);
		return 0;
	}
	while((b=fzp_read(fzp, in, ZCHUNK))>0)
	{
		cbytes+=b;
		if(!MD5_Update(&md5, in, b))
		{
			logp("MD5_Update() failed\n");
			fzp_close(&fzp);
			return -1;
		}
	}
	if(!fzp_eof(fzp))
	{
		logw(asfd, cntr, "error while reading %s\n", best);
		fzp_close(&fzp);
		return 0;
	}
	fzp_close(&fzp);
	if(!MD5_Final(checksum, &md5))
	{
		logp("MD5_Final() failed\n");
		return -1;
	}
	newsum=bytes_to_md5str(checksum);

	if(strcmp(newsum, cp))
	{
		logp("%s %s\n", newsum, cp);
		logw(asfd, cntr, "md5sum for '%s (%s)' did not match!\n",
			sb->path.buf, sb->protocol1->datapth.buf);
		logp("md5sum for '%s (%s)' did not match!\n",
			sb->path.buf, sb->protocol1->datapth.buf);
		return 0;
	}
	*bytes+=cbytes;

	// Just send the file name to the client, so that it can show cntr.
	if(asfd->write(asfd, &sb->path)) return -1;
	return 0;
}
Exemplo n.º 4
0
/*
 * If the stream has no more data available, read some from F into
 * BUF, and let the stream use that.  On return, SEEN_EOF is true if
 * the end of file has passed into the stream.
 */
rs_result rs_infilebuf_fill(rs_job_t *job, rs_buffers_t *buf, void *opaque)
{
	int len=0;
	rs_filebuf_t *fb=(rs_filebuf_t *) opaque;
	struct cntr *cntr;
	int fd=fb->fd;
	cntr=fb->cntr;

	//logp("rs_infilebuf_fill\n");

	/* This is only allowed if either the buf has no input buffer
	 * yet, or that buffer could possibly be BUF. */
	if(buf->next_in)
	{
		//logp("infilebuf avail_in %d buf_len %d\n",
		//	buf->avail_in, fb->buf_len);
		if(buf->avail_in > fb->buf_len)
		{
			logp("buf->avail_in > fb->buf_len (%d > %d) in %s\n",
				buf->avail_in, fb->buf_len, __func__);
			return RS_IO_ERROR;
		}
		if(buf->next_in < fb->buf)
		{
			logp("buf->next_in < fb->buf in %s\n", __func__);
			return RS_IO_ERROR;
		}
		if(buf->next_in > fb->buf + fb->buf_len)
		{
			logp("buf->next_in > fb->buf + fb->buf_len in %s\n",
				__func__);
			return RS_IO_ERROR;
		}
	}
	else
	{
		if(buf->avail_in)
		{
			logp("buf->avail_in is %d in %s\n",
				buf->avail_in, __func__);
			return RS_IO_ERROR;
		}
	}

	if(buf->eof_in) return RS_DONE;

	if(buf->avail_in)
		/* Still some data remaining.  Perhaps we should read
		   anyhow? */
		return RS_DONE;

	if(fd>=0)
	{
		static struct iobuf *rbuf=NULL;
		rbuf=fb->asfd->rbuf;

		if(fb->asfd->read(fb->asfd)) return RS_IO_ERROR;
		if(rbuf->cmd==CMD_APPEND)
		{
			//logp("got '%c' in fd infilebuf: %d\n",
			//	CMD_APPEND, rbuf->len);
			memcpy(fb->buf, rbuf->buf, rbuf->len);
			len=rbuf->len;
			iobuf_free_content(rbuf);
		}
		else if(rbuf->cmd==CMD_END_FILE)
		{
			iobuf_free_content(rbuf);
			//logp("got %c in fd infilebuf\n", CMD_END_FILE);
			buf->eof_in=1;
			return RS_DONE;
		}
		else if(rbuf->cmd==CMD_WARNING)
		{
			logp("WARNING: %s\n", rbuf->buf);
			cntr_add(cntr, rbuf->cmd, 0);
			iobuf_free_content(rbuf);
			return RS_DONE;
		}
		else
		{
			iobuf_log_unexpected(rbuf, __func__);
			iobuf_free_content(rbuf);
			return RS_IO_ERROR;
		}
	}
	else if(fb->bfd)
	{
		if(fb->do_known_byte_count)
		{
			if(fb->data_len>0)
			{
				len=fb->bfd->read(fb->bfd, fb->buf,
					min(fb->buf_len, fb->data_len));
				fb->data_len-=len;
			}
			else
			{
				// We have already read as much data as the VSS
				// header told us to, so set len=0 in order to
				// finish up.
				len=0;
			}
		}
		else
			len=fb->bfd->read(fb->bfd, fb->buf, fb->buf_len);
		if(len==0)
		{
			//logp("bread: eof\n");
			buf->eof_in=1;
			return RS_DONE;
		}
		else if(len<0)
		{
			logp("rs_infilebuf_fill: error in bread\n");
			return RS_IO_ERROR;
		}
		//logp("bread: ok: %d\n", len);
		fb->bytes+=len;
		if(!MD5_Update(&(fb->md5), fb->buf, len))
		{
			logp("rs_infilebuf_fill: MD5_Update() failed\n");
			return RS_IO_ERROR;
		}
	}
	else if(fb->fzp)
	{
		if((len=fzp_read(fb->fzp, fb->buf, fb->buf_len))<=0)
		{
			// This will happen if file size is a multiple of
			// input block len.
			if(fzp_eof(fb->fzp))
			{
				buf->eof_in=1;
				return RS_DONE;
			}
			else
			{
				logp("rs_infilebuf_fill: got return %d when trying to read\n", len);
				return RS_IO_ERROR;
			}
		}
		fb->bytes+=len;
		if(!MD5_Update(&(fb->md5), fb->buf, len))
		{
			logp("rs_infilebuf_fill: MD5_Update() failed\n");
			return RS_IO_ERROR;
		}
	}

	buf->avail_in = len;
	buf->next_in = fb->buf;

	return RS_DONE;
}