void imapcapability() { const char *p; if ((p=getenv("IMAP_TLS")) && atoi(p) && (p=getenv("IMAP_CAPABILITY_TLS")) && *p) writes(p); else if ((p=getenv("IMAP_CAPABILITY")) != 0 && *p) writes(p); else writes("IMAP4rev1"); #if SMAP p=getenv("SMAP_CAPABILITY"); if (p && *p) { writes(" "); writes(p); if (keywords()) writes(" KEYWORDS"); } #endif if ((p=getenv("IMAP_ACL")) && atoi(p)) writes(" ACL ACL2=UNION"); if (getenv("IMAP_ID_FIELDS")) writes(" ID"); if (have_starttls()) { writes(" STARTTLS"); if (tlsrequired()) writes(" LOGINDISABLED"); } else { if (imap_externalauth()) writes(" AUTH=EXTERNAL"); } p=getenv("OUTBOX"); if (p && *p) { writes(" XCOURIEROUTBOX=INBOX"); writes(p); } if (magictrash()) writes(" XMAGICTRASH"); }
int do_imap_command(const char *tag) { struct imaptoken *curtoken=nexttoken(); char authservice[40]; #if SMAP if (strcmp(tag, "\\SMAP1") == 0) { const char *p=getenv("SMAP_CAPABILITY"); if (p && *p) putenv("PROTOCOL=SMAP1"); else return -1; } #endif courier_authdebug_login( 1, "command=%s", curtoken->tokenbuf ); if (strcmp(curtoken->tokenbuf, "LOGOUT") == 0) { if (nexttoken()->tokentype != IT_EOL) return (-1); writes("* BYE Courier-IMAP server shutting down\r\n"); cmdsuccess(tag, "LOGOUT completed\r\n"); writeflush(); fprintf(stderr, "INFO: LOGOUT, ip=[%s], rcvd=%lu, sent=%lu\n", getenv("TCPREMOTEIP"), bytes_received_count, bytes_sent_count); exit(0); } if (strcmp(curtoken->tokenbuf, "NOOP") == 0) { if (nexttoken()->tokentype != IT_EOL) return (-1); cmdsuccess(tag, "NOOP completed\r\n"); return (0); } if (strcmp(curtoken->tokenbuf, "CAPABILITY") == 0) { if (nexttoken()->tokentype != IT_EOL) return (-1); writes("* CAPABILITY "); imapcapability(); writes("\r\n"); cmdsuccess(tag, "CAPABILITY completed\r\n"); return (0); } if (strcmp(curtoken->tokenbuf, "STARTTLS") == 0) { if (!have_starttls()) return (-1); if (starttls(tag)) return (-2); putenv("IMAP_STARTTLS=NO"); putenv("IMAP_TLS_REQUIRED=0"); putenv("IMAP_TLS=1"); return (0); } if (strcmp(curtoken->tokenbuf, "LOGIN") == 0) { struct imaptoken *tok=nexttoken_nouc(); char *userid; char *passwd; const char *p; int rc; if (have_starttls() && tlsrequired()) /* Not yet */ { cmdfail(tag, "STARTTLS required\r\n"); return (0); } switch (tok->tokentype) { case IT_ATOM: case IT_NUMBER: case IT_QUOTED_STRING: break; default: return (-1); } userid=strdup(tok->tokenbuf); if (!userid) write_error_exit(0); tok=nexttoken_nouc_okbracket(); switch (tok->tokentype) { case IT_ATOM: case IT_NUMBER: case IT_QUOTED_STRING: break; default: free(userid); return (-1); } passwd=my_strdup(tok->tokenbuf); if (nexttoken()->tokentype != IT_EOL) { free(userid); free(passwd); return (-1); } strcat(strcpy(authservice, "AUTHSERVICE"), getenv("TCPLOCALPORT")); p=getenv(authservice); if (!p || !*p) p="imap"; rc=auth_login(p, userid, passwd, login_callback, (void *)tag); courier_safe_printf("INFO: LOGIN FAILED, user=%s, ip=[%s]", userid, getenv("TCPREMOTEIP")); free(userid); free(passwd); if (rc > 0) { perror("ERR: authentication error"); writes("* BYE Temporary problem, please try again later\r\n"); writeflush(); exit(1); } sleep(5); cmdfail(tag, "Login failed.\r\n"); return (0); } if (strcmp(curtoken->tokenbuf, "AUTHENTICATE") == 0) { char method[32]; int rc; if (have_starttls() && tlsrequired()) /* Not yet */ { cmdfail(tag, "STARTTLS required\r\n"); return (0); } rc=authenticate(tag, method, sizeof(method)); courier_safe_printf("INFO: LOGIN FAILED, method=%s, ip=[%s]", method, getenv("TCPREMOTEIP")); if (rc > 0) { perror("ERR: authentication error"); writes("* BYE Temporary problem, please try again later\r\n"); writeflush(); exit(1); } sleep(5); cmdfail(tag, "Login failed.\r\n"); writeflush(); return (-2); } return (-1); }