Exemple #1
0
/* Capability state 2. Check capabilities and choose login type. */
int
imap_state_capability2(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	if (data->starttls) {
		if (!(data->capa & IMAP_CAPA_STARTTLS)) {
			log_warnx("%s: server doesn't support STARTTLS",
			    a->name);
			return (FETCH_ERROR);
		}
		if (imap_putln(a, "%u STARTTLS", ++data->tag) != 0)
			return (FETCH_ERROR);
		fctx->state = imap_state_starttls;
		return (FETCH_BLOCK);
	}

	return (imap_pick_auth(a, fctx));
}
Exemple #2
0
/* Search state 3. */
int
imap_state_search3(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	/* Save the total. */
	data->total = ARRAY_LENGTH(&data->wanted);

	/* Update grand total. */
	data->folders_total += data->total;

	/* If no mails, or polling, stop here. */
	if (data->total == 0 || fctx->flags & FETCH_POLL) {
		if (imap_putln(a, "%u CLOSE", ++data->tag) != 0)
			return (FETCH_ERROR);
		fctx->state = imap_state_close;
		return (FETCH_BLOCK);
	}

	fctx->state = imap_state_next;
	return (FETCH_AGAIN);
}
Exemple #3
0
/* Search state 2. */
int
imap_state_search2(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line, *ptr;
	u_int			 uid;

	if (imap_getln(a, fctx, IMAP_UNTAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);

	/* Skip the header. */
	if (strncasecmp(line, "* SEARCH", 8) != 0)
		return (imap_bad(a, line));
	line += 8;

	/* Read each UID and save it. */
	do {
		while (isspace((u_char) *line))
			line++;
		ptr = strchr(line, ' ');
		if (ptr == NULL)
			ptr = strchr(line, '\0');
		if (ptr == line)
			break;

		if (sscanf(line, "%u", &uid) != 1)
			return (imap_bad(a, line));
		ARRAY_ADD(&data->wanted, uid);
		log_debug3("%s: fetching UID: %u", a->name, uid);

		line = ptr;
	} while (*line == ' ');

	fctx->state = imap_state_search3;
	return (FETCH_AGAIN);
}
Exemple #4
0
/* Expunge state. */
int
imap_state_expunge(struct account *a, struct fetch_ctx *fctx)
{
	char	*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	fctx->state = imap_state_next;
	return (FETCH_AGAIN);
}
Exemple #5
0
/* Quit state. */
int
imap_state_quit(struct account *a, struct fetch_ctx *fctx)
{
	char	*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	imap_abort(a);
	return (FETCH_EXIT);
}
Exemple #6
0
/* Wait for okay. */
int
deliver_imap_waitokay(struct account *a, struct fetch_ctx *fctx, struct io *io,
    char **line)
{
	do {
		if (deliver_imap_poll(a, io) != 0)
			return (1);
		if (imap_getln(a, fctx, IMAP_TAGGED, line) != 0)
			return (1);
	} while (*line == NULL);

	if (!imap_okay(*line)) {
		imap_bad(a, *line);
		return (1);
	}
	return (0);
}
Exemple #7
0
/* Commit state. */
int
imap_state_commit(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	data->committed++;

	fctx->state = imap_state_next;
	return (FETCH_AGAIN);
}
Exemple #8
0
/* Mail state. */
int
imap_state_mail(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char	*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	if (data->capa & IMAP_CAPA_GMEXT) {
		fctx->state = imap_state_gmext_start;
		return (FETCH_AGAIN);
	}

	fctx->state = imap_state_next;
	return (FETCH_MAIL);
}
Exemple #9
0
/* STARTTLS state. */
int
imap_state_starttls(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line, *cause;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	data->io->ssl = makessl(&data->server, data->io->fd,
	    conf.verify_certs && data->server.verify, conf.timeout, &cause);
	if (data->io->ssl == NULL) {
		log_warnx("%s: STARTTLS failed: %s", a->name, cause);
		xfree(cause);
		return (FETCH_ERROR);
	}

	return (imap_pick_auth(a, fctx));
}
Exemple #10
0
/*
 * Parse line based on type. Returns -1 on error, 0 on success, 1 to ignore
 * this line.
 */
int
imap_parse(struct account *a, int type, char *line)
{
	struct fetch_imap_data	*data = a->data;
	int			 tag;

	if (type == IMAP_RAW)
		return (0);

	tag = imap_tag(line);
	switch (type) {
	case IMAP_TAGGED:
		if (tag == IMAP_TAG_NONE)
			return (1);
		if (tag == IMAP_TAG_CONTINUE)
			goto invalid;
		if (tag != data->tag)
			goto invalid;
		break;
	case IMAP_UNTAGGED:
		if (tag != IMAP_TAG_NONE)
			goto invalid;
		break;
	case IMAP_CONTINUE:
		if (tag == IMAP_TAG_NONE)
			return (1);
		if (tag != IMAP_TAG_CONTINUE)
			goto invalid;
		break;
	}

	return (0);

invalid:
	imap_bad(a, line);
	return (-1);
}
Exemple #11
0
/* Close state. */
int
imap_state_close(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	data->folder++;
	if (data->folder != ARRAY_LENGTH(data->folders)) {
		fctx->state = imap_state_select1;
		return (FETCH_AGAIN);
	}

	if (imap_putln(a, "%u LOGOUT", ++data->tag) != 0)
		return (FETCH_ERROR);
	fctx->state = imap_state_quit;
	return (FETCH_BLOCK);
}
Exemple #12
0
/* Select state 4. Hold until select completes. */
int
imap_state_select4(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	/* If no mails, stop early. */
	if (data->total == 0) {
		if (imap_putln(a, "%u CLOSE", ++data->tag) != 0)
			return (FETCH_ERROR);
		fctx->state = imap_state_close;
		return (FETCH_BLOCK);
	}

	fctx->state = imap_state_search1;
	return (FETCH_AGAIN);
}