1 /**
2  * @file
3  * Shared constants/structs that are private to IMAP
4  *
5  * @authors
6  * Copyright (C) 1996-1999 Brandon Long <blong@fiction.net>
7  * Copyright (C) 1999-2009 Brendan Cully <brendan@kublai.com>
8  * Copyright (C) 2018 Richard Russon <rich@flatcap.org>
9  *
10  * @copyright
11  * This program is free software: you can redistribute it and/or modify it under
12  * the terms of the GNU General Public License as published by the Free Software
13  * Foundation, either version 2 of the License, or (at your option) any later
14  * version.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19  * details.
20  *
21  * You should have received a copy of the GNU General Public License along with
22  * this program.  If not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 #ifndef MUTT_IMAP_PRIVATE_H
26 #define MUTT_IMAP_PRIVATE_H
27 
28 #include "config.h"
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include "config/lib.h"
33 #include "mutt.h"
34 
35 struct Buffer;
36 struct ConnAccount;
37 struct Email;
38 struct ImapAccountData;
39 struct ImapMboxData;
40 struct ListHead;
41 struct Mailbox;
42 struct Message;
43 struct Progress;
44 
45 #define IMAP_PORT     143  ///< Default port for IMAP
46 #define IMAP_SSL_PORT 993  ///< Port for IMAP over SSL/TLS
47 
48 /* logging levels */
49 #define IMAP_LOG_CMD  2
50 #define IMAP_LOG_LTRL 3
51 #define IMAP_LOG_PASS 5
52 
53 /* IMAP command responses. Used in ImapCommand.state too */
54 #define IMAP_RES_NO       -2  ///< `<tag> NO ...`
55 #define IMAP_RES_BAD      -1  ///< `<tag> BAD ...`
56 #define IMAP_RES_OK        0  ///< `<tag> OK ...`
57 #define IMAP_RES_CONTINUE  1  ///< `* ...`
58 #define IMAP_RES_RESPOND   2  ///< `+`
59 #define IMAP_RES_NEW       3  ///< ImapCommand.state additions
60 
61 #define SEQ_LEN 16
62 #define IMAP_MAX_CMDLEN 1024 ///< Maximum length of command lines before they must be split (for lazy servers)
63 
64 typedef uint8_t ImapOpenFlags;         ///< Flags, e.g. #MUTT_THREAD_COLLAPSE
65 #define IMAP_OPEN_NO_FLAGS          0  ///< No flags are set
66 #define IMAP_REOPEN_ALLOW     (1 << 0) ///< Allow re-opening a folder upon expunge
67 #define IMAP_EXPUNGE_EXPECTED (1 << 1) ///< Messages will be expunged from the server
68 #define IMAP_EXPUNGE_PENDING  (1 << 2) ///< Messages on the server have been expunged
69 #define IMAP_NEWMAIL_PENDING  (1 << 3) ///< New mail is waiting on the server
70 #define IMAP_FLAGS_PENDING    (1 << 4) ///< Flags have changed on the server
71 
72 typedef uint8_t ImapCmdFlags;          ///< Flags for imap_exec(), e.g. #IMAP_CMD_PASS
73 #define IMAP_CMD_NO_FLAGS          0   ///< No flags are set
74 #define IMAP_CMD_PASS        (1 << 0)  ///< Command contains a password. Suppress logging
75 #define IMAP_CMD_QUEUE       (1 << 1)  ///< Queue a command, do not execute
76 #define IMAP_CMD_POLL        (1 << 2)  ///< Poll the tcp connection before running the imap command
77 #define IMAP_CMD_SINGLE      (1 << 3)  ///< Run a single command
78 
79 /**
80  * enum ImapExecResult - Imap_exec return code
81  */
82 enum ImapExecResult
83 {
84   IMAP_EXEC_SUCCESS = 0, ///< Imap command executed or queued successfully
85   IMAP_EXEC_ERROR,       ///< Imap command failure
86   IMAP_EXEC_FATAL,       ///< Imap connection failure
87 };
88 
89 /* length of "DD-MMM-YYYY HH:MM:SS +ZZzz" (null-terminated) */
90 #define IMAP_DATELEN 27
91 
92 /**
93  * enum ImapFlags - IMAP server responses
94  */
95 enum ImapFlags
96 {
97   IMAP_FATAL = 1, ///< Unrecoverable error occurred
98   IMAP_BYE,       ///< Logged out from server
99 };
100 
101 /**
102  * enum ImapState - IMAP connection state
103  */
104 enum ImapState
105 {
106   /* States */
107   IMAP_DISCONNECTED = 0, ///< Disconnected from server
108   IMAP_CONNECTED,        ///< Connected to server
109   IMAP_AUTHENTICATED,    ///< Connection is authenticated
110   IMAP_SELECTED,         ///< Mailbox is selected
111 
112   /* and pseudo-states */
113   IMAP_IDLE, ///< Connection is idle
114 };
115 
116 /**
117  * typedef ImapCapFlags - Capabilities we are interested in
118  *
119  * @note This must be kept in the same order as Capabilities.
120  */
121 typedef uint32_t ImapCapFlags;              ///< Flags, e.g. #IMAP_CAP_IMAP4
122 #define IMAP_CAP_NO_FLAGS                0  ///< No flags are set
123 #define IMAP_CAP_IMAP4            (1 <<  0) ///< Server supports IMAP4
124 #define IMAP_CAP_IMAP4REV1        (1 <<  1) ///< Server supports IMAP4rev1
125 #define IMAP_CAP_STATUS           (1 <<  2) ///< Server supports STATUS command
126 #define IMAP_CAP_ACL              (1 <<  3) ///< RFC2086: IMAP4 ACL extension
127 #define IMAP_CAP_NAMESPACE        (1 <<  4) ///< RFC2342: IMAP4 Namespace
128 #define IMAP_CAP_AUTH_CRAM_MD5    (1 <<  5) ///< RFC2195: CRAM-MD5 authentication
129 #define IMAP_CAP_AUTH_GSSAPI      (1 <<  6) ///< RFC1731: GSSAPI authentication
130 #define IMAP_CAP_AUTH_ANONYMOUS   (1 <<  7) ///< AUTH=ANONYMOUS
131 #define IMAP_CAP_AUTH_OAUTHBEARER (1 <<  8) ///< RFC7628: AUTH=OAUTHBEARER
132 #define IMAP_CAP_AUTH_XOAUTH2     (1 <<  9) ///< AUTH=XOAUTH2, deprecated but used by OWA
133 #define IMAP_CAP_STARTTLS         (1 << 10) ///< RFC2595: STARTTLS
134 #define IMAP_CAP_LOGINDISABLED    (1 << 11) ///< RFC2595: LOGINDISABLED
135 #define IMAP_CAP_IDLE             (1 << 12) ///< RFC2177: IDLE
136 #define IMAP_CAP_SASL_IR          (1 << 13) ///< SASL initial response draft
137 #define IMAP_CAP_ENABLE           (1 << 14) ///< RFC5161
138 #define IMAP_CAP_CONDSTORE        (1 << 15) ///< RFC7162
139 #define IMAP_CAP_QRESYNC          (1 << 16) ///< RFC7162
140 #define IMAP_CAP_LIST_EXTENDED    (1 << 17) ///< RFC5258: IMAP4 LIST Command Extensions
141 #define IMAP_CAP_COMPRESS         (1 << 18) ///< RFC4978: COMPRESS=DEFLATE
142 #define IMAP_CAP_X_GM_EXT_1       (1 << 19) ///< https://developers.google.com/gmail/imap/imap-extensions
143 
144 #define IMAP_CAP_ALL             ((1 << 20) - 1)
145 
146 /**
147  * struct ImapList - Items in an IMAP browser
148  */
149 struct ImapList
150 {
151   char *name;
152   char delim;
153   bool noselect;
154   bool noinferiors;
155 };
156 
157 /**
158  * struct ImapCommand - IMAP command structure
159  */
160 struct ImapCommand
161 {
162   char seq[SEQ_LEN + 1]; ///< Command tag, e.g. 'a0001'
163   int state;            ///< Command state, e.g. #IMAP_RES_NEW
164 };
165 
166 /**
167  * struct SeqsetIterator - UID Sequence Set Iterator
168  */
169 struct SeqsetIterator
170 {
171   char *full_seqset;
172   char *eostr;
173   int in_range;
174   int down;
175   unsigned int range_cur;
176   unsigned int range_end;
177   char *substr_cur;
178   char *substr_end;
179 };
180 
181 /* -- private IMAP functions -- */
182 /* imap.c */
183 int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox);
184 int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname);
185 int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post,
186                      enum MessageType flag, bool changed, bool invert);
187 int imap_open_connection(struct ImapAccountData *adata);
188 void imap_close_connection(struct ImapAccountData *adata);
189 int imap_read_literal(FILE *fp, struct ImapAccountData *adata, unsigned long bytes, struct Progress *pbar);
190 void imap_expunge_mailbox(struct Mailbox *m);
191 int imap_login(struct ImapAccountData *adata);
192 int imap_sync_message_for_copy(struct Mailbox *m, struct Email *e, struct Buffer *cmd, enum QuadOption *err_continue);
193 bool imap_has_flag(struct ListHead *flag_list, const char *flag);
194 int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata);
195 
196 /* auth.c */
197 int imap_authenticate(struct ImapAccountData *adata);
198 
199 /* command.c */
200 int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr);
201 int imap_cmd_step(struct ImapAccountData *adata);
202 void imap_cmd_finish(struct ImapAccountData *adata);
203 bool imap_code(const char *s);
204 const char *imap_cmd_trailer(struct ImapAccountData *adata);
205 int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags);
206 int imap_cmd_idle(struct ImapAccountData *adata);
207 
208 /* message.c */
209 int imap_read_headers(struct Mailbox *m, unsigned int msn_begin, unsigned int msn_end, bool initial_download);
210 char *imap_set_flags(struct Mailbox *m, struct Email *e, char *s, bool *server_changes);
211 int imap_cache_del(struct Mailbox *m, struct Email *e);
212 int imap_cache_clean(struct Mailbox *m);
213 int imap_append_message(struct Mailbox *m, struct Message *msg);
214 
215 bool imap_msg_open(struct Mailbox *m, struct Message *msg, int msgno);
216 int imap_msg_close(struct Mailbox *m, struct Message *msg);
217 int imap_msg_commit(struct Mailbox *m, struct Message *msg);
218 int imap_msg_save_hcache(struct Mailbox *m, struct Email *e);
219 
220 /* util.c */
221 #ifdef USE_HCACHE
222 void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata);
223 void imap_hcache_close(struct ImapMboxData *mdata);
224 struct Email *imap_hcache_get(struct ImapMboxData *mdata, unsigned int uid);
225 int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e);
226 int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid);
227 int imap_hcache_store_uid_seqset(struct ImapMboxData *mdata);
228 int imap_hcache_clear_uid_seqset(struct ImapMboxData *mdata);
229 char *imap_hcache_get_uid_seqset(struct ImapMboxData *mdata);
230 #endif
231 
232 enum QuadOption imap_continue(const char *msg, const char *resp);
233 void imap_error(const char *where, const char *msg);
234 void imap_mdata_cache_reset(struct ImapMboxData *mdata);
235 char *imap_fix_path(char delim, const char *mailbox, char *path, size_t plen);
236 void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest);
237 int imap_get_literal_count(const char *buf, unsigned int *bytes);
238 char *imap_get_qualifier(char *buf);
239 char *imap_next_word(char *s);
240 void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path);
241 void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick);
242 void imap_unquote_string(char *s);
243 void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src);
244 void imap_unmunge_mbox_name(bool unicode, char *s);
245 struct SeqsetIterator *mutt_seqset_iterator_new(const char *seqset);
246 int mutt_seqset_iterator_next(struct SeqsetIterator *iter, unsigned int *next);
247 void mutt_seqset_iterator_free(struct SeqsetIterator **ptr);
248 bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2);
249 void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen);
250 bool  mutt_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2);
251 
252 /* utf7.c */
253 void imap_utf_encode(bool unicode, char **s);
254 void imap_utf_decode(bool unicode, char **s);
255 void imap_allow_reopen(struct Mailbox *m);
256 void imap_disallow_reopen(struct Mailbox *m);
257 
258 /* search.c */
259 void cmd_parse_search(struct ImapAccountData *adata, const char *s);
260 
261 #endif /* MUTT_IMAP_PRIVATE_H */
262