dovecot-2.2-pigeonhole: managesieve-login: Implemented proxy XCL...
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Thu May 21 19:47:50 UTC 2015
details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/ad7fc0736050
changeset: 2074:ad7fc0736050
user: Stephan Bosch <stephan at rename-it.nl>
date: Thu May 21 21:45:40 2015 +0200
description:
managesieve-login: Implemented proxy XCLIENT support.
diffstat:
src/managesieve-login/client.c | 53 +++++++++++++++++++++++++++-
src/managesieve-login/client.h | 1 +
src/managesieve-login/managesieve-proxy.c | 57 ++++++++++++++++++++++++++++--
3 files changed, 105 insertions(+), 6 deletions(-)
diffs (198 lines):
diff -r 9caff604a21e -r ad7fc0736050 src/managesieve-login/client.c
--- a/src/managesieve-login/client.c Tue May 19 21:23:52 2015 +0200
+++ b/src/managesieve-login/client.c Thu May 21 21:45:40 2015 +0200
@@ -80,6 +80,10 @@
/* Protocol version */
client_send_raw(client, "\"VERSION\" \"1.0\"\r\n");
+
+ /* XCLIENT */
+ if (client->trusted)
+ client_send_raw(client, "\"XCLIENT\"\r\n");
} T_END;
}
@@ -151,13 +155,58 @@
return 1;
}
+static int cmd_xclient
+(struct managesieve_client *client,
+ const struct managesieve_arg *args)
+{
+ unsigned int remote_port;
+ const char *arg;
+ bool args_ok = TRUE;
+
+ if ( !client->common.trusted ) {
+ client_send_no(&client->common,
+ "You are not from trusted IP");
+ return 1;
+ }
+ while (!MANAGESIEVE_ARG_IS_EOL(&args[0]) &&
+ managesieve_arg_get_atom(&args[0], &arg)) {
+ if ( strncasecmp(arg, "ADDR=", 5) == 0 ) {
+ if (net_addr2ip(arg + 5, &client->common.ip) < 0)
+ args_ok = FALSE;
+ } else if ( strncasecmp(arg, "PORT=", 5) == 0 ) {
+ if (str_to_uint(arg + 5, &remote_port) < 0 ||
+ remote_port == 0 || remote_port > 65535)
+ args_ok = FALSE;
+ else
+ client->common.remote_port = remote_port;
+ } else if ( strncasecmp(arg, "SESSION=", 8) == 0 ) {
+ const char *value = arg + 8;
+
+ if (strlen(value) <= LOGIN_MAX_SESSION_ID_LEN) {
+ client->common.session_id =
+ p_strdup(client->common.pool, value);
+ }
+ } else if ( strncasecmp(arg, "TTL=", 4 ) == 0) {
+ if (str_to_uint(arg + 4, &client->common.proxy_ttl) < 0)
+ args_ok = FALSE;
+ }
+ args++;
+ }
+ if ( !args_ok || !MANAGESIEVE_ARG_IS_EOL(&args[0]))
+ return -1;
+
+ client_send_ok(&client->common, "Updated");
+ return 1;
+}
+
static struct managesieve_command commands[] = {
{ "AUTHENTICATE", cmd_authenticate, 1 },
{ "CAPABILITY", cmd_capability, -1 },
{ "STARTTLS", cmd_starttls, -1 },
{ "NOOP", cmd_noop, 0 },
- { "LOGOUT", cmd_logout, -1},
- { NULL, NULL, 0}
+ { "LOGOUT", cmd_logout, -1 },
+ { "XCLIENT", cmd_xclient, 0 },
+ { NULL, NULL, 0 }
};
static bool client_handle_input(struct managesieve_client *client)
diff -r 9caff604a21e -r ad7fc0736050 src/managesieve-login/client.h
--- a/src/managesieve-login/client.h Tue May 19 21:23:52 2015 +0200
+++ b/src/managesieve-login/client.h Thu May 21 21:45:40 2015 +0200
@@ -32,6 +32,7 @@
unsigned int proxy_starttls:1;
unsigned int proxy_sasl_plain:1;
+ unsigned int proxy_xclient:1;
};
bool client_skip_line(struct managesieve_client *client);
diff -r 9caff604a21e -r ad7fc0736050 src/managesieve-login/managesieve-proxy.c
--- a/src/managesieve-login/managesieve-proxy.c Tue May 19 21:23:52 2015 +0200
+++ b/src/managesieve-login/managesieve-proxy.c Thu May 21 21:45:40 2015 +0200
@@ -23,6 +23,7 @@
PROXY_STATE_INITIAL,
PROXY_STATE_TLS_START,
PROXY_STATE_TLS_READY,
+ PROXY_STATE_XCLIENT,
PROXY_STATE_AUTHENTICATE,
};
@@ -64,8 +65,21 @@
managesieve_quote_append_string(dest, str_c(base64), FALSE);
}
+static void proxy_write_xclient
+(struct managesieve_client *client, string_t *str)
+{
+ str_printfa(str,
+ "XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u\r\n",
+ net_ip2addr(&client->common.ip),
+ client->common.remote_port,
+ client_get_session_id(&client->common),
+ client->common.proxy_ttl - 1);
+}
+
static int proxy_write_login(struct managesieve_client *client, string_t *str)
{
+ i_assert(client->common.proxy_ttl > 1);
+
if ( !client->proxy_sasl_plain ) {
client_log_err(&client->common, "proxy: "
"Server does not support required PLAIN SASL mechanism");
@@ -77,7 +91,6 @@
get_plain_auth(&client->common, str);
proxy_free_password(&client->common);
str_append(str, "\r\n");
-
return 1;
}
@@ -171,6 +184,8 @@
} else if ( strcasecmp(capability, "STARTTLS") == 0 ) {
client->proxy_starttls = TRUE;
+ } else if ( strcasecmp(capability, "XCLIENT") == 0 ) {
+ client->proxy_xclient = TRUE;
}
} else {
@@ -249,6 +264,11 @@
str_append(command, "STARTTLS\r\n");
msieve_client->proxy_state = PROXY_STATE_TLS_START;
+
+ } else if (msieve_client->proxy_xclient) {
+ proxy_write_xclient(msieve_client, command);
+ msieve_client->proxy_state = PROXY_STATE_XCLIENT;
+
} else {
if ( proxy_write_login(msieve_client, command) < 0 ) {
client_proxy_failed(client, TRUE);
@@ -296,17 +316,46 @@
}
command = t_str_new(128);
+ if ( msieve_client->proxy_xclient ) {
+ proxy_write_xclient(msieve_client, command);
+ msieve_client->proxy_state = PROXY_STATE_XCLIENT;
+
+ } else {
+ if ( proxy_write_login(msieve_client, command) < 0 ) {
+ client_proxy_failed(client, TRUE);
+ return -1;
+ }
+ msieve_client->proxy_state = PROXY_STATE_AUTHENTICATE;
+ }
+ (void)o_stream_send(output, str_data(command), str_len(command));
+ }
+ return 0;
+
+ case PROXY_STATE_XCLIENT:
+ if ( strncasecmp(line, "OK", 2) == 0 &&
+ ( strlen(line) == 2 || line[2] == ' ' ) ) {
+
+ /* STARTTLS successful, begin TLS negotiation. */
+ if ( login_proxy_starttls(client->login_proxy) < 0 ) {
+ client_proxy_failed(client, TRUE);
+ return -1;
+ }
+
+ command = t_str_new(128);
if ( proxy_write_login(msieve_client, command) < 0 ) {
client_proxy_failed(client, TRUE);
return -1;
}
-
(void)o_stream_send(output, str_data(command), str_len(command));
-
msieve_client->proxy_state = PROXY_STATE_AUTHENTICATE;
+ return 0;
}
- return 0;
+ client_log_err(client, t_strdup_printf(
+ "proxy: Remote XCLIENT failed: %s",
+ str_sanitize(line, 160)));
+ client_proxy_failed(client, TRUE);
+ return -1;
case PROXY_STATE_AUTHENTICATE:
More information about the dovecot-cvs
mailing list