int imap_urlauth_fetch_url(struct imap_urlauth_fetch *ufetch, const char *url, enum imap_urlauth_fetch_flags url_flags) { struct imap_urlauth_context *uctx = ufetch->uctx; enum imap_url_parse_flags url_parse_flags = IMAP_URL_PARSE_ALLOW_URLAUTH; struct mail_user *mail_user = uctx->user; struct imap_url *imap_url; const char *error, *errormsg; /* parse the url */ if (imap_url_parse(url, NULL, url_parse_flags, &imap_url, &error) < 0) { errormsg = t_strdup_printf( "Failed to fetch URLAUTH \"%s\": %s", url, error); if (mail_user->mail_debug) i_debug("%s", errormsg); ufetch->pending_requests++; imap_urlauth_fetch_ref(ufetch); imap_urlauth_fetch_error(ufetch, url, url_flags, errormsg); imap_urlauth_fetch_unref(&ufetch); return 1; } return imap_urlauth_fetch_url_parsed(ufetch, url, imap_url, url_flags); }
int imap_urlauth_fetch(struct imap_urlauth_context *uctx, const char *urlauth, struct imap_msgpart_url **mpurl_r, enum mail_error *error_code_r, const char **error_r) { struct imap_url *url; enum imap_url_parse_flags url_flags = IMAP_URL_PARSE_ALLOW_URLAUTH; const char *error; /* validate URL */ if (imap_url_parse(urlauth, NULL, url_flags, &url, &error) < 0) { *error_r = t_strdup_printf("Invalid URLAUTH: %s", error); *error_code_r = MAIL_ERROR_PARAMS; return 0; } return imap_urlauth_fetch_parsed(uctx, url, mpurl_r, error_code_r, error_r); }
int imap_msgpart_url_parse(struct mail_user *user, struct mailbox *selected_box, const char *urlstr, struct imap_msgpart_url **mpurl_r, const char **error_r) { struct mailbox_status box_status; struct imap_url base_url, *url; const char *error; /* build base url */ memset(&base_url, 0, sizeof(base_url)); if (selected_box != NULL) { mailbox_get_open_status(selected_box, STATUS_UIDVALIDITY, &box_status); base_url.mailbox = mailbox_get_vname(selected_box); base_url.uidvalidity = box_status.uidvalidity; } /* parse url */ if (imap_url_parse(urlstr, &base_url, IMAP_URL_PARSE_REQUIRE_RELATIVE, &url, &error) < 0) { *error_r = t_strconcat("Invalid IMAP URL: ", error, NULL); return 0; } if (url->mailbox == NULL) { *error_r = "Mailbox-relative IMAP URL, but no mailbox selected"; return 0; } if (url->uid == 0 || url->search_program != NULL) { *error_r = "Invalid messagepart IMAP URL"; return 0; } if (imap_msgpart_url_create(user, url, mpurl_r, error_r) < 0) return -1; (*mpurl_r)->selected_box = selected_box; return 1; }
int imap_urlauth_generate(struct imap_urlauth_context *uctx, const char *mechanism, const char *rumpurl, const char **urlauth_r, const char **error_r) { struct mail_user *user = uctx->user; enum imap_url_parse_flags url_flags = IMAP_URL_PARSE_ALLOW_URLAUTH; struct imap_url *url; struct imap_msgpart_url *mpurl = NULL; struct mailbox *box; const char *error; enum mail_error error_code; unsigned char mailbox_key[IMAP_URLAUTH_KEY_LEN]; const unsigned char *token; size_t token_len; int ret; /* validate mechanism */ if (strcasecmp(mechanism, "INTERNAL") != 0) { *error_r = t_strdup_printf("Unsupported URLAUTH mechanism: %s", mechanism); return 0; } /* validate URL */ if (imap_url_parse(rumpurl, NULL, url_flags, &url, &error) < 0) { *error_r = t_strdup_printf("Invalid URL: %s", error); return 0; } if (url->mailbox == NULL || url->uid == 0 || url->search_program != NULL || url->uauth_rumpurl == NULL || url->uauth_mechanism != NULL) { *error_r = "Invalid URL: Must be an URLAUTH rump URL"; return 0; } /* validate expiry time */ if (url->uauth_expire != (time_t)-1) { time_t now = time(NULL); if (now > url->uauth_expire) { *error_r = t_strdup_printf("URLAUTH has already expired"); return 0; } } /* validate user */ if (url->userid == NULL) { *error_r = "Invalid URL: Missing user name"; return 0; } if (user->anonymous || strcmp(url->userid, user->username) != 0) { *error_r = t_strdup_printf( "Not permitted to generate URLAUTH for user %s", url->userid); return 0; } /* validate host:port */ if (!imap_urlauth_check_hostport(uctx, url, error_r)) return 0; /* validate mailbox */ if ((ret = imap_msgpart_url_create(user, url, &mpurl, &error)) < 0 || imap_msgpart_url_verify(mpurl, &error) <= 0) { *error_r = t_strdup_printf("Invalid URL: %s", error); if (mpurl != NULL) imap_msgpart_url_free(&mpurl); return ret; } box = imap_msgpart_url_get_mailbox(mpurl); /* obtain mailbox key */ ret = imap_urlauth_backend_get_mailbox_key(box, TRUE, mailbox_key, error_r, &error_code); if (ret < 0) { imap_msgpart_url_free(&mpurl); return ret; } token = imap_urlauth_internal_generate(rumpurl, mailbox_key, &token_len); imap_msgpart_url_free(&mpurl); *urlauth_r = imap_url_add_urlauth(rumpurl, mechanism, token, token_len); return 1; }