/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "login-common.h"
#include "buffer.h"
#include "ioloop.h"
#include "istream.h"
#include "ostream.h"
#include "safe-memset.h"
#include "str.h"
#include "imap-parser.h"
#include "imap-id.h"
#include "imap-resp-code.h"
#include "master-service.h"
#include "master-service-ssl-settings.h"
#include "master-auth.h"
#include "imap-login-client.h"
#include "client-authenticate.h"
#include "auth-client.h"
#include "imap-proxy.h"
#include "imap-quote.h"
#include "imap-login-commands.h"
#include "imap-login-settings.h"
#endif
/* Disconnect client when it sends too many bad commands */
/* Skip incoming data until newline is found,
returns TRUE if newline was found. */
{
const unsigned char *data;
for (i = 0; i < data_size; i++) {
if (data[i] == '\n') {
return TRUE;
}
}
return FALSE;
}
struct imap_parser *parser)
{
const char *msg;
switch (parse_error) {
case IMAP_PARSE_ERROR_NONE:
i_unreached();
return FALSE;
default:
break;
}
return TRUE;
}
{
/* no PLAIN authentication, can't use LOGIN command */
return TRUE;
}
return FALSE;
}
return TRUE;
return TRUE;
return FALSE;
}
{
} else {
}
if (!explicit_capability) {
else
}
if (is_login_cmd_disabled(client))
}
{
/* Client is required to send CAPABILITY after STARTTLS, so the
capability resp-code workaround checks only pre-STARTTLS
CAPABILITY commands. */
"Pre-login capabilities listed, post-login capabilities have more.");
return 1;
}
{
return 1;
}
static void
{
if (success)
else
}
{
"NOOP completed.");
return 1;
}
{
"Logout completed.");
return 1;
}
{
"ENABLE ignored in non-authenticated state.");
return 1;
}
{
return -2;
}
{
switch (*tag) {
case '+':
/* atom-specials: */
case '(':
case ')':
case '{':
case '/':
case ' ':
/* list-wildcards: */
case '%':
case '*':
/* quoted-specials: */
case '"':
case '\\':
return FALSE;
default:
return FALSE;
break;
}
}
return TRUE;
}
{
case -1:
/* error */
/* client destroyed */
return 0;
}
return -1;
case -2:
/* not enough data */
return 0;
default:
/* we read the entire line - skip over the CRLF */
if (!client_skip_line(client))
i_unreached();
return 1;
}
}
{
if (client->cmd_finished) {
/* clear the previous command from memory. don't do this
immediately after handling command since we need the
cmd_tag to stay some time after authentication commands. */
/* remove \r\n */
if (!client_skip_line(client))
return FALSE;
}
}
return FALSE; /* need more data */
/* the tag is invalid, don't allow it and don't
send it back. this attempts to prevent any
potentially dangerous replies in case someone tries
to access us using HTTP protocol. */
}
}
return FALSE; /* need more data */
}
}
{
bool parsed;
int ret;
/* SASL-IR may need more space than input buffer's size,
so we'll handle it as a special case. */
return FALSE;
/* ID extensions allows max. 30 parameters,
each max. 1024 bytes long. that brings us over the input
buffer's size, so handle the parameters one at a time */
if (ret == 0)
return FALSE;
if (ret < 0)
} else {
if (ret < 0)
return TRUE;
if (ret == 0)
return FALSE;
}
"First parameter in line is IMAP's command tag, "
"not the command name. Add that before the command, "
"like: a login user pass");
} else if (ret < 0) {
"Too many invalid IMAP commands.");
"Disconnected: Too many invalid commands");
return FALSE;
}
"Error in IMAP command received by server.");
}
}
{
if (!client_read(client))
return;
for (;;) {
if (!auth_client_is_connected(auth_client)) {
/* we're not currently connected to auth process -
don't allow any commands */
break;
} else {
if (!client_handle_input(imap_client))
break;
}
}
}
{
return &imap_client->common;
}
{
}
{
}
{
}
{
/* CRLF is lost from buffer when streams are reopened. */
}
static void ATTR_NULL(3)
{
T_BEGIN {
if (tagged)
else
} T_END;
}
{
switch (reply) {
case IMAP_CMD_REPLY_OK:
prefix = "OK";
break;
case IMAP_CMD_REPLY_NO:
break;
case IMAP_CMD_REPLY_BAD:
prefix = "BAD";
break;
case IMAP_CMD_REPLY_BYE:
prefix = "BYE";
break;
}
}
const char *text)
{
}
static void
{
if (bad)
else
}
static void
const char *text)
{
if (reason == CLIENT_DISCONNECT_INTERNAL_ERROR) {
} else {
}
}
static void imap_login_preinit(void)
{
}
{ "LOGIN", cmd_login },
{ "CAPABILITY", cmd_capability },
{ "STARTTLS", cmd_starttls },
{ "NOOP", cmd_noop },
{ "LOGOUT", cmd_logout },
{ "ENABLE", cmd_enable }
};
static void imap_login_init(void)
{
}
static void imap_login_deinit(void)
{
}
NULL,
NULL,
};
.protocol = "imap",
.process_name = "imap-login",
.default_port = 143,
.default_ssl_port = 993,
.init = imap_login_init,
};
{
}