Beispiel #1
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 #2
0
static int do_browse_manifest(struct asfd *srfd,
	struct manio *manio, struct sbuf *sb, const char *browse)
{
	int ret=-1;
	int ars=0;
	//char ls[1024]="";
	//struct cntr cntr;
	size_t blen=0;
	char *last_bd_match=NULL;
	if(browse) blen=strlen(browse);
	while(1)
	{
		int r;
		sbuf_free_content(sb);
		if((ars=manio_read(manio, sb)))
		{
			if(ars<0) goto end;
			// ars==1 means it ended ok.
			break;
		}

		if(manio->protocol==PROTO_2 && sb->endfile.buf)
			continue;

		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
		  && !cmd_is_link(sb->path.cmd))
			continue;

		if((r=check_browsedir(browse, sb, blen, &last_bd_match))<0)
			goto end;
		if(!r) continue;

		if(json_from_statp(sb->path.buf, &sb->statp)) goto end;
	}

	ret=0;
end:
	free_w(&last_bd_match);
	return ret;
}
Beispiel #3
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 #4
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 #5
0
int do_list_client(struct config *conf, enum action act, int json)
{
	int ret=0;
	size_t slen=0;
	char msg[512]="";
	char scmd=0;
	struct stat statp;
	char *statbuf=NULL;
	char ls[2048]="";
	char *dpth=NULL;
	int first_entry=1;
	// format long list as JSON
	int emit_json = (act==ACTION_LONG_LIST && conf->backup && json);
//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(async_write_str(CMD_GEN, msg)
	  || async_read_expect(CMD_GEN, "ok"))
		return -1;

	if(emit_json)
	{
		printf("{\n");
	}
	
	// This should probably should use the sbuf stuff.
	while(1)
	{
		char fcmd=0;
		size_t flen=0;
		int64_t winattr=0;
		int compression=-1;
		char *fname=NULL;
		if(async_read(&scmd, &statbuf, &slen))
		{
			//ret=-1; break;
			break;
		}
		if(scmd==CMD_TIMESTAMP)
		{
			// A backup timestamp, just print it.
			if(emit_json)
			{
				printf("\t\"backup\":\n"
				       "\t\t{\n"
				       "\t\t\t\"timestamp\": \"%s\",\n"
				       "\t\t\t\"directory\": \"%s\",\n"
				       "\t\t\t\"regex\": \"%s\"\n"
				       "\t\t},\n",
				       statbuf,
				       conf->browsedir? conf->browsedir:"",
				       conf->regex? conf->regex:"");
			}
			else
			{
				printf("Backup: %s\n", statbuf);
				if(conf->browsedir)
					printf("Listing directory: %s\n",
					       conf->browsedir);
				if(conf->regex)
					printf("With regex: %s\n",
					       conf->regex);
			}
			if(statbuf) { free(statbuf); statbuf=NULL; }
			continue;
		}
		else if(scmd==CMD_DATAPTH)
		{
			if(statbuf) { free(statbuf); statbuf=NULL; }
			continue;
		}
		else if(scmd!=CMD_STAT)
		{
			logp("expected %c cmd - got %c:%s\n",
				CMD_STAT, scmd, statbuf);
			ret=-1; break;
		}

		decode_stat(statbuf, &statp, &winattr, &compression);

		if(async_read(&fcmd, &fname, &flen))
		{
			logp("got stat without an object\n");
			ret=-1; break;
		}
		else if(fcmd==CMD_DIRECTORY
			|| fcmd==CMD_FILE
			|| fcmd==CMD_ENC_FILE
			|| fcmd==CMD_EFS_FILE
			|| fcmd==CMD_SPECIAL)
		{
			*ls='\0';
			if(act==ACTION_LONG_LIST)
			{
				if(emit_json)
				{
					char *esc_fname = NULL;
					ls_output_json(ls, sizeof(ls), first_entry, fcmd, fname, &esc_fname, NULL, NULL, &statp);
					printf(ls, esc_fname? esc_fname:"", "");
					if(esc_fname)
						free(esc_fname);
				}
				else
				{
					ls_output(ls, fname, &statp);
					printf("%s\n", ls);
				}
			}
			else
			{
				printf("%s\n", fname);
			}
			if (first_entry)
			{
				first_entry = 0;
			}
		}
		else if(cmd_is_link(fcmd)) // symlink or hardlink
		{
			char lcmd=0;
			size_t llen=0;
			char *lname=NULL;
			if(async_read(&lcmd, &lname, &llen)
			  || lcmd!=fcmd)
			{
				logp("could not get second part of link %c:%s\n", fcmd, fname);
				ret=-1;
			}
			else
			{
				if(act==ACTION_LONG_LIST)
				{
					*ls='\0';
					if(emit_json)
					{
						char *esc_fname = NULL;
						char *esc_lname = NULL;
						ls_output_json(ls, sizeof(ls), first_entry, fcmd, fname, &esc_fname, lname, &esc_lname, &statp);
						printf(ls, esc_fname? esc_fname:"", esc_lname? esc_lname:"");
						if(esc_fname)
							free(esc_fname);
						if(esc_lname)
							free(esc_lname);
					}
					else
					{
						ls_output(ls, fname, &statp);
						printf("%s -> %s\n", ls, lname);
					}
				}
				else
				{
					printf("%s\n", fname);
				}
				if (first_entry)
				{
					first_entry = 0;
				}
			}
			if(lname) free(lname);
		}
		else
		{
			fprintf(stderr, "unlistable %c:%s\n", fcmd, fname?:"");
		}
		if(fname) free(fname);
		if(statbuf) { free(statbuf); statbuf=NULL; }
	}
	if(statbuf) free(statbuf);
	if(dpth) free(dpth);
	if(emit_json)
	{
		if(!first_entry)
		{
			printf("\t\t]\n");
		}
		printf("}\n");
	}
	if(!ret) logp("List finished ok\n");
	return ret;
}
Beispiel #6
0
int iobuf_is_link(struct iobuf *iobuf)
{
	return cmd_is_link(iobuf->cmd);
}
Beispiel #7
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 #8
0
static int list_manifest(const char *fullpath, regex_t *regex, const char *browsedir, const char *client, struct cntr *p1cntr, struct cntr *cntr)
{
	int ars=0;
	int ret=0;
	int quit=0;
	gzFile zp=NULL;
	struct sbuf mb;
	char *manifest=NULL;
	size_t bdlen=0;

	init_sbuf(&mb);

	if(!(manifest=prepend_s(fullpath,
		"manifest.gz", strlen("manifest.gz"))))
	{
		log_and_send_oom(__FUNCTION__);
		return -1;
	}
	if(!(zp=gzopen_file(manifest, "rb")))
	{
		log_and_send("could not open manifest");
		free(manifest);
		return -1;
	}
	free(manifest);

	if(browsedir) bdlen=strlen(browsedir);

	while(!quit)
	{
		int show=0;
		//logp("list manifest loop\n");
		// Need to parse while sending, to take note of the regex.

		free_sbuf(&mb);
		if((ars=sbuf_fill(NULL, zp, &mb, cntr)))
		{
			if(ars<0) ret=-1;
			// ars==1 means it ended ok.
			break;
		}

		if(mb.cmd!=CMD_DIRECTORY
		 && mb.cmd!=CMD_FILE
		 && mb.cmd!=CMD_ENC_FILE
		 && mb.cmd!=CMD_EFS_FILE
		 && mb.cmd!=CMD_SPECIAL
		 && !cmd_is_link(mb.cmd))
			continue;

		//if(mb.path[mb.plen]=='\n') mb.path[mb.plen]='\0';
		write_status(client, STATUS_LISTING, mb.path, p1cntr, cntr);

		if(browsedir)
		{
			int r;
			if((r=check_browsedir(browsedir, &(mb.path), bdlen))<0)
			{
				quit++;
				ret=-1;
			}
			if(!r) continue;
			show++;
		}
		else
		{
			if(check_regex(regex, mb.path))
				show++;
		}
		if(show)
		{
			if(async_write(CMD_STAT, mb.statbuf, mb.slen)
			  || async_write(mb.cmd, mb.path, mb.plen))
			{ quit++; ret=-1; }
			else if(sbuf_is_link(&mb)
			  && async_write(mb.cmd, mb.linkto, mb.llen))
			{ quit++; ret=-1; }
		}
	}
	gzclose_fp(&zp);
	free_sbuf(&mb);
	return ret;
}
Beispiel #9
0
static enum parse_ret parse_cmd(struct sbuf *sb, struct asfd *asfd,
	struct iobuf *rbuf, struct blk *blk, struct cntr *cntr)
{
	switch(rbuf->cmd)
	{
		case CMD_ATTRIBS:
			if(sb->protocol2)
				sbuf_free_content(sb);
			else
			{
				if(sb->protocol1->datapth.buf)
					// protocol 1 phase 2+ file data
					// starts with datapth.
					iobuf_free_content(&sb->attr);
				else
					// protocol 1 phase 1 or non file data
					// starts with attribs
					sbuf_free_content(sb);
			}
			iobuf_move(&sb->attr, rbuf);
			attribs_decode(sb);
			return PARSE_RET_NEED_MORE;

		case CMD_FILE:
		case CMD_DIRECTORY:
		case CMD_SOFT_LINK:
		case CMD_HARD_LINK:
		case CMD_SPECIAL:
		// Stuff not currently supported in burp-2, but OK
		// to find in burp-1.
		case CMD_ENC_FILE:
		case CMD_METADATA:
		case CMD_ENC_METADATA:
		case CMD_EFS_FILE:
		case CMD_VSS:
		case CMD_ENC_VSS:
		case CMD_VSS_T:
		case CMD_ENC_VSS_T:
			if(!sb->attr.buf)
			{
				log_and_send(asfd, "read cmd with no attribs");
				return PARSE_RET_ERROR;
			}
			if(sb->flags & SBUF_NEED_LINK)
			{
				if(cmd_is_link(rbuf->cmd))
				{
					iobuf_free_content(&sb->link);
					iobuf_move(&sb->link, rbuf);
					sb->flags &= ~SBUF_NEED_LINK;
					return PARSE_RET_COMPLETE;
				}
				else
				{
					log_and_send(asfd, "got non-link after link in manifest");
					return PARSE_RET_NEED_MORE;
				}
			}
			else
			{
				iobuf_free_content(&sb->path);
				iobuf_move(&sb->path, rbuf);
				if(cmd_is_link(rbuf->cmd))
				{
					sb->flags |= SBUF_NEED_LINK;
					return PARSE_RET_NEED_MORE;
				}
				else if(sb->protocol1
				  && sb->protocol1->datapth.buf)
				{
					// Protocol1 client restore reads
					// CMD_APPEND and CMD_END_FILE in the
					// calling function, so pretend it is
					// complete if we have the hack flag.
					if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
						return PARSE_RET_COMPLETE;
					return PARSE_RET_NEED_MORE;
				}
				return PARSE_RET_COMPLETE;
			}
#ifndef HAVE_WIN32
		case CMD_SIG:
			// Fill in the sig/block, if the caller provided
			// a pointer for one. Server only.
			if(!blk) return PARSE_RET_NEED_MORE;

			// Just fill in the sig details.
			if(blk_set_from_iobuf_sig_and_savepath(blk, rbuf))
				return PARSE_RET_ERROR;
			blk->got_save_path=1;
			iobuf_free_content(rbuf);
			return PARSE_RET_COMPLETE;
#endif
		case CMD_DATA:
			// Need to write the block to disk.
			// Client only.
			if(!blk) return PARSE_RET_NEED_MORE;
			blk->data=rbuf->buf;
			blk->length=rbuf->len;
			rbuf->buf=NULL;
			return PARSE_RET_COMPLETE;
		case CMD_MESSAGE:
		case CMD_WARNING:
			log_recvd(rbuf, cntr, 1);
			return PARSE_RET_NEED_MORE;
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "restoreend")
			  || !strcmp(rbuf->buf, "phase1end")
			  || !strcmp(rbuf->buf, "backupphase2")
			// Think these are protocol1 things.
                	  || !strcmp(rbuf->buf, "backupend")
			  || !strcmp(rbuf->buf, "estimateend"))
				return PARSE_RET_FINISHED;
			iobuf_log_unexpected(rbuf, __func__);
			return PARSE_RET_ERROR;
		case CMD_FINGERPRINT:
			if(blk && blk_set_from_iobuf_fingerprint(blk, rbuf))
				return PARSE_RET_ERROR;
			// Fall through.
		case CMD_MANIFEST:
			iobuf_free_content(&sb->path);
			iobuf_move(&sb->path, rbuf);
			return PARSE_RET_COMPLETE;
		case CMD_ERROR:
			logp("got error: %s\n", rbuf->buf);
			return PARSE_RET_ERROR;
		case CMD_DATAPTH:
			if(!sb->protocol1)
			{
				iobuf_log_unexpected(rbuf, __func__);
				return PARSE_RET_ERROR;
			}
			if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
			{
				sbuf_free_content(sb);
				sb->flags |= SBUF_CLIENT_RESTORE_HACK;
			}
			else
				sbuf_free_content(sb);
			
			iobuf_move(&sb->protocol1->datapth, rbuf);
			return PARSE_RET_NEED_MORE;
		case CMD_END_FILE:
			iobuf_free_content(&sb->endfile);
			iobuf_move(&sb->endfile, rbuf);
			if(sb->protocol1)
			{
				if(!sb->attr.buf
				  || !sb->protocol1->datapth.buf
				  || (!sbuf_is_filedata(sb)
					&& !sbuf_is_vssdata(sb)))
				{
					logp("got unexpected cmd_endfile");
					return PARSE_RET_ERROR;
				}
			}
			return PARSE_RET_COMPLETE;
		default:
			iobuf_log_unexpected(rbuf, __func__);
			return PARSE_RET_ERROR;
	}
	logp("Fell out of switch unexpectedly in %s()\n", __func__);
	return PARSE_RET_ERROR;
}