conn->set.hostname != NULL ? conn->set.hostname : "";
connection_input_halt(&conn->conn);
if (io_stream_create_ssl_client(conn->set.ssl_ctx, hostname,
- conn->conn.event,
+ conn->conn.event, 0,
&conn->conn.input, &conn->conn.output,
&conn->ssl_iostream, &error) < 0) {
*error_r = t_strdup_printf(
connection_input_halt(&conn->conn);
if (io_stream_create_ssl_client(ssl_ctx, pshared->addr.a.tcp.https_name,
- conn->event,
+ conn->event, 0,
&conn->conn.input, &conn->conn.output,
&conn->ssl_iostream, &error) < 0) {
*error_r = t_strdup_printf(
io_remove(&conn->io);
if (io_stream_create_ssl_client(conn->client->ssl_ctx,
conn->client->set.host,
- conn->event,
+ conn->event, 0,
&conn->input, &conn->output,
&conn->ssl_iostream, &error) < 0) {
e_error(conn->event, "Couldn't initialize SSL client: %s",
connection_input_halt(&conn->conn);
if (io_stream_create_ssl_client(
- conn->ssl_ctx, conn->host, conn->event,
+ conn->ssl_ctx, conn->host, conn->event, 0,
&conn->conn.input, &conn->conn.output,
&conn->ssl_iostream, &error) < 0) {
*error_r = t_strdup_printf(
}
if (preverify_ok == 0) {
ssl_io->cert_broken = TRUE;
- if (!ssl_io->ctx->allow_invalid_cert) {
+ if (!ssl_io->allow_invalid_cert) {
ssl_io->handshake_failed = TRUE;
return 0;
}
openssl_iostream_create(struct ssl_iostream_context *ctx,
struct event *event_parent, const char *host,
bool client,
+ enum ssl_iostream_flags flags,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r,
const char **error_r)
ssl_io->plain_output = *output;
ssl_io->connected_host = i_strdup(host);
ssl_io->event = event_create(event_parent);
+ ssl_io->allow_invalid_cert = ctx->allow_invalid_cert ||
+ (flags & SSL_IOSTREAM_FLAG_ALLOW_INVALID_CERT) != 0;
if (client)
event_add_category(ssl_io->event, &event_category_ssl_client);
else
ssl_io->handshake_failed = TRUE;
}
} else if (ssl_io->connected_host != NULL && !ssl_io->handshake_failed &&
- !ssl_io->ctx->allow_invalid_cert) {
+ !ssl_io->allow_invalid_cert) {
if (ssl_iostream_check_cert_validity(ssl_io, ssl_io->connected_host, &reason) < 0) {
openssl_iostream_set_error(ssl_io, reason);
ssl_io->handshake_failed = TRUE;
static bool
openssl_iostream_get_allow_invalid_cert(struct ssl_iostream *ssl_io)
{
- return ssl_io->ctx->allow_invalid_cert;
+ return ssl_io->allow_invalid_cert;
}
static const char *
void *sni_context;
bool do_shutdown:1;
+ bool allow_invalid_cert:1;
bool handshaked:1;
bool handshake_failed:1;
bool cert_received:1;
struct event *event_parent,
const char *host,
bool client,
+ enum ssl_iostream_flags flags,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r, const char **error_r);
void (*unref)(struct ssl_iostream *ssl_io);
int io_stream_create_ssl_client(struct ssl_iostream_context *ctx, const char *host,
struct event *event_parent,
+ enum ssl_iostream_flags flags,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r,
const char **error_r)
{
- return ssl_vfuncs->create(ctx, event_parent, host, TRUE,
+ return ssl_vfuncs->create(ctx, event_parent, host, TRUE, flags,
input, output, iostream_r, error_r);
}
struct ssl_iostream **iostream_r,
const char **error_r)
{
- return ssl_vfuncs->create(ctx, event_parent, NULL, TRUE,
+ return ssl_vfuncs->create(ctx, event_parent, NULL, TRUE, 0,
input, output, iostream_r, error_r);
}
int io_stream_autocreate_ssl_client(
struct event *event_parent, const char *host,
+ enum ssl_iostream_flags flags,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r,
const char **error_r)
if (ret < 0)
return -1;
- ret = io_stream_create_ssl_client(ctx, host, event_parent, input,
+ ret = io_stream_create_ssl_client(ctx, host, event_parent, flags, input,
output, iostream_r, error_r);
ssl_iostream_context_unref(&ctx);
return ret;
struct ssl_iostream;
struct ssl_iostream_context;
+enum ssl_iostream_flags {
+ /* Enable ssl_iostream_settings.allow_invalid_cert after context is
+ already created. If the context already has
+ ssl_iostream_settings.allow_invalid_cert enabled, it can't
+ be anymore disabled. */
+ SSL_IOSTREAM_FLAG_ALLOW_INVALID_CERT = BIT(0),
+};
+
struct ssl_iostream_cert {
const char *cert;
const char *key;
int io_stream_create_ssl_client(struct ssl_iostream_context *ctx, const char *host,
struct event *event_parent,
+ enum ssl_iostream_flags flags,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r,
const char **error_r);
get the context and call io_stream_create_ssl_client(). */
int io_stream_autocreate_ssl_client(
struct event *event_parent, const char *host,
+ enum ssl_iostream_flags flags,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r,
const char **error_r);
will always return FALSE before even checking the hostname. */
bool ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io, const char *name,
const char **reason_r);
-/* Returns ssl_iostream_settings.allow_invalid_cert. */
+/* Returns if ssl_iostream_settings.allow_invalid_cert is set or
+ SSL_IOSTREAM_FLAG_ALLOW_INVALID_CERT is used. */
bool ssl_iostream_get_allow_invalid_cert(struct ssl_iostream *ssl_io);
/* Returns username from the received certificate of the peer (client) if
available, NULL if not. The username is based on cert_username_field
ret = -1;
}
- if (io_stream_create_ssl_client(client->ctx, client->hostname, NULL,
+ if (io_stream_create_ssl_client(client->ctx, client->hostname, NULL, 0,
&client->input, &client->output,
&client->iostream, &error) != 0) {
ret = -1;
test_assert(io_stream_create_ssl_server(server->ctx, NULL,
&server->input, &server->output,
&server->iostream, &error) == 0);
- test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL,
+ test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL, 0,
&client->input, &client->output,
&client->iostream, &error) == 0);
test_assert(io_stream_create_ssl_server(server->ctx, NULL,
&server->input, &server->output,
&server->iostream, &error) == 0);
- test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL,
+ test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL, 0,
&client->input, &client->output,
&client->iostream, &error) == 0);
}
if (io_stream_create_ssl_client(client->ssl_ctx, client->set.host,
- client->event,
+ client->event, 0,
&client->input, &client->output,
&client->ssl_iostream, &error) < 0) {
e_error(client->event,
}
if (io_stream_create_ssl_client(ssl_ctx, proxy->host,
- proxy->event,
+ proxy->event, 0,
&proxy->server_input,
&proxy->server_output,
&proxy->server_ssl_iostream,