bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainenstatic void cmd_urlfetch_finish(struct client_command_context *cmd)
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen /* failed in the middle of a literal.
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen we need to disconnect. */
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen client_disconnect(cmd->client, "URLFETCH failed");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_tagline(cmd, "OK URLFETCH completed.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic bool cmd_urlfetch_cancel(struct client_command_context *cmd)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "aborting URLAUTH fetch requests prematurely");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic int cmd_urlfetch_transfer_literal(struct client_command_context *cmd)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* are we in the middle of an urlfetch literal? */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* flush output to client if buffer is filled above optimum */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (o_stream_get_buffer_used_size(client->output) >=
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((ret = o_stream_flush(client->output)) <= 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* transfer literal to client */
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen o_stream_set_max_buffer_size(client->output, 0);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen res = o_stream_send_istream(client->output, ctx->input);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch o_stream_set_max_buffer_size(client->output, (size_t)-1);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen /* client disconnected */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic bool cmd_urlfetch_continue(struct client_command_context *cmd)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* finish a pending literal transfer */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* not finished; apparently output blocked again */
d3a3d31d1eb77c4d040ce77c9cd7babe3003901aStephan Bosch urls_pending = imap_urlauth_fetch_continue(ctx->ufetch);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* waiting for imap urlauth service */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch cmd->state = CLIENT_COMMAND_STATE_WAIT_EXTERNAL;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* retrieve next url */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* finished */
31281f7ff3c17c3971de99cee666bb1c19f85627Aki Tuomistatic int cmd_urlfetch_url_success(struct client_command_context *cmd,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct cmd_urlfetch_context *ctx = cmd->context;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((reply->flags & IMAP_URLAUTH_FETCH_FLAG_EXTENDED) == 0) {
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen str_printfa(response, " {%"PRIuUOFF_T"}", reply->size);
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen client_send_line(cmd->client, str_c(response));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_assert(reply->size == 0 || reply->input != NULL);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* extended */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((reply->flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0 &&
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((reply->flags & IMAP_URLAUTH_FETCH_FLAG_BODY) != 0 ||
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch (reply->flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((reply->flags & IMAP_URLAUTH_FETCH_FLAG_BODY) != 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_printfa(response, "{%"PRIuUOFF_T"}", reply->size);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_assert(reply->size == 0 || reply->input != NULL);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_line(cmd->client, str_c(response));
d04f3e064ceb2ba1d734182937a7115739ebadbeTimo Sirainen ctx->input = i_stream_create_sized(reply->input, reply->size);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* not finished; apparently output blocked */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschcmd_urlfetch_url_callback(struct imap_urlauth_fetch_reply *reply,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct cmd_urlfetch_context *ctx = cmd->context;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* fatal failure */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* URL fetch succeeded */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* URL fetch failed */
dfc3a20b33f265b54746c9c2768b997d5e1cf15eTimo Sirainen if ((last && cmd->state == CLIENT_COMMAND_STATE_WAIT_EXTERNAL) ||
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschcmd_urlfetch_parse_arg(struct client_command_context *cmd,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch url_flags |= IMAP_URLAUTH_FETCH_FLAG_EXTENDED;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* read url */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (!imap_arg_get_astring(params++, &url_text)) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_command_error(cmd, "Invalid arguments.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (!imap_arg_get_atom(params++, &fetch_param)) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "Invalid URL fetch parameter.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch else if (strcasecmp(fetch_param, "BINARY") == 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch else if (strcasecmp(fetch_param, "BODYPARTSTRUCTURE") == 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch url_flags |= IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch t_strdup_printf("Unknown URL fetch parameter: %s",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BODY) != 0 &&
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "URL cannot have both BODY and BINARY fetch parameters.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (url_flags == IMAP_URLAUTH_FETCH_FLAG_EXTENDED)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschbool cmd_urlfetch(struct client_command_context *cmd)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_command_error(cmd, "URLAUTH disabled.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_command_error(cmd, "Invalid arguments.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* parse url arguments and group them per userid */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (cmd_urlfetch_parse_arg(cmd, args, ufurl) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch cmd->context = ctx = p_new(cmd->pool, struct cmd_urlfetch_context, 1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ctx->ufetch = imap_urlauth_fetch_init(client->urlauth_ctx,
620b60321d04006b32a116824d49b88b61be7131Stephan Bosch if (imap_urlauth_fetch_url(ctx->ufetch, url->url, url->flags) < 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* fatal error */
620b60321d04006b32a116824d49b88b61be7131Stephan Bosch if ((ctx->failed || !imap_urlauth_fetch_is_pending(ctx->ufetch))
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* finished */