}
}
+static void
+cmd_id_x_client_transport(struct imap_client *client,
+ const char *key ATTR_UNUSED, const char *value)
+{
+ /* for now values are either "insecure" or "TLS", but plan ahead already
+ in case we want to transfer e.g. the TLS security string */
+ client->common.end_client_tls_secured_set = TRUE;
+ client->common.end_client_tls_secured =
+ str_begins_with(value, CLIENT_TRANSPORT_TLS);
+}
+
static void
cmd_id_x_forward_(struct imap_client *client,
const char *key, const char *value)
{ "x-proxy-ttl", FALSE, cmd_id_x_proxy_ttl },
{ "x-session-id", FALSE, cmd_id_x_session_id },
{ "x-session-ext-id", FALSE, cmd_id_x_session_id },
+ { "x-client-transport", FALSE, cmd_id_x_client_transport },
{ "x-forward-", TRUE, cmd_id_x_forward_ },
{ NULL, FALSE, NULL }
"\"x-originating-port\" \"%u\" "
"\"x-connected-ip\" \"%s\" "
"\"x-connected-port\" \"%u\" "
- "\"x-proxy-ttl\" \"%u\"",
+ "\"x-proxy-ttl\" \"%u\" "
+ "\"x-client-transport\" \"%s\"",
client_get_session_id(&client->common),
net_ip2addr(&client->common.ip),
client->common.remote_port,
net_ip2addr(&client->common.local_ip),
client->common.local_port,
- client->common.proxy_ttl - 1);
+ client->common.proxy_ttl - 1,
+ client->common.end_client_tls_secured ?
+ CLIENT_TRANSPORT_TLS : CLIENT_TRANSPORT_INSECURE);
/* append any forward_ variables to request */
for(const char *const *ptr = client->common.auth_passdb_args; *ptr != NULL; ptr++) {
TLS secured anyway. */
client->connection_tls_secured = conn->haproxy.ssl;
client->haproxy_terminated_tls = conn->haproxy.ssl;
+ /* Start by assuming this is the end client connection.
+ Later on this can be overwritten. */
client->end_client_tls_secured = conn->haproxy.ssl;
client->local_name = conn->haproxy.hostname;
client->client_cert_common_name = conn->haproxy.cert_common_name;
client->connection_tls_secured = TRUE;
client->connection_secured = TRUE;
- client->end_client_tls_secured = TRUE;
+ if (!client->end_client_tls_secured_set)
+ client->end_client_tls_secured = TRUE;
if (client->connection_used_starttls) {
io_remove(&client->io);
#define CLIENT_UNAUTHENTICATED_LOGOUT_MSG \
"Aborted login by logging out"
+#define CLIENT_TRANSPORT_TLS "TLS"
+#define CLIENT_TRANSPORT_INSECURE "insecure"
+
struct master_service_connection;
enum client_disconnect_reason {
previous hop is secured. */
bool connection_secured:1;
/* End client is using TLS connection. The TLS termination may be either
- on Dovecot side or HAProxy side. FIXME: This is broken on a proxying
- setup, because it indicates whether the previous hop connection is
- TLS secured, not whether the original client connection is TLS
- secured. */
+ on Dovecot side or HAProxy side. This value is forwarded through
+ trusted Dovecot proxies. */
bool end_client_tls_secured:1;
+ /* TRUE if end_client_tls_secured is set via ID/XCLIENT and must not
+ be changed anymore. */
+ bool end_client_tls_secured_set:1;
/* Connection is from a trusted client/proxy, which is allowed to e.g.
forward the original client IP address. Note that a trusted
connection is not necessarily considered secured. */
} else if (str_begins_icase(*tmp, "TTL=", &value)) {
if (str_to_uint(value, &client->common.proxy_ttl) < 0)
args_ok = FALSE;
+ } else if (str_begins_icase(*tmp, "CLIENT-TRANSPORT=", &value)) {
+ client->common.end_client_tls_secured_set = TRUE;
+ client->common.end_client_tls_secured =
+ str_begins_with(value, CLIENT_TRANSPORT_TLS);
} else if (str_begins_icase(*tmp, "FORWARD=", &value)) {
if (!client_forward_decode_base64(&client->common, value))
args_ok = FALSE;
}
}
- str_printfa(str, "XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u",
+ str_printfa(str, "XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u "
+ "CLIENT-TRANSPORT=%s",
net_ip2addr(&client->common.ip),
client->common.remote_port,
client_get_session_id(&client->common),
- client->common.proxy_ttl - 1);
+ client->common.proxy_ttl - 1,
+ client->common.end_client_tls_secured ?
+ CLIENT_TRANSPORT_TLS : CLIENT_TRANSPORT_INSECURE);
if (str_len(fwd) > 0) {
str_append(str, " FORWARD=");
base64_encode(str_data(fwd), str_len(fwd), str);
client->common.session_id =
p_strdup(client->common.pool, data->session);
}
+ if (data->client_transport != NULL) {
+ client->common.end_client_tls_secured_set = TRUE;
+ client->common.end_client_tls_secured =
+ str_begins_with(data->client_transport,
+ CLIENT_TRANSPORT_TLS);
+ }
for (i = 0; i < data->extra_fields_count; i++) {
const char *name = data->extra_fields[i].name;
proxy_send_xclient_more(client, output, str, "SESSION",
client_get_session_id(&client->common));
}
+ if (str_array_icase_find(client->proxy_xclient, "CLIENT-TRANSPORT")) {
+ proxy_send_xclient_more(client, output, str, "CLIENT-TRANSPORT",
+ client->common.end_client_tls_secured ?
+ CLIENT_TRANSPORT_TLS : CLIENT_TRANSPORT_INSECURE);
+ }
if (str_array_icase_find(client->proxy_xclient, "FORWARD")) {
buffer_t *fwd = proxy_compose_xclient_forward(client);