diff --git a/changes/next/imap_jmapaccess b/changes/next/imap_jmapaccess index 1b6a27a1d6..b668ee4853 100644 --- a/changes/next/imap_jmapaccess +++ b/changes/next/imap_jmapaccess @@ -1,7 +1,7 @@ Description: -Adds support for IMAP JMAPACCESS response code (draft-ietf-extra-jmapaccess). +Adds support for IMAP JMAPACCESS (draft-ietf-extra-jmapaccess). Config changes: diff --git a/imap/imapd.c b/imap/imapd.c index 393f684347..f67fc88cb1 100644 --- a/imap/imapd.c +++ b/imap/imapd.c @@ -203,8 +203,9 @@ static int imapd_starttls_done = 0; /* have we done a successful starttls? */ static int imapd_tls_required = 0; /* is tls required? */ static void *imapd_tls_comp = NULL; /* TLS compression method, if any */ static int imapd_compress_done = 0; /* have we done a successful compress? */ -static const char *imapd_jmapaccess_url = NULL; static const char *plaintextloginalert = NULL; +static const char *imapd_jmapaccess_url = NULL; +static int imapd_jmapaccess_enabled = 0; static int ignorequota = 0; static int sync_sieve_mailbox_enabled = 0; static int sync_archive_enabled = 0; @@ -418,7 +419,8 @@ static struct capa_struct base_capabilities[] = { { .statep = &imapd_idle_enabled } }, { "IMAPSIEVE=", 0, /* not implemented */ { 0 } }, /* RFC 6785 */ { "INPROGRESS", CAPA_POSTAUTH, { 0 } }, /* draft-ietf-extra-imap-inprogress */ - { "JMAPACCESS", 0, /* just a respcode */ { 0 } }, /* draft-ietf-extra-jmapaccess */ + { "JMAPACCESS", CAPA_POSTAUTH|CAPA_STATE, /* draft-ietf-extra-jmapaccess */ + { .statep = &imapd_jmapaccess_enabled } }, { "LANGUAGE", 0, /* not implemented */ { 0 } }, /* RFC 5255 */ { "LIST-EXTENDED", CAPA_POSTAUTH, { 0 } }, /* RFC 5258 */ { "LIST-METADATA", CAPA_POSTAUTH, { 0 } }, /* draft-ietf-extra-imap-list-metadata */ @@ -609,6 +611,8 @@ static void cmd_replace(char *tag, char *seqno, char *name, int usinguid); static void cmd_notify(char *tag, int set); static void push_updates(int idling); +static void cmd_getjmapaccess(char* tag); + static int parsecreateargs(struct dlist **extargs); static int parse_annotate_fetch_data(const char *tag, @@ -1081,6 +1085,7 @@ int service_init(int argc, char **argv, char **envp) #endif imapd_jmapaccess_url = config_getstring(IMAPOPT_JMAPACCESS_URL); + imapd_jmapaccess_enabled = !!imapd_jmapaccess_url; /* setup for sending IMAP IDLE/NOTIFY notifications */ if ((imapd_idle_enabled = idle_enabled())) { @@ -1860,6 +1865,12 @@ static void cmdloop(void) prometheus_increment(CYRUS_IMAP_GETANNOTATION_TOTAL); } + else if (imapd_jmapaccess_enabled && !strcmp(cmd.s, "Getjmapaccess")) { + if (!IS_EOL(c, imapd_in)) goto extraargs; + cmd_getjmapaccess(tag.s); + + prometheus_increment(CYRUS_IMAP_GETJMAPACCESS_TOTAL); + } else if (!strcmp(cmd.s, "Getmetadata")) { if (c != ' ') goto missingargs; @@ -2927,12 +2938,6 @@ static void authentication_success(const char *tag, int ssf, const char *reply) /* authstate already created by mysasl_proxy_policy() */ imapd_userisadmin = global_authisa(imapd_authstate, IMAPOPT_ADMINS); - if (imapd_jmapaccess_url) { - prot_printf(imapd_out, "* OK [JMAPACCESS \"%s\"] %s\r\n", - imapd_jmapaccess_url, - "This server is also accessible via JMAP, see RFC8620"); - } - prot_printf(imapd_out, "%s OK", tag); if (!ssf) { prot_puts(imapd_out, " [CAPABILITY"); @@ -16623,3 +16628,16 @@ static void push_updates(int idling) msg = nextmsg; } } + +static void cmd_getjmapaccess(char *tag) +{ + if (!imapd_jmapaccess_url) { + prot_printf(imapd_out, "%s BAD %s\r\n", tag, + "This server is not accessible via JMAP\r\n"); + return; + } + + prot_printf(imapd_out, "* JMAPACCESS \"%s\"\r\n", imapd_jmapaccess_url); + prot_printf(imapd_out, "%s OK %s\r\n", tag, + "This server is also accessible via JMAP, see RFC8620"); +} diff --git a/imap/promdata.p b/imap/promdata.p index 49000a270f..4788c031db 100644 --- a/imap/promdata.p +++ b/imap/promdata.p @@ -39,6 +39,7 @@ metric counter cyrus_imap_examine_total The total number of IMAP metric counter cyrus_imap_fetch_total The total number of IMAP FETCHs metric counter cyrus_imap_getacl_total The total number of IMAP GETACLs metric counter cyrus_imap_getannotation_total The total number of IMAP SETANNOTATIONs +metric counter cyrus_imap_getjmapaccess_total The total number of IMAP GETJMAPACCESSs metric counter cyrus_imap_getmetadata_total The total number of IMAP GETMETADATAs metric counter cyrus_imap_getquota_total The total number of IMAP GETQUOTAs metric counter cyrus_imap_getquotaroot_total The total number of IMAP GETQUOTAROOTs