/* 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)); }
/* User state. */ int imap_state_user(struct account *a, struct fetch_ctx *fctx) { struct fetch_imap_data *data = a->data; char *line; int tag; if (data->capa & IMAP_CAPA_NOSPACE) { if (imap_getln(a, fctx, IMAP_CONTINUE, &line) != 0) return (FETCH_ERROR); if (line == NULL) return (FETCH_BLOCK); } else { for (;;) { if (imap_getln(a, fctx, IMAP_RAW, &line) != 0) return (FETCH_ERROR); if (line == NULL) return (FETCH_BLOCK); tag = imap_tag(line); if (tag == IMAP_TAG_NONE) continue; if (tag == IMAP_TAG_CONTINUE || tag == data->tag) break; return (FETCH_ERROR); } if (tag != IMAP_TAG_CONTINUE) { log_debug("%s: didn't accept user (%s); " "trying without space", a->name, line); data->capa |= IMAP_CAPA_NOSPACE; return (imap_pick_auth(a, fctx)); } } if (imap_putln(a, "%s", data->pass) != 0) return (FETCH_ERROR); fctx->state = imap_state_pass; return (FETCH_BLOCK); }
/* 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)); }