#include "serv_imap.h"
#include "imap_tools.h"
#include "imap_fetch.h"
+#include "imap_search.h"
long SYM_IMAP;
IMAP->msgids = NULL;
IMAP->num_msgs = 0;
}
+ if (IMAP->flags != NULL) {
+ phree(IMAP->flags);
+ IMAP->flags = NULL;
+ }
}
IMAP->msgids = reallok(IMAP->msgids,
IMAP->num_msgs * sizeof(long));
}
+ if (IMAP->flags == NULL) {
+ IMAP->flags = mallok(IMAP->num_msgs * sizeof(long));
+ }
+ else {
+ IMAP->flags = reallok(IMAP->flags,
+ IMAP->num_msgs * sizeof(long));
+ }
IMAP->msgids[IMAP->num_msgs - 1] = msgnum;
+ IMAP->flags[IMAP->num_msgs - 1] = 0;
}
void imap_greeting(void) {
strcpy(CC->cs_clientname, "IMAP session");
- CC->internal_pgm = 1;
CtdlAllocUserData(SYM_IMAP, sizeof(struct citimap));
+ IMAP->authstate = imap_as_normal;
cprintf("* OK %s Citadel/UX IMAP4rev1 server ready\r\n",
config.c_fqdn);
}
+/*
+ * Implements the AYTHENTICATE command
+ */
+void imap_authenticate(int num_parms, char *parms[]) {
+ char buf[SIZ];
+
+ if (num_parms != 3) {
+ cprintf("%s BAD incorrect number of parameters\r\n", parms[0]);
+ return;
+ }
+
+ if (!strcasecmp(parms[2], "LOGIN")) {
+ encode_base64(buf, "Username:");
+ cprintf("+ %s\r\n", buf);
+ IMAP->authstate = imap_as_expecting_username;
+ strcpy(IMAP->authseq, parms[0]);
+ return;
+ }
+
+ else {
+ cprintf("%s NO AUTHENTICATE %s failed\r\n",
+ parms[0], parms[1]);
+ }
+}
+
+void imap_auth_login_user(char *cmd) {
+ char buf[SIZ];
+
+ decode_base64(buf, cmd);
+ CtdlLoginExistingUser(buf);
+ encode_base64(buf, "Password:");
+ cprintf("+ %s\r\n", buf);
+ IMAP->authstate = imap_as_expecting_password;
+ return;
+}
+
+void imap_auth_login_pass(char *cmd) {
+ char buf[SIZ];
+
+ decode_base64(buf, cmd);
+ if (CtdlTryPassword(buf) == pass_ok) {
+ cprintf("%s OK authentication succeeded\r\n", IMAP->authseq);
+ }
+ else {
+ cprintf("%s NO authentication failed\r\n", IMAP->authseq);
+ }
+ IMAP->authstate = imap_as_normal;
+ return;
+}
+
+
+
/*
* implements the CAPABILITY command
*/
* implements the SELECT command
*/
void imap_select(int num_parms, char *parms[]) {
- char towhere[256];
- char augmented_roomname[256];
+ char towhere[SIZ];
+ char augmented_roomname[SIZ];
int c = 0;
int ok = 0;
int ra = 0;
/*
* Back end for imap_lsub()
+ *
+ * IMAP "subscribed folder" is equivocated to Citadel "known rooms." This
+ * may or may not be the desired behavior in the future.
*/
void imap_lsub_listroom(struct quickroom *qrbuf, void *data) {
- char buf[256];
-
- imap_mailboxname(buf, sizeof buf, qrbuf);
- cprintf("* LSUB () \"|\" \"%s\"\r\n", buf);
+ char buf[SIZ];
+ int ra;
+
+ /* Only list rooms to which the user has access!! */
+ ra = CtdlRoomAccess(qrbuf, &CC->usersupp);
+ if (ra & UA_KNOWN) {
+ imap_mailboxname(buf, sizeof buf, qrbuf);
+ cprintf("* LSUB () \"|\" \"%s\"\r\n", buf);
+ }
}
* Implements the LSUB command
*
* FIXME: Handle wildcards, please.
- * FIXME: Currently we show all rooms as subscribed folders. Need to handle
- * subscriptions properly.
*/
void imap_lsub(int num_parms, char *parms[]) {
ForEachRoom(imap_lsub_listroom, NULL);
* Back end for imap_list()
*/
void imap_list_listroom(struct quickroom *qrbuf, void *data) {
- char buf[256];
-
- imap_mailboxname(buf, sizeof buf, qrbuf);
- cprintf("* LIST () \"|\" \"%s\"\r\n", buf);
+ char buf[SIZ];
+ int ra;
+
+ /* Only list rooms to which the user has access!! */
+ ra = CtdlRoomAccess(qrbuf, &CC->usersupp);
+ if ( (ra & UA_KNOWN)
+ || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED))) {
+ imap_mailboxname(buf, sizeof buf, qrbuf);
+ cprintf("* LIST () \"|\" \"%s\"\r\n", buf);
+ }
}
* Main command loop for IMAP sessions.
*/
void imap_command_loop(void) {
- char cmdbuf[256];
- char *parms[256];
+ char cmdbuf[SIZ];
+ char *parms[SIZ];
int num_parms;
- int i;
time(&CC->lastcmd);
memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
if (cmdbuf[strlen(cmdbuf)-1]=='\r') cmdbuf[strlen(cmdbuf)-1]=0;
striplt(cmdbuf);
+ /* If we're in the middle of a multi-line command, handle that */
+ if (IMAP->authstate == imap_as_expecting_username) {
+ imap_auth_login_user(cmdbuf);
+ return;
+ }
+ if (IMAP->authstate == imap_as_expecting_password) {
+ imap_auth_login_pass(cmdbuf);
+ return;
+ }
+
+
+ /* Ok, at this point we're in normal command mode */
+
/* grab the tag */
num_parms = imap_parameterize(parms, cmdbuf);
- for (i=0; i<num_parms; ++i) {
- lprintf(9, " parms[%d]='%s'\n", i, parms[i]);
- }
/* commands which may be executed in any state */
imap_login(num_parms, parms);
}
+ else if (!strcasecmp(parms[1], "AUTHENTICATE")) {
+ imap_authenticate(num_parms, parms);
+ }
+
else if (!strcasecmp(parms[1], "CAPABILITY")) {
imap_capability(num_parms, parms);
}
imap_fetch(num_parms, parms);
}
+ else if ( (!strcasecmp(parms[1], "UID"))
+ && (!strcasecmp(parms[2], "FETCH")) ) {
+ imap_uidfetch(num_parms, parms);
+ }
+
+ else if (!strcasecmp(parms[1], "SEARCH")) {
+ imap_search(num_parms, parms);
+ }
+
+ else if ( (!strcasecmp(parms[1], "UID"))
+ && (!strcasecmp(parms[2], "SEARCH")) ) {
+ imap_uidsearch(num_parms, parms);
+ }
+
else if (!strcasecmp(parms[1], "CLOSE")) {
imap_close(num_parms, parms);
}