bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "lib.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "ioloop.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "buffer.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "iostream-ssl.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "master-service-private.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "master-service-settings.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "master-service-ssl-settings.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include "master-service-ssl.h"
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen#include <unistd.h>
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainenint master_service_ssl_init(struct master_service *service,
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen struct istream **input, struct ostream **output,
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen struct ssl_iostream **ssl_iostream_r,
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen const char **error_r)
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen{
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen const struct master_service_ssl_settings *set;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen struct ssl_iostream_settings ssl_set;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen i_assert(service->ssl_ctx_initialized);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen if (service->ssl_ctx == NULL) {
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen *error_r = "Failed to initialize SSL context";
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen return -1;
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen }
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen set = master_service_ssl_settings_get(service);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&ssl_set);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.verbose = set->verbose_ssl;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.verify_remote_cert = set->ssl_verify_client_cert;
3b4bd183cc469f70eb91d82a7f01f60ffc24ca5bTimo Sirainen return io_stream_create_ssl_server(service->ssl_ctx, &ssl_set,
3b4bd183cc469f70eb91d82a7f01f60ffc24ca5bTimo Sirainen input, output, ssl_iostream_r, error_r);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen}
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainenbool master_service_ssl_is_enabled(struct master_service *service)
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen{
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen return service->ssl_ctx != NULL;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen}
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainenvoid master_service_ssl_ctx_init(struct master_service *service)
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen{
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen const struct master_service_ssl_settings *set;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen struct ssl_iostream_settings ssl_set;
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen const char *error;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen if (service->ssl_ctx_initialized)
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen return;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen service->ssl_ctx_initialized = TRUE;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen /* must be called after master_service_init_finish() so that if
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen initialization fails we can close the SSL listeners */
fde095c17b70113d89684d12ea359b467e307b5aTimo Sirainen i_assert(service->listeners != NULL || service->socket_count == 0);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen set = master_service_ssl_settings_get(service);
c53dd9a6ef9ac43353f292c687a13b3dbb2bbbb9Timo Sirainen if (strcmp(set->ssl, "no") == 0) {
c53dd9a6ef9ac43353f292c687a13b3dbb2bbbb9Timo Sirainen /* SSL disabled, don't use it */
c53dd9a6ef9ac43353f292c687a13b3dbb2bbbb9Timo Sirainen return;
c53dd9a6ef9ac43353f292c687a13b3dbb2bbbb9Timo Sirainen }
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&ssl_set);
976dee5384c4827dc648c9bc53825390521c388eMartti Rannanjärvi ssl_set.min_protocol = set->ssl_min_protocol;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.cipher_list = set->ssl_cipher_list;
c4d66e8ccbb8440622f1a70791ed2a8f99659af1Juha Koho ssl_set.curve_list = set->ssl_curve_list;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.ca = set->ssl_ca;
9f7ba3807f77209a65e0faa56cac8545b06cd116Aki Tuomi ssl_set.cert.cert = set->ssl_cert;
9f7ba3807f77209a65e0faa56cac8545b06cd116Aki Tuomi ssl_set.cert.key = set->ssl_key;
878734e3d9ff8da069a2567f18ca61eefa3116aaAki Tuomi ssl_set.dh = set->ssl_dh;
9f7ba3807f77209a65e0faa56cac8545b06cd116Aki Tuomi ssl_set.cert.key_password = set->ssl_key_password;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.cert_username_field = set->ssl_cert_username_field;
15707468f4889e9fee15ae8dd7ddc302b174949aAki Tuomi if (set->ssl_alt_cert != NULL && *set->ssl_alt_cert != '\0') {
15707468f4889e9fee15ae8dd7ddc302b174949aAki Tuomi ssl_set.alt_cert.cert = set->ssl_alt_cert;
15707468f4889e9fee15ae8dd7ddc302b174949aAki Tuomi ssl_set.alt_cert.key = set->ssl_alt_key;
15707468f4889e9fee15ae8dd7ddc302b174949aAki Tuomi ssl_set.alt_cert.key_password = set->ssl_key_password;
15707468f4889e9fee15ae8dd7ddc302b174949aAki Tuomi }
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.crypto_device = set->ssl_crypto_device;
f134770dbca7ce9b283f9c6a76011379f2f2a0cdAki Tuomi ssl_set.skip_crl_check = !set->ssl_require_crl;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.verbose = set->verbose_ssl;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen ssl_set.verify_remote_cert = set->ssl_verify_client_cert;
f974134f495e47ba7173f5b0f75fbd5cbacf1fe2Timo Sirainen ssl_set.prefer_server_ciphers = set->ssl_prefer_server_ciphers;
9864489d143fafe6f08f6a6d98a478d36458aa98Phil Carmody ssl_set.compression = set->parsed_opts.compression;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen if (ssl_iostream_context_init_server(&ssl_set, &service->ssl_ctx,
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen &error) < 0) {
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen i_error("SSL context initialization failed, disabling SSL: %s",
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen error);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen master_service_ssl_io_listeners_remove(service);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen return;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen }
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen}
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainenvoid master_service_ssl_ctx_deinit(struct master_service *service)
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen{
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen if (service->ssl_ctx != NULL)
15d19d6e4daf460d8d2c82b981e23996dbdf7ba5Timo Sirainen ssl_iostream_context_unref(&service->ssl_ctx);
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen service->ssl_ctx_initialized = FALSE;
cf3894a2a22dc76247275e7ad7a5417fa5f27a28Timo Sirainen}