Пример #1
0
static struct status *
status_fromrd(char *path, struct stream *file)
{
	struct status *st;
	char *id, *line;
	time_t scantime;
	int error, ver;

	/* Get the first line of the file and validate it. */
	line = stream_getln(file, NULL);
	if (line == NULL) {
		stream_close(file);
		return (NULL);
	}
	id = proto_get_ascii(&line);
	error = proto_get_int(&line, &ver, 10);
	if (error) {
		stream_close(file);
		return (NULL);
	}
	error = proto_get_time(&line, &scantime);
	if (error || line != NULL) {
		stream_close(file);
		return (NULL);
	}

	if (strcmp(id, "F") != 0 || ver != STATUS_VERSION) {
		stream_close(file);
		return (NULL);
	}

	st = status_new(path, scantime, file);
	st->linenum = 1;
	return (st);
}
Пример #2
0
static int
auth_domd5auth(struct config *config)
{
	struct stream *s;
	char *line, *cmd, *challenge, *realm, *client, *srvresponse, *msg;
	char shrdsecret[MD5_CHARS_MAX], response[MD5_CHARS_MAX];
	char clichallenge[MD5_CHARS_MAX];
	struct srvrecord auth;
	int error;

	lprintf(2, "MD5 authentication started\n");
	s = config->server;
	line = stream_getln(s, NULL);
	cmd = proto_get_ascii(&line);
	realm = proto_get_ascii(&line);
	challenge = proto_get_ascii(&line);
	if (challenge == NULL ||
	    line != NULL ||
	    (strcmp(cmd, "AUTHMD5") != 0)) {
		lprintf(-1, "Invalid server reply to USER\n");
		return (STATUS_FAILURE);
	}

	client = NULL;
	response[0] = clichallenge[0] = '.';
	response[1] = clichallenge[1] = 0;
	if (config->reqauth || (strcmp(challenge, ".") != 0)) {
		if (strcmp(realm, ".") == 0) {
			lprintf(-1, "Authentication required, but not enabled on server\n");
			return (STATUS_FAILURE);
		}
		error = auth_lookuprecord(realm, &auth);
		if (error != STATUS_SUCCESS)
			return (error);
		client = auth.client;
		auth_makesecret(&auth, shrdsecret);
	}

	if (strcmp(challenge, ".") != 0)
		auth_makeresponse(challenge, shrdsecret, response);
	if (config->reqauth)
		auth_makechallenge(config, clichallenge);
	proto_printf(s, "AUTHMD5 %s %s %s\n",
		client == NULL ? "." : client, response, clichallenge);
	stream_flush(s);
	line = stream_getln(s, NULL);
	cmd = proto_get_ascii(&line);
	if (cmd == NULL || line == NULL)
		goto bad;
	if (strcmp(cmd, "OK") == 0) {
		srvresponse = proto_get_ascii(&line);
		if (srvresponse == NULL)
			goto bad;
		if (config->reqauth &&
		    !auth_checkresponse(srvresponse, clichallenge, shrdsecret)) {
			lprintf(-1, "Server failed to authenticate itself to client\n");
			return (STATUS_FAILURE);
		}
		lprintf(2, "MD5 authentication successful\n");
		return (STATUS_SUCCESS);
	}
	if (strcmp(cmd, "!") == 0) {
		msg = proto_get_rest(&line);
		if (msg == NULL)
			goto bad;
		lprintf(-1, "Server error: %s\n", msg);
		return (STATUS_FAILURE);
	}
bad:
	lprintf(-1, "Invalid server reply to AUTHMD5\n");
	return (STATUS_FAILURE);
}
Пример #3
0
static int
statusrec_cook(struct statusrec *sr, char *line)
{
	char *clientattr, *serverattr;

	switch (sr->sr_type) {
	case SR_FILEDEAD:
	case SR_FILELIVE:
		clientattr = proto_get_ascii(&line);
		if (clientattr == NULL || line != NULL)
			return (-1);
		sr->sr_clientattr = fattr_decode(clientattr);
		if (sr->sr_clientattr == NULL)
			return (-1);
		break;
	case SR_DIRDOWN:
		/* Nothing to do. */
		if (line != NULL)
			return (-1);
		break;
	case SR_CHECKOUTLIVE:
		sr->sr_tag = proto_get_ascii(&line);
		sr->sr_date = proto_get_ascii(&line);
		serverattr = proto_get_ascii(&line);
		sr->sr_revnum = proto_get_ascii(&line);
		sr->sr_revdate = proto_get_ascii(&line);
		clientattr = proto_get_ascii(&line);
		if (clientattr == NULL || line != NULL)
			return (-1);
		sr->sr_serverattr = fattr_decode(serverattr);
		if (sr->sr_serverattr == NULL)
			return (-1);
		sr->sr_clientattr = fattr_decode(clientattr);
		if (sr->sr_clientattr == NULL) {
			fattr_free(sr->sr_serverattr);
			return (-1);
		}
		break;
	case SR_CHECKOUTDEAD:
		sr->sr_tag = proto_get_ascii(&line);
		sr->sr_date = proto_get_ascii(&line);
		serverattr = proto_get_ascii(&line);
		if (serverattr == NULL || line != NULL)
			return (-1);
		sr->sr_serverattr = fattr_decode(serverattr);
		if (sr->sr_serverattr == NULL)
			return (-1);
		break;
	case SR_DIRUP:
		clientattr = proto_get_ascii(&line);
		if (clientattr == NULL || line != NULL)
			return (-1);
		sr->sr_clientattr = fattr_decode(clientattr);
		if (sr->sr_clientattr == NULL)
			return (-1);
		break;
	default:
		return (-1);
	}
	return (0);
}
Пример #4
0
static struct statusrec *
status_rdraw(struct status *st, char **linep)
{
	struct statusrec sr;
	char *cmd, *line, *file;

	if (st->rd == NULL || st->eof)
		return (NULL);
	line = stream_getln(st->rd, NULL);
	if (line == NULL) {
		if (stream_eof(st->rd)) {
			if (st->depth != 0) {
				st->error = STATUS_ERR_TRUNC;
				return (NULL);
			}
			st->eof = 1;
			return (NULL);
		}
		st->error = STATUS_ERR_READ;
		st->suberror = errno;
		return (NULL);
	}
	st->linenum++;
	cmd = proto_get_ascii(&line);
	file = proto_get_ascii(&line);
	if (file == NULL || strlen(cmd) != 1) {
		st->error = STATUS_ERR_PARSE;
		return (NULL);
	}

	switch (cmd[0]) {
	case 'A':
		sr.sr_type = SR_FILELIVE;
		break;
	case 'D':
		sr.sr_type = SR_DIRDOWN;
		st->depth++;
		break;
	case 'C':
		sr.sr_type = SR_CHECKOUTLIVE;
		break;
	case 'c':
		sr.sr_type = SR_CHECKOUTDEAD;
		break;
	case 'U':
		sr.sr_type = SR_DIRUP;
		if (st->depth <= 0) {
			st->error = STATUS_ERR_BOGUS_DIRUP;
			return (NULL);
		}
		st->depth--;
		break;
	case 'V':
		sr.sr_type = SR_FILELIVE;
		break;
	case 'v':
		sr.sr_type = SR_FILEDEAD;
		break;
	default:
		st->error = STATUS_ERR_BAD_TYPE;
		st->suberror = cmd[0];
		return (NULL);
	}

	sr.sr_file = xstrdup(file);
	if (st->previous != NULL &&
	    statusrec_cmp(st->previous, &sr) >= 0) {
		st->error = STATUS_ERR_UNSORTED;
		free(sr.sr_file);
		return (NULL);
	}

	if (st->previous == NULL) {
		st->previous = &st->buf;
	} else {
		statusrec_fini(st->previous);
		statusrec_init(st->previous);
	}
	st->previous->sr_type = sr.sr_type;
	st->previous->sr_file = sr.sr_file;
	*linep = line;
	return (st->previous);
}