#include <config.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include "protocol.h"
#include "xmalloc.h"
static char *imap_parsemechlist(const char *str, struct protocol_t *prot)
{
char *ret = xzmalloc(strlen(str)+1);
char *tmp;
int num = 0;
if (strstr(str, "SASL-IR")) {
prot->sasl_cmd.maxlen = INT_MAX;
}
while ((tmp = strstr(str, "AUTH="))) {
char *end = (tmp += 5);
while((*end != ' ') && (*end != '\0')) end++;
if (num++ > 0) strcat(ret, " ");
strlcat(ret, tmp, strlen(ret) + (end - tmp) + 1);
str = end + 1;
}
return ret;
}
static char *nntp_parsesuccess(char *str, const char **status)
{
char *success = NULL;
if (!strncmp(str, "283 ", 4)) {
success = str+4;
}
if (status) *status = NULL;
return success;
}
static char *sieve_parsesuccess(char *str, const char **status)
{
char *success = NULL, *tmp;
if (!strncmp(str, "OK (", 4) &&
(tmp = strstr(str+4, "SASL \"")) != NULL) {
success = tmp+6;
tmp = strstr(success, "\"");
*tmp = '\0';
}
if (status) *status = NULL;
return success;
}
struct protocol_t protocol[] = {
{ "imap", "imap",
{ 0, "* OK" },
{ "C01 CAPABILITY", "C01 ", &imap_parsemechlist,
{ { " AUTH=", CAPA_AUTH },
{ " STARTTLS", CAPA_STARTTLS },
{ " IDLE", CAPA_IDLE },
{ " MUPDATE", CAPA_MUPDATE },
{ " MULTIAPPEND", CAPA_MULTIAPPEND },
{ " LIST-SUBSCRIBED", CAPA_LISTSUBSCRIBED },
{ " RIGHTS=kxte", CAPA_ACLRIGHTS },
{ NULL, 0 } } },
{ "S01 STARTTLS", "S01 OK", "S01 NO" },
{ "A01 AUTHENTICATE", 0, 0, "A01 OK", "A01 NO", "+ ", "*", NULL },
{ "N01 NOOP", "* ", "N01 OK" },
{ "Q01 LOGOUT", "* ", "Q01 " } },
{ "pop3", "pop",
{ 0, "+OK " },
{ "CAPA", ".", NULL,
{ { "SASL ", CAPA_AUTH },
{ "STLS", CAPA_STARTTLS },
{ NULL, 0 } } },
{ "STLS", "+OK", "-ERR" },
{ "AUTH", 255, 0, "+OK", "-ERR", "+ ", "*", NULL },
{ "NOOP", NULL, "+OK" },
{ "QUIT", NULL, "+OK" } },
{ "nntp", "nntp",
{ 0, "20" },
{ "CAPABILITIES", ".", NULL,
{ { "SASL ", CAPA_AUTH },
{ "STARTTLS", CAPA_STARTTLS },
{ NULL, 0 } } },
{ "STARTTLS", "382", "580" },
{ "AUTHINFO SASL", 512, 0, "28", "48", "383 ", "*", &nntp_parsesuccess },
{ "DATE", NULL, "111" },
{ "QUIT", NULL, "205" } },
{ "lmtp", "lmtp",
{ 0, "220 " },
{ "LHLO murder", "250 ", NULL,
{ { "AUTH ", CAPA_AUTH },
{ "STARTTLS", CAPA_STARTTLS },
{ "PIPELINING", CAPA_PIPELINING },
{ "IGNOREQUOTA", CAPA_IGNOREQUOTA },
{ NULL, 0 } } },
{ "STARTTLS", "220", "454" },
{ "AUTH", 512, 0, "235", "5", "334 ", "*", NULL },
{ "NOOP", NULL, "250" },
{ "QUIT", NULL, "221" } },
{ "mupdate", "mupdate",
{ 1, "* OK" },
{ NULL, "* OK", NULL,
{ { "* AUTH ", CAPA_AUTH },
{ "* STARTTLS", CAPA_STARTTLS },
{ NULL, 0 } } },
{ "S01 STARTTLS", "S01 OK", "S01 NO" },
{ "A01 AUTHENTICATE", INT_MAX, 1, "A01 OK", "A01 NO", "", "*", NULL },
{ "N01 NOOP", NULL, "N01 OK" },
{ "Q01 LOGOUT", NULL, "Q01 " } },
{ "sieve", SIEVE_SERVICE_NAME,
{ 1, "OK" },
{ "CAPABILITY", "OK", NULL,
{ { "\"SASL\" ", CAPA_AUTH },
{ "\"STARTTLS\"", CAPA_STARTTLS },
{ NULL, 0 } } },
{ "STARTTLS", "OK", "NO" },
{ "AUTHENTICATE", INT_MAX, 1, "OK", "NO", NULL, "*", &sieve_parsesuccess },
{ NULL, NULL, NULL },
{ "LOGOUT", NULL, "OK" } },
{ "csync", "csync",
{ 1, "* OK" },
{ NULL, "* OK", NULL,
{ { "* SASL ", CAPA_AUTH },
{ "* STARTTLS", CAPA_STARTTLS },
{ NULL, 0 } } },
{ "STARTTLS", "OK", "NO" },
{ "AUTHENTICATE", INT_MAX, 0, "OK", "NO", "+ ", "*", NULL },
{ "NOOP", NULL, "OK" },
{ "EXIT", NULL, "OK" } }
};