imap-urlauth-fetch.c revision 96fbbe9c6fd04bca25770020bf94eec50888bc9b
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen /* local urls */
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen struct imap_urlauth_fetch_url *local_urls_head, *local_urls_tail;
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainenstatic void imap_urlauth_fetch_abort_local(struct imap_urlauth_fetch *ufetch)
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen struct imap_urlauth_fetch_url *url, *url_next;
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen i_free_and_null(ufetch->pending_reply.bodypartstruct);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->local_urls_head = ufetch->local_urls_tail = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void imap_urlauth_fetch_abort(struct imap_urlauth_fetch *ufetch)
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen imap_urlauth_request_abort_by_context(ufetch->uctx->conn, ufetch);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void imap_urlauth_fetch_fail(struct imap_urlauth_fetch *ufetch)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenimap_urlauth_fetch_init(struct imap_urlauth_context *uctx,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen imap_urlauth_fetch_callback_t *callback, void *context)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenvoid imap_urlauth_fetch_deinit(struct imap_urlauth_fetch **_ufetch)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenimap_urlauth_fetch_error(struct imap_urlauth_fetch *ufetch, const char *url,
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen ret = ufetch->callback(&reply, ufetch->pending_requests == 0,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen else if (ret < 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenimap_urlauth_fetch_local(struct imap_urlauth_fetch *ufetch, const char *url,
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen const char *error, *errormsg = NULL, *bpstruct = NULL;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen bool debug = ufetch->uctx->user->mail_debug, success;
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen /* fetch URL */
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen ret = imap_urlauth_fetch_parsed(ufetch->uctx, imap_url,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen errormsg = t_strdup_printf("Failed to fetch URLAUTH \"%s\": %s",
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen /* fetch metadata */
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (success && (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (url_flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ret = imap_msgpart_url_get_bodypartstructure(mpurl, &bpstruct, &error);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen ("Failed to read URLAUTH \"%s\": %s", url, error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen /* if requested, read the message part the URL points to */
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen if (success && ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BODY) != 0 ||
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0)) {
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen ret = imap_msgpart_url_read_part(mpurl, &mpresult, &error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ("Failed to read URLAUTH \"%s\": %s", url, error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_debug("Fetched URLAUTH yielded BODYPARTSTRUCTURE (%s)", bpstruct);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (mpresult.size == 0 || mpresult.input == NULL)
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen i_debug("Fetched URLAUTH yielded empty result");
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen i_debug("Fetched URLAUTH yielded %"PRIuUOFF_T" bytes "
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (mpresult.binary_decoded_input_has_nuls ? "binary " : ""));
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen (void)ufetch->callback(NULL, TRUE, ufetch->context);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen reply.binary_has_nuls = mpresult.binary_decoded_input_has_nuls;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ret = ufetch->callback(&reply, ufetch->pending_requests == 1,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainenimap_urlauth_fetch_request_callback(struct imap_urlauth_fetch_reply *reply,
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.url = i_strdup(reply->url);
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.error = i_strdup(reply->error);
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.succeeded = reply->succeeded;
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.binary_has_nuls = reply->binary_has_nuls;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen bool last = ufetch->pending_requests == 0 || reply == NULL;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen ret = ufetch->callback(reply, last, ufetch->context);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen /* report failure only once */
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainenint imap_urlauth_fetch_url(struct imap_urlauth_fetch *ufetch, const char *url,
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen struct imap_urlauth_context *uctx = ufetch->uctx;
f0f9c8e94abac18f8acd91b9e724c4c32863723aTimo Sirainen /* parse the url */
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (imap_url_parse(url, NULL, url_parse_flags, &imap_url, &error) < 0) {
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen "Failed to fetch URLAUTH \"%s\": %s", url, error);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen imap_urlauth_fetch_error(ufetch, url, url_flags, errormsg);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen /* if access user and target user match, handle fetch request locally */
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen strcmp(mail_user->username, imap_url->userid) == 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen url_local = i_new(struct imap_urlauth_fetch_url, 1);
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen /* don't try to fetch remote URLs that are already known to fail access */
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen } else if (!imap_urlauth_check(uctx, imap_url, TRUE, &error)) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen "Failed to fetch URLAUTH \"%s\": %s", url, error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen imap_urlauth_fetch_error(ufetch, url, url_flags, errormsg);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen /* create request for url */
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen if (imap_url != NULL && imap_url->userid != NULL) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (void)imap_urlauth_request_new(uctx->conn, imap_url->userid,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (imap_urlauth_connection_connect(uctx->conn) < 0)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return (ufetch->pending_requests > 0 ? 0 : 1);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainenbool imap_urlauth_fetch_continue(struct imap_urlauth_fetch *ufetch)
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen struct imap_urlauth_fetch_url *url, *url_next;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen /* not waiting for local request handling */
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen imap_urlauth_connection_continue(ufetch->uctx->conn);
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen /* handle pending remote reply */
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.bodypartstruct = ufetch->pending_reply.bodypartstruct;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.succeeded = ufetch->pending_reply.succeeded;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.binary_has_nuls = ufetch->pending_reply.binary_has_nuls;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen ret = ufetch->callback(&reply, ufetch->pending_requests == 0,
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (ufetch->pending_reply.bodypartstruct != NULL)
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen imap_urlauth_connection_continue(ufetch->uctx->conn);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen /* handle pending local urls */