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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}