Esempio n. 1
0
File: main.c Progetto: jkniiv/burp
static enum cliret maybe_check_timer(struct asfd *asfd,
	enum action action, const char *phase1str,
	struct conf *conf, int *resume)
{
	int complen=0;
	struct iobuf *rbuf=asfd->rbuf;

        if(asfd->write_str(asfd, CMD_GEN, phase1str)) goto error;

        if(asfd->read(asfd)) goto error;

        if(rbuf->cmd!=CMD_GEN)
        {
		iobuf_free_content(rbuf);
		iobuf_log_unexpected(rbuf, __func__);
		goto error;
        }
        if(!strcmp(rbuf->buf, "timer conditions not met"))
        {
		iobuf_free_content(rbuf);
                logp("Timer conditions on the server were not met\n");
		goto timer_not_met;
        }
        else if(!strcmp(rbuf->buf, "timer conditions met"))
        {
		iobuf_free_content(rbuf);
                logp("Timer conditions on the server were met\n");
		if(action==ACTION_TIMER_CHECK) goto end;
        }

	if(!strncmp_w(rbuf->buf, "ok"))
		complen=3;
	else if(!strncmp_w(rbuf->buf, "resume"))
	{
		complen=7;
		*resume=1;
		logp("server wants to resume previous backup.\n");
	}
	else
	{
		iobuf_log_unexpected(rbuf, __func__);
		iobuf_free_content(rbuf);
		goto error;
	}
        // The server now tells us the compression level in the OK response.
        if(strlen(rbuf->buf)>3) conf->compression=atoi(rbuf->buf+complen);
        logp("Compression level: %d\n", conf->compression);

	iobuf_free_content(rbuf);
end:
	return CLIENT_OK;
error:
	return CLIENT_ERROR;
timer_not_met:
	return CLIENT_SERVER_TIMER_NOT_MET;
}
Esempio n. 2
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;
}
Esempio n. 3
0
// return -1 for error, 0 for OK, 1 if the client wants to interrupt the
// transfer.
int do_quick_read(struct asfd *asfd, const char *datapth, struct conf **confs)
{
	int r=0;
	struct iobuf *rbuf;
	if(asfd->as->read_quick(asfd->as)) return -1;
	rbuf=asfd->rbuf;

	if(rbuf->buf)
	{
		if(rbuf->cmd==CMD_MESSAGE
		  || rbuf->cmd==CMD_WARNING)
		{
			log_recvd(rbuf, confs, 0);
		}
		else if(rbuf->cmd==CMD_INTERRUPT)
		{
			// Client wants to interrupt - double check that
			// it is still talking about the file that we are
			// sending.
			if(datapth && !strcmp(rbuf->buf, datapth))
				r=1;
		}
		else
		{
			iobuf_log_unexpected(rbuf, __func__);
			r=-1;
		}
		iobuf_free_content(rbuf);
	}
	return r;
}
Esempio n. 4
0
// Return 0 for OK, -1 for error, 1 for finished reading the file.
static int get_next_dindex(uint64_t **dnew, struct sbuf *sb, struct fzp *fzp)
{
	static struct blk blk;
	static struct iobuf rbuf;

	memset(&rbuf, 0, sizeof(rbuf));

	switch(iobuf_fill_from_fzp(&rbuf, fzp))
	{
		case -1: goto error;
		case 1: return 1; // Reached the end.
	}
	if(rbuf.cmd==CMD_SAVE_PATH)
	{
		if(blk_set_from_iobuf_savepath(&blk, &rbuf))
			goto error;
		*dnew=(uint64_t *)malloc_w(sizeof(uint64_t), __func__);
		**dnew=blk.savepath;
		iobuf_free_content(&rbuf);
		return 0;
	}
	else
		iobuf_log_unexpected(&sb->path, __func__);

error:
	iobuf_free_content(&rbuf);
	return -1;
}
Esempio n. 5
0
static int deal_with_read_from_chfd(struct asfd *chfd,
	struct blist *blist, uint64_t *wrap_up, struct dpth *dpth,
	struct cntr *cntr)
{
	int ret=-1;

	// Deal with champ chooser read here.
	//printf("read from cc: %s\n", chfd->rbuf->buf);
	switch(chfd->rbuf->cmd)
	{
		case CMD_SIG:
			// Get these for blks that the champ chooser has found.
			if(deal_with_sig_from_chfd(chfd->rbuf, blist, dpth))
				goto end;
			cntr_add_same(cntr, CMD_DATA);
			break;
		case CMD_WRAP_UP:
			if(deal_with_wrap_up_from_chfd(chfd->rbuf, blist, dpth))
				goto end;
			break;
		default:
			iobuf_log_unexpected(chfd->rbuf, __func__);
			goto end;
	}
	ret=0;
end:
	iobuf_free_content(chfd->rbuf);
	return ret;
}
Esempio n. 6
0
// Want to make sure that we are listening for reads too - this will let us
// exit promptly if the client was killed.
// FIX THIS: Maybe some of this should go in async.c/asfd.c.
static int read_and_write(struct asfd *asfd)
{
	if(asfd->as->read_write(asfd->as)) return -1;
	if(!asfd->rbuf->buf) return 0;
	iobuf_log_unexpected(asfd->rbuf, __func__);
	return -1;
}
Esempio n. 7
0
static enum asl_ret restore_end_func(struct asfd *asfd,
	struct conf **confs, void *param)
{
	if(!strcmp(asfd->rbuf->buf, "restoreend_ok"))
		return ASL_END_OK;
	iobuf_log_unexpected(asfd->rbuf, __func__);
	return ASL_END_ERROR;
}
Esempio n. 8
0
// FIX THIS: it only works with protocol1.
int restore_interrupt(struct asfd *asfd,
	struct sbuf *sb, const char *msg, struct cntr *cntr,
	enum protocol protocol)
{
	int ret=0;
	struct iobuf *rbuf=asfd->rbuf;

	if(protocol!=PROTO_1) return 0;
	if(!cntr) return 0;

	cntr_add(cntr, CMD_WARNING, 1);
	logp("WARNING: %s\n", msg);
	if(asfd->write_str(asfd, CMD_WARNING, msg)) goto end;

	// If it is file data, get the server
	// to interrupt the flow and move on.
	if(sb->path.cmd!=CMD_FILE
	  && sb->path.cmd!=CMD_ENC_FILE
	  && sb->path.cmd!=CMD_EFS_FILE
	  && sb->path.cmd!=CMD_VSS
	  && sb->path.cmd!=CMD_ENC_VSS
	  && sb->path.cmd!=CMD_VSS_T
	  && sb->path.cmd!=CMD_ENC_VSS_T)
		return 0;
	if(sb->protocol1 && !(sb->protocol1->datapth.buf))
		return 0;
	if(sb->protocol2 && !(sb->path.buf))
		return 0;

	if(asfd->write_str(asfd, CMD_INTERRUPT, sb->protocol1->datapth.buf))
		goto end;

	// Read to the end file marker.
	while(1)
	{
		iobuf_free_content(rbuf);
		if(asfd->read(asfd))
			goto end;
		if(!ret && rbuf->len)
		{
			if(rbuf->cmd==CMD_APPEND)
				continue;
			else if(rbuf->cmd==CMD_END_FILE)
				break;
			else
			{
				iobuf_log_unexpected(rbuf, __func__);
				goto end;
			}
		}
	}

	ret=0;
end:
	iobuf_free_content(rbuf);
	return ret;
}
Esempio n. 9
0
int restore_interrupt(struct asfd *asfd,
	struct sbuf *sb, const char *msg, struct cntr *cntr,
	enum protocol protocol)
{
	int ret=0;
	char *path=NULL;
	struct iobuf *rbuf=asfd->rbuf;

	if(cntr)
	{
		cntr_add(cntr, CMD_WARNING, 1);
		logp("WARNING: %s\n", msg);
		if(asfd->write_str(asfd, CMD_WARNING, msg)) goto end;
	}

	// If it is file data, get the server
	// to interrupt the flow and move on.
	if(!iobuf_is_filedata(&sb->path)
	  && !iobuf_is_vssdata(&sb->path))
		return 0;

	if(protocol==PROTO_1)
		path=sb->protocol1->datapth.buf;
	else if(protocol==PROTO_2)
		path=sb->path.buf;

	if(!path) return 0;

	if(asfd->write_str(asfd, CMD_INTERRUPT, path))
		goto end;

	// Read to the end file marker.
	while(1)
	{
		iobuf_free_content(rbuf);
		if(asfd->read(asfd))
			goto end;
		if(!rbuf->len) continue;

		switch(rbuf->cmd)
		{
			case CMD_APPEND:
			case CMD_DATA:
				continue;
			case CMD_END_FILE:
				ret=0;
				goto end;
			default:
				iobuf_log_unexpected(rbuf, __func__);
				goto end;
		}
	}
end:
	iobuf_free_content(rbuf);
	return ret;
}
Esempio n. 10
0
static enum asl_ret autoupgrade_func(struct asfd *asfd,
	struct conf *conf, void *param)
{
	if(!strcmp(asfd->rbuf->buf, "do not autoupgrade"))
		return ASL_END_OK;
	if(strcmp(asfd->rbuf->buf, "autoupgrade ok"))
	{
		iobuf_log_unexpected(asfd->rbuf, __func__);
		return ASL_END_ERROR;
	}
	return ASL_END_OK_RETURN_1;
}
Esempio n. 11
0
// Return 0 for OK, -1 for error, 1 for finished reading the file.
static int get_next_set_of_hooks(struct hooks **hnew, struct sbuf *sb,
	struct fzp *spzp, char **path, uint64_t **fingerprints, size_t *len)
{
	struct blk blk;
	while(1)
	{
		switch(sbuf_fill_from_file(sb, spzp, NULL, NULL))
		{
			case -1: goto error;
			case 1:
				// Reached the end.
				if(hooks_alloc(hnew, path, fingerprints, len))
					goto error;
				return 1;
		}
		if(sb->path.cmd==CMD_MANIFEST)
		{
			if(hooks_alloc(hnew, path, fingerprints, len))
				break;
			*path=sb->path.buf;
			sb->path.buf=NULL;
			sbuf_free_content(sb);
			if(*hnew) return 0;
		}
		else if(sb->path.cmd==CMD_FINGERPRINT)
		{
			if(!(*fingerprints=(uint64_t *)realloc_w(*fingerprints,
				((*len)+1)*sizeof(uint64_t), __func__)))
					goto error;
			if(blk_set_from_iobuf_fingerprint(&blk, &sb->path))
				goto error;
			(*fingerprints)[(*len)++]=blk.fingerprint;
			sbuf_free_content(sb);
		}
		else
		{
			iobuf_log_unexpected(&sb->path, __func__);
			break;
		}
	}

error:
	sbuf_free_content(sb);
	return -1;
}
Esempio n. 12
0
static enum asl_ret restore_style_func(struct asfd *asfd,
	struct conf **confs, void *param)
{
	char msg[32]="";
	restore_style=NULL;
	if(strcmp(asfd->rbuf->buf, RESTORE_STREAM)
	   && strcmp(asfd->rbuf->buf, RESTORE_SPOOL))
	{
		iobuf_log_unexpected(asfd->rbuf, __func__);
		return ASL_END_ERROR;
	}
	snprintf(msg, sizeof(msg), "%s_ok", asfd->rbuf->buf);
	if(asfd->write_str(asfd, CMD_GEN, msg))
		return ASL_END_ERROR;
	restore_style=asfd->rbuf->buf;
	iobuf_init(asfd->rbuf);
	return ASL_END_OK;
}
Esempio n. 13
0
// Return 0 for OK, -1 for error, 1 for finished reading the file.
static int get_next_set_of_hooks(struct hooks **hnew, struct sbuf *sb,
	struct fzp *spzp, char **path, char **fingerprints,
	struct conf **confs)
{
	while(1)
	{
		switch(sbuf_fill(sb, NULL /* struct async */,
			spzp, NULL, NULL, confs))
		{
			case -1: goto error;
			case 1:
				// Reached the end.
				if(hooks_alloc(hnew, path, fingerprints))
					goto error;
				return 1;
		}
		if(sb->path.cmd==CMD_MANIFEST)
		{
			if(hooks_alloc(hnew, path, fingerprints))
				break;
			free_w(fingerprints);
			free_w(path);
			*path=sb->path.buf;
			sb->path.buf=NULL;
			sbuf_free_content(sb);
			if(*hnew) return 0;
		}
		else if(sb->path.cmd==CMD_FINGERPRINT)
		{
			if(astrcat(fingerprints, sb->path.buf, __func__))
				break;
			sbuf_free_content(sb);
		}
		else
		{
			iobuf_log_unexpected(&sb->path, __func__);
			break;
		}
	}

error:
	return -1;
}
Esempio n. 14
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;
}
Esempio n. 15
0
File: msg.c Progetto: pkdevbox/burp
static DWORD WINAPI read_efs(PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength)
{
	struct iobuf *rbuf;
	struct winbuf *mybuf=(struct winbuf *)pvCallbackContext;
	rbuf=mybuf->asfd->rbuf;

	while(1)
	{
		if(mybuf->asfd->read(mybuf->asfd))
			return ERROR_FUNCTION_FAILED;
		(*(mybuf->rcvd))+=rbuf->len;

		switch(rbuf->cmd)
		{
			case CMD_APPEND:
				memcpy(pbData, rbuf->buf, rbuf->len);
				*ulLength=(ULONG)rbuf->len;
				(*(mybuf->sent))+=rbuf->len;
				iobuf_free_content(rbuf);
				return ERROR_SUCCESS;
			case CMD_END_FILE:
				*ulLength=0;
				iobuf_free_content(rbuf);
				return ERROR_SUCCESS;
			case CMD_MESSAGE:
				logp("MESSAGE: %s\n", rbuf->buf);
				cntr_add(mybuf->cntr, rbuf->cmd, 0);
				iobuf_free_content(rbuf);
				continue;
			case CMD_WARNING:
				logp("WARNING: %s\n", rbuf->buf);
				cntr_add(mybuf->cntr, rbuf->cmd, 0);
				iobuf_free_content(rbuf);
				continue;
			default:
				iobuf_log_unexpected(rbuf, __func__);
				iobuf_free_content(rbuf);
				break;
		}
	}
	return ERROR_FUNCTION_FAILED;
}
Esempio n. 16
0
static int get_meta(
	struct asfd *asfd,
	struct cntr *cntr,
	char **metadata,
	size_t *metalen)
{
	int ret=-1;
	struct iobuf *rbuf=asfd->rbuf;

	while(1)
	{
		iobuf_free_content(rbuf);
		if(asfd->read(asfd))
			goto end;

		switch(rbuf->cmd)
		{
			case CMD_DATA:
				if(!(*metadata=(char *)realloc_w(*metadata,
					(*metalen)+rbuf->len, __func__)))
						goto end;
				memcpy((*metadata)+(*metalen),
					rbuf->buf, rbuf->len);
				*metalen+=rbuf->len;
				break;
			case CMD_END_FILE:
				ret=0;
				goto end;
			case CMD_MESSAGE:
			case CMD_WARNING:
				log_recvd(rbuf, cntr, 0);
				break;
			default:
				iobuf_log_unexpected(rbuf, __func__);
				goto end;
		}
	}

end:
	iobuf_free_content(rbuf);
	return ret;
}
Esempio n. 17
0
File: main.c Progetto: scosu/burp
static enum asl_ret maybe_check_timer_func(struct asfd *asfd,
	struct conf **confs, void *param)
{
	int complen=0;
	struct tchk *tchk=(struct tchk *)param;

	if(!strcmp(asfd->rbuf->buf, "timer conditions not met"))
	{
		logp("Timer conditions on the server were not met\n");
		tchk->ret=CLIENT_SERVER_TIMER_NOT_MET;
		return ASL_END_OK;
	}
	else if(!strcmp(asfd->rbuf->buf, "timer conditions met"))
	{
		// Only happens on 'timer check only'.
		logp("Timer conditions on the server were met\n");
		tchk->ret=CLIENT_OK;
		return ASL_END_OK;
	}

	if(!strncmp_w(asfd->rbuf->buf, "ok"))
		complen=3;
	else if(!strncmp_w(asfd->rbuf->buf, "resume"))
	{
		complen=7;
		tchk->resume=1;
		logp("server wants to resume previous backup.\n");
	}
	else
	{
		iobuf_log_unexpected(asfd->rbuf, __func__);
		return ASL_END_ERROR;
	}

	// The server now tells us the compression level in the OK response.
	if(strlen(asfd->rbuf->buf)>3)
		set_int(confs[OPT_COMPRESSION], atoi(asfd->rbuf->buf+complen));
	logp("Compression level: %d\n",
		get_int(confs[OPT_COMPRESSION]));

	return ASL_END_OK;
}
Esempio n. 18
0
static int deal_with_read_from_chfd(struct asfd *asfd, struct asfd *chfd,
	struct blist *blist, uint64_t *wrap_up, struct dpth *dpth)
{
	int ret=-1;
	uint64_t file_no;
	char *save_path;

	// Deal with champ chooser read here.
	//printf("read from cc: %s\n", chfd->rbuf->buf);
	switch(chfd->rbuf->cmd)
	{
		case CMD_SIG:
			// Get these for blks that the champ chooser has found.
			file_no=decode_file_no_and_save_path(chfd->rbuf,
				&save_path);
		//	printf("got save_path: %d %s\n", file_no, save_path);
			if(mark_up_to_index(blist, file_no, dpth)) goto end;
			mark_got(blist->blk_from_champ_chooser, save_path);
//			printf("after mark_got: %d\n",
//				blist->blk_from_champ_chooser->index);
			break;
		case CMD_WRAP_UP:
			file_no=decode_file_no(chfd->rbuf);
	//		printf("mark up to: %d\n", file_no);
			if(mark_up_to_index(blist, file_no, dpth)) goto end;
			mark_not_got(blist->blk_from_champ_chooser, dpth);

			//printf("after mark_up: %d\n",
			//	blist->blk_from_champ_chooser->index);
			break;
		default:
			iobuf_log_unexpected(chfd->rbuf, __func__);
			goto end;
	}
	ret=0;
end:
	iobuf_free_content(chfd->rbuf);
	return ret;
}
Esempio n. 19
0
File: ca.c Progetto: vanElden/burp
static enum asl_ret csr_server_func(struct asfd *asfd,
	struct conf **confs, void *param)
{
	static const char **client;
	static struct iobuf *rbuf;
	const char *ca_conf=get_string(confs[OPT_CA_CONF]);
	client=(const char **)param;
	rbuf=asfd->rbuf;
	if(!strcmp(rbuf->buf, "csr"))
	{
		// Client wants to sign a certificate.
		logp("Client %s wants a certificate signed\n", *client);
		if(!ca_conf || !gca_dir)
		{
			logp("But server is not configured to sign client certificate requests.\n");
			logp("See option 'ca_conf'.\n");
			asfd->write_str(asfd, CMD_ERROR,
			  "server not configured to sign client certificates");
			return ASL_END_ERROR;
		}
		if(sign_client_cert(asfd, *client, confs))
			return ASL_END_ERROR;
		return ASL_END_OK;
	}
	else if(!strcmp(rbuf->buf, "nocsr"))
	{
		// Client does not want to sign a certificate.
		// No problem, just carry on.
		logp("Client %s does not want a certificate signed\n", *client);
		if(asfd->write_str(asfd, CMD_GEN, "nocsr ok"))
			return ASL_END_ERROR;
		return ASL_END_OK;
	}
	else
	{
		iobuf_log_unexpected(rbuf, __func__);
		return ASL_END_ERROR;
	}
}
Esempio n. 20
0
int authorise_server(struct asfd *asfd,
	struct conf **globalcs, struct conf **cconfs)
{
	int ret=-1;
	char *cp=NULL;
	char *password=NULL;
	char *cname=NULL;
	char whoareyou[256]="";
	struct iobuf *rbuf=asfd->rbuf;
	const char *peer_version=NULL;
	if(asfd->read(asfd))
	{
		logp("unable to read initial message\n");
		goto end;
	}
	if(rbuf->cmd!=CMD_GEN || strncmp_w(rbuf->buf, "hello"))
	{
		iobuf_log_unexpected(rbuf, __func__);
		goto end;
	}
	// String may look like...
	// "hello"
	// "hello:(version)"
	// (version) is a version number
	if((cp=strchr(rbuf->buf, ':')))
	{
		cp++;
		if(cp && set_string(cconfs[OPT_PEER_VERSION], cp))
			goto end;
	}
	iobuf_free_content(rbuf);

	snprintf(whoareyou, sizeof(whoareyou), "whoareyou");
	peer_version=get_string(cconfs[OPT_PEER_VERSION]);
	if(peer_version)
	{
		long min_ver=0;
		long cli_ver=0;
		if((min_ver=version_to_long("1.3.2"))<0
		  || (cli_ver=version_to_long(peer_version))<0)
			return -1;
		// Stick the server version on the end of the whoareyou string.
		// if the client version is recent enough.
		if(min_ver<=cli_ver)
		 snprintf(whoareyou, sizeof(whoareyou),
			"whoareyou:%s", VERSION);
	}

	if(asfd->write_str(asfd, CMD_GEN, whoareyou)
	  || asfd->read(asfd))
	{
		logp("unable to get client name\n");
		goto end;
	}

	if(!(cname=strdup_w(rbuf->buf, __func__)))
		goto end;
	if(!get_int(globalcs[OPT_CNAME_FQDN]))
		strip_fqdn(&cname);
	if(get_int(globalcs[OPT_CNAME_LOWERCASE]))
		strlwr(cname);

	if(set_string(cconfs[OPT_CNAME], cname))
		goto end;
	iobuf_free_content(rbuf);

	if(asfd->write_str(asfd, CMD_GEN, "okpassword")
	  || asfd->read(asfd))
	{
		logp("unable to get password for client %s\n",
			get_string(cconfs[OPT_CNAME]));
		goto end;
	}
	password=rbuf->buf;
	iobuf_init(rbuf);

	if(check_client_and_password(globalcs, password, cconfs))
		goto end;

	if(get_int(cconfs[OPT_VERSION_WARN]))
		version_warn(asfd, globalcs, cconfs);

	logp("auth ok for: %s%s\n", get_string(cconfs[OPT_CNAME]),
		get_int(cconfs[OPT_PASSWORD_CHECK])?
			"":" (no password needed)");

	if(asfd->write_str(asfd, CMD_GEN, "ok"))
		goto end;

	ret=0;
end:
	iobuf_free_content(rbuf);
	free_w(&password);
	free_w(&cname);
	return ret;
}
Esempio n. 21
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;
}
Esempio n. 22
0
static int deal_with_read(struct iobuf *rbuf, struct slist *slist,
	struct cntr *cntr, uint8_t *end_flags, struct dpth *dpth)
{
	int ret=0;

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

		/* Incoming block signatures. */
		case CMD_ATTRIBS_SIGS:
			static struct iobuf attr;
			static uint64_t index;

			iobuf_init(&attr);
			iobuf_move(&attr, rbuf);
			index=decode_file_no(&attr);

			// Need to go through slist to find the matching
			// entry.
			if(set_up_for_sig_info(slist, &attr, index))
				goto error;
			return 0;
		case CMD_SIG:
			if(add_to_sig_list(slist, rbuf))
				goto error;
			goto end;

		/* Incoming control/message stuff. */
		case CMD_MESSAGE:
		case CMD_WARNING:
		{
			struct cntr *cntr=NULL;
			log_recvd(rbuf, cntr, 0);
			goto end;
		}
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "sigs_end"))
			{
				(*end_flags)|=END_SIGS;
				goto end;
			}
			else if(!strcmp(rbuf->buf, "backup_end"))
			{
				(*end_flags)|=END_BACKUP;
				goto end;
			}
			break;
		case CMD_INTERRUPT:
		{
			uint64_t file_no;
			file_no=base64_to_uint64(rbuf->buf);
			if(slist_del_sbuf_by_index(slist, file_no))
				goto error;
			goto end;
		}
		default:
			break;
	}

	iobuf_log_unexpected(rbuf, __func__);
error:
	ret=-1;
end:
	iobuf_free_content(rbuf);
	return ret;
}
Esempio n. 23
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;
}
Esempio n. 24
0
static int unexpected(struct iobuf *rbuf, const char *func)
{
	iobuf_log_unexpected(rbuf, func);
	iobuf_free_content(rbuf);
	return -1;
}
Esempio n. 25
0
File: auth.c Progetto: Lacoste/burp
int authorise_client(struct asfd *asfd,
	char **server_version, const char *cname, const char *password,
	struct cntr *cntr)
{
	int ret=-1;
	char hello[256]="";
	struct iobuf *rbuf=asfd->rbuf;

	snprintf(hello, sizeof(hello), "hello:%s", VERSION);
	if(asfd->write_str(asfd, CMD_GEN, hello))
	{
		logp("problem with auth\n");
		goto end;
	}

	if(asfd->read(asfd)
	  || rbuf->cmd!=CMD_GEN
	  || strncmp_w(rbuf->buf, "whoareyou"))
	{
		logp("problem with auth\n");
		goto end;
	}
	if(rbuf->buf)
	{
		char *cp=NULL;
		if((cp=strchr(rbuf->buf, ':')))
		{
			cp++;
			if(cp && !(*server_version=strdup_w(cp, __func__)))
				goto end;
		}
		iobuf_free_content(rbuf);
	}

	if(asfd->write_str(asfd, CMD_GEN, cname)
	  || asfd_read_expect(asfd, CMD_GEN, "okpassword")
	  || asfd->write_str(asfd, CMD_GEN, password)
	  || asfd->read(asfd))
	{
		logp("problem with auth\n");
		goto end;
	}

	if(rbuf->cmd==CMD_WARNING) // special case for the version warning
	{
		//logw(conf->p1cntr, rbuf->buf);
		logp("WARNING: %s\n", rbuf->buf);
		cntr_add(cntr, rbuf->cmd, 0);
		iobuf_free_content(rbuf);
		if(asfd->read(asfd))
		{
			logp("problem with auth\n");
			goto end;
		}
	}
	if(rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "ok"))
	{
		// It is OK.
		logp("auth ok\n");
	}
	else
	{
		iobuf_log_unexpected(rbuf, __func__);
		goto end;
	}

	ret=0;
end:
	iobuf_free_content(rbuf);
	return ret;
}
Esempio n. 26
0
static int extra_comms_read(struct async *as,
	struct vers *vers, int *srestore,
	char **incexc, struct conf **globalcs, struct conf **cconfs)
{
	int ret=-1;
	struct asfd *asfd;
	struct iobuf *rbuf;
	asfd=as->asfd;
	rbuf=asfd->rbuf;

	while(1)
	{
		iobuf_free_content(rbuf);
		if(asfd->read(asfd)) goto end;

		if(rbuf->cmd!=CMD_GEN)
		{
			iobuf_log_unexpected(rbuf, __func__);
			goto end;
		}

		if(!strcmp(rbuf->buf, "extra_comms_end"))
		{
			if(asfd->write_str(asfd, CMD_GEN, "extra_comms_end ok"))
				goto end;
			break;
		}
		else if(!strncmp_w(rbuf->buf, "autoupgrade:"))
		{
			char *os=NULL;
			const char *autoupgrade_dir=
				get_string(globalcs[OPT_AUTOUPGRADE_DIR]);
			os=rbuf->buf+strlen("autoupgrade:");
			iobuf_free_content(rbuf);
			if(os && *os && autoupgrade_server(as, vers->ser,
				vers->cli, os, get_cntr(globalcs),
				autoupgrade_dir))
					goto end;
		}
		else if(!strcmp(rbuf->buf, "srestore ok"))
		{
			iobuf_free_content(rbuf);
			// Client can accept the restore.
			// Load the restore config, then send it.
			*srestore=1;
			if(conf_parse_incexcs_path(cconfs,
				get_string(cconfs[OPT_RESTORE_PATH]))
			  || incexc_send_server_restore(asfd, cconfs))
				goto end;
			// Do not unlink it here - wait until
			// the client says that it wants to do the
			// restore.
			// Also need to leave it around if the
			// restore is to an alternative client, so
			// that the code below that reloads the config
			// can read it again.
			//unlink(get_string(cconfs[OPT_RESTORE_PATH]));
		}
		else if(!strcmp(rbuf->buf, "srestore not ok"))
		{
			const char *restore_path=get_string(
				cconfs[OPT_RESTORE_PATH]);
			// Client will not accept the restore.
			unlink(restore_path);
			if(set_string(cconfs[OPT_RESTORE_PATH], NULL))
				goto end;
			logp("Client not accepting server initiated restore.\n");
		}
		else if(!strcmp(rbuf->buf, "sincexc ok"))
		{
			// Client can accept incexc conf from the
			// server.
			iobuf_free_content(rbuf);
			if(incexc_send_server(asfd, cconfs)) goto end;
		}
		else if(!strcmp(rbuf->buf, "incexc"))
		{
			// Client is telling server its incexc
			// configuration so that it can better decide
			// what to do on resume.
			iobuf_free_content(rbuf);
			if(incexc_recv_server(asfd, incexc, globalcs)) goto end;
			if(*incexc)
			{
				char *tmp=NULL;
				char comp[32]="";
				snprintf(comp, sizeof(comp),
					"compression = %d\n",
					get_int(cconfs[OPT_COMPRESSION]));
				if(!(tmp=prepend(*incexc, comp)))
					goto end;
				free_w(incexc);
				*incexc=tmp;
			}
		}
		else if(!strcmp(rbuf->buf, "countersok"))
		{
			// Client can accept counters on
			// resume/verify/restore.
			logp("Client supports being sent counters.\n");
			set_int(cconfs[OPT_SEND_CLIENT_CNTR], 1);
		}
		else if(!strncmp_w(rbuf->buf, "uname=")
		  && strlen(rbuf->buf)>strlen("uname="))
		{
			char *uname=rbuf->buf+strlen("uname=");
			if(!strncasecmp("Windows", uname, strlen("Windows")))
				set_int(cconfs[OPT_CLIENT_IS_WINDOWS], 1);
		}
		else if(!strncmp_w(rbuf->buf, "orig_client=")
		  && strlen(rbuf->buf)>strlen("orig_client="))
		{
			if(conf_switch_to_orig_client(globalcs, cconfs,
				rbuf->buf+strlen("orig_client=")))
					goto end;
			// If this started out as a server-initiated
			// restore, need to load the restore file
			// again.
			if(*srestore)
			{
				if(conf_parse_incexcs_path(cconfs,
					get_string(cconfs[OPT_RESTORE_PATH])))
						goto end;
			}
			if(asfd->write_str(asfd, CMD_GEN, "orig_client ok"))
				goto end;
		}
		else if(!strncmp_w(rbuf->buf, "restore_spool="))
		{
			// Client supports temporary spool directory
			// for restores.
			if(set_string(cconfs[OPT_RESTORE_SPOOL],
				rbuf->buf+strlen("restore_spool=")))
					goto end;
		}
		else if(!strncmp_w(rbuf->buf, "protocol="))
		{
			char msg[128]="";
			// Client wants to set protocol.
			enum protocol protocol=get_protocol(cconfs);
			if(protocol!=PROTO_AUTO)
			{
				snprintf(msg, sizeof(msg), "Client is trying to use protocol=%s but server is set to protocol=%d\n", rbuf->buf, protocol);
				log_and_send_oom(asfd, __func__);
				goto end;
			}
			else if(!strcmp(rbuf->buf+strlen("protocol="), "1"))
			{
				set_protocol(cconfs, PROTO_1);
				set_protocol(globalcs, PROTO_1);
			}
			else if(!strcmp(rbuf->buf+strlen("protocol="), "2"))
			{
				set_protocol(cconfs, PROTO_2);
				set_protocol(globalcs, PROTO_2);
			}
			else
			{
				snprintf(msg, sizeof(msg), "Client is trying to use protocol=%s, which is unknown\n", rbuf->buf);
				log_and_send_oom(asfd, __func__);
				goto end;
			}
			logp("Client has set protocol=%d\n",
				(int)get_protocol(cconfs));
		}
		else if(!strncmp_w(rbuf->buf, "rshash=blake2"))
		{
#ifdef RS_DEFAULT_STRONG_LEN
			logp("Client is trying to use librsync hash blake2, but server does not support it.\n");
			goto end;
#else
			set_e_rshash(cconfs[OPT_RSHASH], RSHASH_BLAKE2);
			set_e_rshash(globalcs[OPT_RSHASH], RSHASH_BLAKE2);
#endif
		}
		else if(!strncmp_w(rbuf->buf, "msg"))
		{
			set_int(cconfs[OPT_MESSAGE], 1);
			set_int(globalcs[OPT_MESSAGE], 1);
		}
		else
		{
			iobuf_log_unexpected(rbuf, __func__);
			goto end;
		}
	}

	ret=0;
end:
	iobuf_free_content(rbuf);
	return ret;
}
Esempio n. 27
0
static int deal_with_read(struct iobuf *rbuf, struct slist *slist,
	struct cntr *cntr, uint8_t *end_flags)
{
	int ret=0;
	switch(rbuf->cmd)
	{
		/* Incoming file request. */
		case CMD_FILE:
		case CMD_METADATA:
			if(add_to_file_requests(slist, rbuf)) goto error;
			return 0;

		/* Incoming data block request. */
		case CMD_DATA_REQ:
			if(add_to_data_requests(slist->blist, rbuf)) goto error;
			goto end;

		/* Incoming control/message stuff. */
		case CMD_WRAP_UP:
		{
			int64_t wrap_up;
			struct blk *blk;
			struct blist *blist=slist->blist;
			from_base64(&wrap_up, rbuf->buf);
			for(blk=blist->head; blk; blk=blk->next)
			{
				if(blk->index==(uint64_t)wrap_up)
				{
					blist->last_requested=blk;
					blist->last_sent=blk;
					break;
				}
			}
			if(!blk)
			{
				logp("Could not find wrap up index: %016" PRIX64 "\n",
					wrap_up);
//				goto error;
			}
			goto end;
		}
		case CMD_MESSAGE:
		case CMD_WARNING:
		{
			log_recvd(rbuf, cntr, 0);
			goto end;
		}
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "requests_end"))
			{
				(*end_flags)|=END_REQUESTS;
				goto end;
			}
			else if(!strcmp(rbuf->buf, "blk_requests_end"))
			{
				(*end_flags)|=END_BLK_REQUESTS;
				goto end;
			}
			else if(!strcmp(rbuf->buf, "backup_end"))
			{
				(*end_flags)|=END_BACKUP;
				goto end;
			}
			break;
		default:
			break;
	}

	iobuf_log_unexpected(rbuf, __func__);
error:
	ret=-1;
end:
	iobuf_free_content(rbuf);
	return ret;
}
Esempio n. 28
0
static int unknown_command(struct asfd *asfd)
{
	iobuf_log_unexpected(asfd->rbuf, __func__);
	asfd->write_str(asfd, CMD_ERROR, "unknown command");
	return -1;
}
Esempio n. 29
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;
}
Esempio n. 30
0
int authorise_server(struct asfd *asfd, struct conf *conf, struct conf *cconf)
{
	int ret=-1;
	char *cp=NULL;
	char *password=NULL;
	char whoareyou[256]="";
	struct iobuf *rbuf=asfd->rbuf;
	if(asfd->read(asfd))
	{
		logp("unable to read initial message\n");
		goto end;
	}
	if(rbuf->cmd!=CMD_GEN || strncmp_w(rbuf->buf, "hello"))
	{
		iobuf_log_unexpected(rbuf, __func__);
		goto end;
	}
	// String may look like...
	// "hello"
	// "hello:(version)"
	// (version) is a version number
	if((cp=strchr(rbuf->buf, ':')))
	{
		cp++;
		if(cp && !(cconf->peer_version=strdup_w(cp, __func__)))
			goto end;
	}
	iobuf_free_content(rbuf);

	snprintf(whoareyou, sizeof(whoareyou), "whoareyou");
	if(cconf->peer_version)
	{
		long min_ver=0;
		long cli_ver=0;
		if((min_ver=version_to_long("1.3.2"))<0
		  || (cli_ver=version_to_long(cconf->peer_version))<0)
			return -1;
		// Stick the server version on the end of the whoareyou string.
		// if the client version is recent enough.
		if(min_ver<=cli_ver)
		 snprintf(whoareyou, sizeof(whoareyou),
			"whoareyou:%s", VERSION);
	}

	asfd->write_str(asfd, CMD_GEN, whoareyou);
	if(asfd->read(asfd))
	{
		logp("unable to get client name\n");
		goto end;
	}
	cconf->cname=rbuf->buf;
	iobuf_init(rbuf);

	asfd->write_str(asfd, CMD_GEN, "okpassword");
	if(asfd->read(asfd))
	{
		logp("unable to get password for client %s\n", cconf->cname);
		goto end;
	}
	password=rbuf->buf;
	iobuf_init(rbuf);

	if(check_client_and_password(conf, password, cconf))
		goto end;

	if(cconf->version_warn) version_warn(asfd, conf, cconf);

	logp("auth ok for: %s%s\n", cconf->cname,
		cconf->password_check?"":" (no password needed)");

	asfd->write_str(asfd, CMD_GEN, "ok");

	ret=0;
end:
	iobuf_free_content(rbuf);
	free_w(&password);
	return ret;
}