Skip to content

Commit

Permalink
email: Various minor fixes and updates.
Browse files Browse the repository at this point in the history
mod_webmail: Fix typo adding Cc and Reply-To recipients to "To" list.
mod_webmail: Flush updates before IDLE to prevent client getting out
  of sync.
net_imap: Reject FETCH commands immediately if missing sequence number.
  Previously, an error response would have been sent for every message,
  otherwise.
libetpan.sh: Update installation to incorporate unmerged SMTP patch.
  • Loading branch information
InterLinked1 committed Mar 9, 2024
1 parent 48f371b commit 5e0b0f3
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
35 changes: 32 additions & 3 deletions modules/mod_webmail.c
Original file line number Diff line number Diff line change
Expand Up @@ -2450,13 +2450,13 @@ static int fetch_mime_recurse(json_t *root, json_t *attachments, struct mailmime
}
break;
case MAILIMF_FIELD_REPLY_TO:
append_recipients(to, f->fld_data.fld_reply_to->rt_addr_list);
append_recipients(replyto, f->fld_data.fld_reply_to->rt_addr_list);
break;
case MAILIMF_FIELD_TO:
append_recipients(to, f->fld_data.fld_to->to_addr_list);
break;
case MAILIMF_FIELD_CC:
append_recipients(to, f->fld_data.fld_cc->cc_addr_list);
append_recipients(cc, f->fld_data.fld_cc->cc_addr_list);
break;
case MAILIMF_FIELD_SUBJECT:
subject = f->fld_data.fld_subject;
Expand Down Expand Up @@ -2934,7 +2934,6 @@ static int handle_store(struct imap_client *client, int sign, json_t *uids, cons
res = mailimap_flag_list_add(flag_list, flag);
if (res != MAILIMAP_NO_ERROR) {
bbs_warning("LIST add failed: %s\n", maildriver_strerror(res));
mailimap_flag_free(flag);
mailimap_flag_list_free(flag_list);
mailimap_set_free(set);
free_if(keyword);
Expand Down Expand Up @@ -3075,6 +3074,22 @@ static int idle_stop(struct ws_session *ws, struct imap_client *client)
return 0;
}

static int client_flush_pending_output(struct imap_client *client)
{
const char *line;

do {
if ((client->imap->imap_stream && client->imap->imap_stream->read_buffer_len) || bbs_poll(client->imapfd, 50) > 0) {
line = mailimap_read_line(client->imap);
/* Read and discard */
bbs_debug(4, "Flushing output '%s'", line);
} else {
break;
}
} while (line);
return 0;
}

static int idle_start(struct ws_session *ws, struct imap_client *client)
{
UNUSED(ws); /* Formerly used to adjust net_ws timeout, not currently used */
Expand All @@ -3090,6 +3105,20 @@ static int idle_start(struct ws_session *ws, struct imap_client *client)
bbs_error("Attempt to IDLE without an active mailbox?\n");
}
bbs_assert_exists(client->imap->imap_selection_info);

/* Flush any pending input before sending the IDLE command,
* or lack of synchronization could be possible which will confuse libetpan.
* For example, if we issue a MOVE command, we'll get an untagged EXPUNGE,
* and if that hasn't been read, then that may still be in the buffer.
*
* XXX This will cause us to lose updates delivered in that small amount of time
* between when we stop idling and start idling again, which is not ideal.
* In the MOVE case, we already reflect the deletion on our end,
* so we also don't want to handle that twice. */
if (client_flush_pending_output(client) == -1) {
return MAILIMAP_ERROR_STREAM;
}

res = mailimap_idle(client->imap);
if (res != MAILIMAP_NO_ERROR) {
bbs_warning("Failed to start IDLE: %s\n", maildriver_strerror(res));
Expand Down
6 changes: 6 additions & 0 deletions nets/net_imap/imap_server_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,12 @@ int handle_fetch_full(struct imap_session *imap, char *s, int usinguid, int tagg
sequences = strsep(&s, " "); /* Messages, specified by sequence number or by UID (if usinguid) */
REQUIRE_ARGS(s); /* What remains are the items to select */

/* Could be sequence numbers/UIDs, or '$' for saved search */
if (strlen_zero(sequences) || (!atoi(sequences) && strcmp(sequences, "$"))) {
imap_reply(imap, "BAD Missing message numbers");
return 0;
}

/* Remove the surrounding parentheses for parsing */
/* Because of CONDSTORE, multiple parenthesized arguments are supported,
* e.g. s100 UID FETCH 1:* (FLAGS) (CHANGEDSINCE 12345)
Expand Down
5 changes: 5 additions & 0 deletions nets/net_imap/imap_server_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ void parse_keyword(struct imap_session *imap, const char *s, const char *directo
FILE *fp;
char index = 0;

if (strlen_zero(directory)) {
bbs_soft_assert(0);
return;
}

/* Many keywords start with $, but not all of them do */
if (imap->numappendkeywords >= MAX_KEYWORDS) {
bbs_warning("Can't store any more keywords\n"); /* XXX A NO [LIMIT] response might make sense if the whole STORE has failed */
Expand Down
23 changes: 17 additions & 6 deletions scripts/libetpan.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
#!/bin/sh

# This script can be used to compile libetpan from source.
# However, as of this writing, the package version also suffices.
# This script is used to compile libetpan from source,
# with modifications that are required for LBBS and other software.

set -e

cd /usr/local/src
git clone https://github.com/dinhvh/libetpan.git
cd libetpan
if [ ! -d libetpan ]; then
git clone https://github.com/dinhvh/libetpan.git
cd libetpan
else
cd libetpan
git stash
git pull
make clean
fi
wget "https://github.com/dinhvh/libetpan/commit/5ea630e6482422ffa2e26b9afe5fb47a9eb673a2.diff"
git apply "5ea630e6482422ffa2e26b9afe5fb47a9eb673a2.diff"
wget "https://github.com/dinhvh/libetpan/commit/4226610e3dc19f58345ae7c5146fa8cf249ca97b.patch"
git apply "5ea630e6482422ffa2e26b9afe5fb47a9eb673a2.diff" # IMAP STATUS=SIZE
git apply "4226610e3dc19f58345ae7c5146fa8cf249ca97b.patch" # SMTP AUTH
./autogen.sh --with-poll
make
make install
make install

0 comments on commit 5e0b0f3

Please sign in to comment.