print "const struct setting_parser_info *all_default_roots[] = {\n";
print "\t&master_service_setting_parser_info,\n";
print "\t&master_service_ssl_setting_parser_info,\n";
+print "\t&master_service_ssl_server_setting_parser_info,\n";
print "\t&smtp_submit_setting_parser_info,\n";
foreach my $name (sort(keys %parsers)) {
my $module = $parsers{$name};
if (service->want_ssl_settings &&
(input->module != NULL || input->extra_modules != NULL)) {
strarr_push(&conf_argv, "-m");
- strarr_push(&conf_argv, "ssl");
+ strarr_push(&conf_argv, "ssl-server");
}
if (input->parse_full_config)
strarr_push(&conf_argv, "-p");
}
if (service->want_ssl_settings &&
(input->module != NULL || input->extra_modules != NULL))
- str_append(str, "\tmodule=ssl");
+ str_append(str, "\tmodule=ssl-server");
if (input->service != NULL)
str_printfa(str, "\tservice=%s", input->service);
if (input->username != NULL)
if (service->want_ssl_settings) {
tmp_root = &master_service_ssl_setting_parser_info;
array_push_back(&all_roots, &tmp_root);
+ tmp_root = &master_service_ssl_server_setting_parser_info;
+ array_push_back(&all_roots, &tmp_root);
}
if (input->roots != NULL) {
for (i = 0; input->roots[i] != NULL; i++)
const struct setting_parser_context *set_parser)
{
return settings_parser_get_list(set_parser) + 1 +
- (service->want_ssl_settings ? 1 : 0);
+ (service->want_ssl_settings ? 2 : 0);
}
struct setting_parser_context *
static const struct setting_define master_service_ssl_setting_defines[] = {
DEF(ENUM, ssl),
DEF(STR, ssl_ca),
- DEF(STR, ssl_cert),
- DEF(STR, ssl_key),
- DEF(STR, ssl_alt_cert),
- DEF(STR, ssl_alt_key),
- DEF(STR, ssl_key_password),
DEF(STR, ssl_client_ca_file),
DEF(STR, ssl_client_ca_dir),
DEF(STR, ssl_client_cert),
DEF(STR, ssl_client_key),
- DEF(STR, ssl_dh),
DEF(STR, ssl_cipher_list),
DEF(STR, ssl_cipher_suites),
DEF(STR, ssl_curve_list),
#endif
/* keep synced with mail-storage-settings */
.ssl_ca = "",
- .ssl_cert = "",
- .ssl_key = "",
- .ssl_alt_cert = "",
- .ssl_alt_key = "",
- .ssl_key_password = "",
.ssl_client_ca_file = "",
.ssl_client_ca_dir = "",
.ssl_client_cert = "",
.ssl_client_key = "",
- .ssl_dh = "",
.ssl_cipher_list = "ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH",
.ssl_cipher_suites = "", /* Use TLS library provided value */
.ssl_curve_list = "",
.check_func = master_service_ssl_settings_check
};
+#undef DEF
+#define DEF(type, name) \
+ SETTING_DEFINE_STRUCT_##type(#name, name, struct master_service_ssl_server_settings)
+
+static const struct setting_define master_service_ssl_server_setting_defines[] = {
+ DEF(STR, ssl_cert),
+ DEF(STR, ssl_key),
+ DEF(STR, ssl_alt_cert),
+ DEF(STR, ssl_alt_key),
+ DEF(STR, ssl_key_password),
+ DEF(STR, ssl_dh),
+
+ SETTING_DEFINE_LIST_END
+};
+
+static const struct master_service_ssl_server_settings master_service_ssl_server_default_settings = {
+ .ssl_cert = "",
+ .ssl_key = "",
+ .ssl_alt_cert = "",
+ .ssl_alt_key = "",
+ .ssl_key_password = "",
+ .ssl_dh = "",
+};
+
+static const struct setting_parser_info *master_service_ssl_server_setting_dependencies[] = {
+ &master_service_ssl_setting_parser_info,
+ NULL
+};
+
+const struct setting_parser_info master_service_ssl_server_setting_parser_info = {
+ .module_name = "ssl-server",
+ .defines = master_service_ssl_server_setting_defines,
+ .defaults = &master_service_ssl_server_default_settings,
+
+ .type_offset = SIZE_MAX,
+ .struct_size = sizeof(struct master_service_ssl_server_settings),
+
+ .parent_offset = SIZE_MAX,
+ .dependencies = master_service_ssl_server_setting_dependencies,
+};
+
/* <settings checks> */
static bool
master_service_ssl_settings_check(void *_set, pool_t pool ATTR_UNUSED,
return sets[1];
}
+const struct master_service_ssl_server_settings *
+master_service_ssl_server_settings_get(struct master_service *service)
+{
+ void **sets;
+
+ i_assert(service->want_ssl_settings);
+ sets = settings_parser_get_list(service->set_parser);
+ return sets[2];
+}
+
static void master_service_ssl_common_settings_to_iostream_set(
const struct master_service_ssl_settings *ssl_set, pool_t pool,
struct ssl_iostream_settings *set_r)
clients. But at least for now it's needed for login-proxy. */
set_r->ca = p_strdup_empty(pool, ssl_set->ssl_ca);
- set_r->dh = p_strdup(pool, ssl_set->ssl_dh);
set_r->crypto_device = p_strdup(pool, ssl_set->ssl_crypto_device);
set_r->cert_username_field = p_strdup(pool, ssl_set->ssl_cert_username_field);
void master_service_ssl_server_settings_to_iostream_set(
const struct master_service_ssl_settings *ssl_set,
+ const struct master_service_ssl_server_settings *ssl_server_set,
pool_t pool, struct ssl_iostream_settings *set_r)
{
master_service_ssl_common_settings_to_iostream_set(ssl_set, pool, set_r);
- set_r->cert.cert = p_strdup(pool, ssl_set->ssl_cert);
- set_r->cert.key = p_strdup(pool, ssl_set->ssl_key);
- set_r->cert.key_password = p_strdup(pool, ssl_set->ssl_key_password);
- if (ssl_set->ssl_alt_cert != NULL &&
- *ssl_set->ssl_alt_cert != '\0') {
- set_r->alt_cert.cert = p_strdup(pool, ssl_set->ssl_alt_cert);
- set_r->alt_cert.key = p_strdup(pool, ssl_set->ssl_alt_key);
- set_r->alt_cert.key_password = p_strdup(pool, ssl_set->ssl_key_password);
+ set_r->cert.cert = p_strdup(pool, ssl_server_set->ssl_cert);
+ set_r->cert.key = p_strdup(pool, ssl_server_set->ssl_key);
+ set_r->cert.key_password = p_strdup(pool, ssl_server_set->ssl_key_password);
+ if (ssl_server_set->ssl_alt_cert != NULL &&
+ *ssl_server_set->ssl_alt_cert != '\0') {
+ set_r->alt_cert.cert = p_strdup(pool, ssl_server_set->ssl_alt_cert);
+ set_r->alt_cert.key = p_strdup(pool, ssl_server_set->ssl_alt_key);
+ set_r->alt_cert.key_password = p_strdup(pool, ssl_server_set->ssl_key_password);
}
+ set_r->dh = p_strdup(pool, ssl_server_set->ssl_dh);
set_r->verify_remote_cert = ssl_set->ssl_verify_client_cert;
set_r->allow_invalid_cert = !set_r->verify_remote_cert;
}
struct master_service_ssl_settings {
const char *ssl;
const char *ssl_ca;
- const char *ssl_cert;
- const char *ssl_alt_cert;
- const char *ssl_key;
- const char *ssl_alt_key;
- const char *ssl_key_password;
const char *ssl_client_ca_file;
const char *ssl_client_ca_dir;
const char *ssl_client_cert;
const char *ssl_client_key;
- const char *ssl_dh;
const char *ssl_cipher_list;
const char *ssl_cipher_suites;
const char *ssl_curve_list;
} parsed_opts;
};
+struct master_service_ssl_server_settings {
+ const char *ssl_cert;
+ const char *ssl_alt_cert;
+ const char *ssl_key;
+ const char *ssl_alt_key;
+ const char *ssl_key_password;
+ const char *ssl_dh;
+};
+
extern const struct setting_parser_info master_service_ssl_setting_parser_info;
+extern const struct setting_parser_info master_service_ssl_server_setting_parser_info;
const struct master_service_ssl_settings *
master_service_ssl_settings_get(struct master_service *service);
+const struct master_service_ssl_server_settings *
+master_service_ssl_server_settings_get(struct master_service *service);
/* Provides master service ssl settings to iostream settings */
void master_service_ssl_client_settings_to_iostream_set(
const struct master_service_ssl_settings *ssl_set, pool_t pool,
struct ssl_iostream_settings *set_r);
void master_service_ssl_server_settings_to_iostream_set(
- const struct master_service_ssl_settings *ssl_set, pool_t pool,
- struct ssl_iostream_settings *set_r);
+ const struct master_service_ssl_settings *ssl_set,
+ const struct master_service_ssl_server_settings *ssl_server_set,
+ pool_t pool, struct ssl_iostream_settings *set_r);
#endif
void master_service_ssl_ctx_init(struct master_service *service)
{
const struct master_service_ssl_settings *set;
+ const struct master_service_ssl_server_settings *server_set;
struct ssl_iostream_settings ssl_set;
const char *error;
i_assert(service->listeners != NULL || service->socket_count == 0);
set = master_service_ssl_settings_get(service);
+ server_set = master_service_ssl_server_settings_get(service);
if (strcmp(set->ssl, "no") == 0) {
/* SSL disabled, don't use it */
return;
ssl_set.cipher_list = set->ssl_cipher_list;
ssl_set.curve_list = set->ssl_curve_list;
ssl_set.ca = set->ssl_ca;
- ssl_set.cert.cert = set->ssl_cert;
- ssl_set.cert.key = set->ssl_key;
- ssl_set.dh = set->ssl_dh;
- ssl_set.cert.key_password = set->ssl_key_password;
+ ssl_set.cert.cert = server_set->ssl_cert;
+ ssl_set.cert.key = server_set->ssl_key;
+ ssl_set.dh = server_set->ssl_dh;
+ ssl_set.cert.key_password = server_set->ssl_key_password;
ssl_set.cert_username_field = set->ssl_cert_username_field;
- if (set->ssl_alt_cert != NULL && *set->ssl_alt_cert != '\0') {
- ssl_set.alt_cert.cert = set->ssl_alt_cert;
- ssl_set.alt_cert.key = set->ssl_alt_key;
- ssl_set.alt_cert.key_password = set->ssl_key_password;
+ if (server_set->ssl_alt_cert != NULL &&
+ *server_set->ssl_alt_cert != '\0') {
+ ssl_set.alt_cert.cert = server_set->ssl_alt_cert;
+ ssl_set.alt_cert.key = server_set->ssl_alt_key;
+ ssl_set.alt_cert.key_password = server_set->ssl_key_password;
}
ssl_set.crypto_device = set->ssl_crypto_device;
ssl_set.skip_crl_check = !set->ssl_require_crl;
client_alloc(int fd, pool_t pool,
const struct master_service_connection *conn,
const struct login_settings *set,
- const struct master_service_ssl_settings *ssl_set)
+ const struct master_service_ssl_settings *ssl_set,
+ const struct master_service_ssl_server_settings *ssl_server_set)
{
struct client *client;
client->preproxy_pool = pool_alloconly_create(MEMPOOL_GROWING"preproxy pool", 256);
client->set = set;
client->ssl_set = ssl_set;
+ client->ssl_server_set = ssl_server_set;
p_array_init(&client->module_contexts, client->pool, 5);
client->fd = fd;
client->local_name = p_strdup(client->pool, name);
client->set = login_settings_read(client->pool, &client->local_ip,
&client->ip, name,
- &client->ssl_set, &other_sets);
+ &client->ssl_set,
+ &client->ssl_server_set, &other_sets);
master_service_ssl_server_settings_to_iostream_set(client->ssl_set,
- pool_datastack_create(), &ssl_set);
+ client->ssl_server_set, pool_datastack_create(), &ssl_set);
if (ssl_iostream_server_context_cache_get(&ssl_set, &ssl_ctx, &error) < 0) {
*error_r = t_strdup_printf(
"Failed to initialize SSL server context: %s", error);
}
master_service_ssl_server_settings_to_iostream_set(client->ssl_set,
- pool_datastack_create(), &ssl_set);
+ client->ssl_server_set, pool_datastack_create(), &ssl_set);
/* If the client cert is invalid, we'll reply NO to the login
command. */
ssl_set.allow_invalid_cert = TRUE;
struct ssl_iostream *ssl_iostream;
const struct login_settings *set;
const struct master_service_ssl_settings *ssl_set;
+ const struct master_service_ssl_server_settings *ssl_server_set;
const char *session_id, *listener_name, *postlogin_socket_path;
const char *local_name;
const char *client_cert_common_name;
client_alloc(int fd, pool_t pool,
const struct master_service_connection *conn,
const struct login_settings *set,
- const struct master_service_ssl_settings *ssl_set);
+ const struct master_service_ssl_settings *ssl_set,
+ const struct master_service_ssl_server_settings *ssl_server_set);
void client_init(struct client *client, void **other_sets);
void client_disconnect(struct client *client, const char *reason,
bool add_disconnected_prefix);
const struct ip_addr *remote_ip,
const char *local_name,
const struct master_service_ssl_settings **ssl_set_r,
+ const struct master_service_ssl_server_settings **ssl_server_set_r,
void ***other_settings_r)
{
struct master_service_settings_input input;
*ssl_set_r =
login_setting_dup(pool, &master_service_ssl_setting_parser_info,
settings_parser_get_list(parser)[1]);
+ *ssl_server_set_r =
+ login_setting_dup(pool, &master_service_ssl_server_setting_parser_info,
+ settings_parser_get_list(parser)[2]);
*other_settings_r = sets + 1;
return sets[0];
}
#define LOGIN_SETTINGS_H
struct master_service_ssl_settings;
+struct master_service_ssl_server_settings;
struct login_settings {
const char *login_trusted_networks;
const struct ip_addr *remote_ip,
const char *local_name,
const struct master_service_ssl_settings **ssl_set_r,
+ const struct master_service_ssl_server_settings **ssl_server_set_r,
void ***other_settings_r) ATTR_NULL(2, 3, 4);
void login_settings_deinit(void);
const struct login_settings *global_login_settings;
const struct master_service_ssl_settings *global_ssl_settings;
+const struct master_service_ssl_server_settings *global_ssl_server_settings;
void **global_other_settings;
static ARRAY(struct ip_addr) login_source_ips_array;
struct client *client;
const struct login_settings *set;
const struct master_service_ssl_settings *ssl_set;
+ const struct master_service_ssl_server_settings *ssl_server_set;
pool_t pool;
void **other_sets;
pool = pool_alloconly_create("login client", 8*1024);
set = login_settings_read(pool, &conn->local_ip,
- &conn->remote_ip, NULL, &ssl_set, &other_sets);
+ &conn->remote_ip, NULL,
+ &ssl_set, &ssl_server_set, &other_sets);
- client = client_alloc(conn->fd, pool, conn, set, ssl_set);
+ client = client_alloc(conn->fd, pool, conn, set,
+ ssl_set, ssl_server_set);
if (ssl_connections || conn->ssl) {
if (client_init_ssl(client) < 0) {
client_unref(&client);
return;
master_service_ssl_server_settings_to_iostream_set(global_ssl_settings,
- pool_datastack_create(), &ssl_set);
+ global_ssl_server_settings, pool_datastack_create(), &ssl_set);
if (io_stream_ssl_global_init(&ssl_set, &error) < 0)
i_fatal("Failed to initialize SSL library: %s", error);
login_ssl_initialized = TRUE;
global_login_settings =
login_settings_read(set_pool, NULL, NULL, NULL,
&global_ssl_settings,
+ &global_ssl_server_settings,
&global_other_settings);
main_preinit();