<commit_before>/* Copyright (c) 2002-2011 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 "strescape.h"
#include "imap-parser.h"
#include "imap-id.h"
#include "imap-resp-code.h"
#include "master-service.h"
#include "master-auth.h"
#include "client.h"
#include "client-authenticate.h"
#include "auth-client.h"
#include "ssl-proxy.h"
#include "imap-proxy.h"
#include "imap-login-settings.h"

#include <stdlib.h>

/* maximum length for IMAP command line. */
#define MAX_IMAP_LINE 8192

/* Disconnect client when it sends too many bad commands */
#define CLIENT_MAX_BAD_COMMANDS 10

const struct login_binary login_binary = {
	.protocol = "imap",
	.process_name = "imap-login",
	.default_port = 143,
	.default_ssl_port = 993
};

void login_process_preinit(void)
{
	login_set_roots = imap_login_setting_roots;
}

/* Skip incoming data until newline is found,
   returns TRUE if newline was found. */
bool client_skip_line(struct imap_client *client)
{
	const unsigned char *data;
	size_t i, data_size;

	data = i_stream_get_data(client->common.input, &data_size);

	for (i = 0; i < data_size; i++) {
		if (data[i] == '\n') {
			i_stream_skip(client->common.input, i+1);
			return TRUE;
		}
	}

	return FALSE;
}

static const char *get_capability(struct client *client)
{
	struct imap_client *imap_client = (struct imap_client *)client;
	string_t *cap_str = t_str_new(256);

	if (*imap_client->set->imap_capability == '\0')
		str_append(cap_str, CAPABILITY_BANNER_STRING);
	else if (*imap_client->set->imap_capability != '+')
		str_append(cap_str, imap_client->set->imap_capability);
	else {
		str_append(cap_str, CAPABILITY_BANNER_STRING);
		str_append_c(cap_str, ' ');
		str_append(cap_str, imap_client->set->imap_capability + 1);
	}

	if (ssl_initialized && !client->tls)
		str_append(cap_str, " STARTTLS");
	if (client->set->disable_plaintext_auth && !client->secured)
		str_append(cap_str, " LOGINDISABLED");

	client_authenticate_get_capabilities(client, cap_str);
	return str_c(cap_str);
}

static int cmd_capability(struct imap_client *imap_client)
{
	struct client *client = &imap_client->common;

	/* Client is required to send CAPABILITY after STARTTLS, so the
	   capability resp-code workaround checks only pre-STARTTLS
	   CAPABILITY commands. */
	if (!client->starttls)
		imap_client->client_ignores_capability_resp_code = TRUE;
	client_send_raw(client, t_strconcat(
		"* CAPABILITY ", get_capability(client), "\r\n", NULL));
	client_send_line(client, CLIENT_CMD_REPLY_OK, "Capability completed.");
	return 1;
}

static int cmd_starttls(struct imap_client *client)
{
	client_cmd_starttls(&client->common);
	return 1;
}

static void
client_update_info(struct imap_client *client, const struct imap_arg *args)
{
	const char *key, *value;

	if (!imap_arg_get_list(args, &args))
		return;

	while (imap_arg_get_string(&args[0], &key) &&
	       imap_arg_get_nstring(&args[1], &value)) {
		if (strcasecmp(key, "x-originating-ip") == 0)
			(void)net_addr2ip(value, &client->common.ip);
		else if (strcasecmp(key, "x-originating-port") == 0)
			client->common.remote_port = atoi(value);
		else if (strcasecmp(key, "x-connected-ip") == 0)
			(void)net_addr2ip(value, &client->common.local_ip);
		else if (strcasecmp(key, "x-connected-port") == 0)
			client->common.local_port = atoi(value);<commit_msg>imap-login: Changed CAPABILITY's tagged OK reply to say post-login capabilities have more.<commit_after>/* Copyright (c) 2002-2011 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 "strescape.h"
#include "imap-parser.h"
#include "imap-id.h"
#include "imap-resp-code.h"
#include "master-service.h"
#include "master-auth.h"
#include "client.h"
#include "client-authenticate.h"
#include "auth-client.h"
#include "ssl-proxy.h"
#include "imap-proxy.h"
#include "imap-login-settings.h"

#include <stdlib.h>

/* maximum length for IMAP command line. */
#define MAX_IMAP_LINE 8192

/* Disconnect client when it sends too many bad commands */
#define CLIENT_MAX_BAD_COMMANDS 10

const struct login_binary login_binary = {
	.protocol = "imap",
	.process_name = "imap-login",
	.default_port = 143,
	.default_ssl_port = 993
};

void login_process_preinit(void)
{
	login_set_roots = imap_login_setting_roots;
}

/* Skip incoming data until newline is found,
   returns TRUE if newline was found. */
bool client_skip_line(struct imap_client *client)
{
	const unsigned char *data;
	size_t i, data_size;

	data = i_stream_get_data(client->common.input, &data_size);

	for (i = 0; i < data_size; i++) {
		if (data[i] == '\n') {
			i_stream_skip(client->common.input, i+1);
			return TRUE;
		}
	}

	return FALSE;
}

static const char *get_capability(struct client *client)
{
	struct imap_client *imap_client = (struct imap_client *)client;
	string_t *cap_str = t_str_new(256);

	if (*imap_client->set->imap_capability == '\0')
		str_append(cap_str, CAPABILITY_BANNER_STRING);
	else if (*imap_client->set->imap_capability != '+')
		str_append(cap_str, imap_client->set->imap_capability);
	else {
		str_append(cap_str, CAPABILITY_BANNER_STRING);
		str_append_c(cap_str, ' ');
		str_append(cap_str, imap_client->set->imap_capability + 1);
	}

	if (ssl_initialized && !client->tls)
		str_append(cap_str, " STARTTLS");
	if (client->set->disable_plaintext_auth && !client->secured)
		str_append(cap_str, " LOGINDISABLED");

	client_authenticate_get_capabilities(client, cap_str);
	return str_c(cap_str);
}

static int cmd_capability(struct imap_client *imap_client)
{
	struct client *client = &imap_client->common;

	/* Client is required to send CAPABILITY after STARTTLS, so the
	   capability resp-code workaround checks only pre-STARTTLS
	   CAPABILITY commands. */
	if (!client->starttls)
		imap_client->client_ignores_capability_resp_code = TRUE;
	client_send_raw(client, t_strconcat(
		"* CAPABILITY ", get_capability(client), "\r\n", NULL));
	client_send_line(client, CLIENT_CMD_REPLY_OK,
			 "Pre-login capabilities listed, post-login capabilities have more.");
	return 1;
}

static int cmd_starttls(struct imap_client *client)
{
	client_cmd_starttls(&client->common);
	return 1;
}

static void
client_update_info(struct imap_client *client, const struct imap_arg *args)
{
	const char *key, *value;

	if (!imap_arg_get_list(args, &args))
		return;

	while (imap_arg_get_string(&args[0], &key) &&
	       imap_arg_get_nstring(&args[1], &value)) {
		if (strcasecmp(key, "x-originating-ip") == 0)
			(void)net_addr2ip(value, &client->common.ip);
		else if (strcasecmp(key, "x-originating-port") == 0)
			client->common.remote_port = atoi(value);
		else if (strcasecmp(key, "x-connected-ip") == 0)
			(void)net_addr2ip(value, &client->common.local_ip);
		else if (strcasecmp(key, "x-connected-port") == 0)
			client->common.local_port = atoi(value);
{'fraction_non_alphanumeric': 0.14004252303330972, 'fraction_numerical': 0.010489014883061658, 'mean_word_length': 5.222222222222222, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3184461', 'n_tokens_mistral': 2783, 'n_tokens_neox': 2626, 'n_words': 567}