ssl-params.c revision 7cb128dc4cae2a03a742f63ba7afee23c78e3af0
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2009-2015 Dovecot authors, see the included COPYING file */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenssl_params_if_unchanged(const char *path, time_t mtime,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen unsigned int ssl_dh_parameters_length ATTR_UNUSED)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (setpriority(PRIO_PROCESS, 0, SSL_PARAMS_PRIORITY) < 0)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_error("setpriority(%d) failed: %m", SSL_PARAMS_PRIORITY);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen fd = open(temp_path, O_WRONLY | O_CREAT, 0644);
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen /* If multiple dovecot instances are running, only one of them needs
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen to regenerate this file. */
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_fatal("file_try_lock(%s) failed: %m", temp_path);
92d1458b00f4f236c4cec96a696253d3bbf8b05aTimo Sirainen /* someone else is writing this */
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_fatal("Timeout while waiting for %s generation to complete",
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen /* make sure the .tmp file is still the one we created */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* nope. so someone else just generated the file. */
3764f786a6d13b23c49c9990b816be1e23a1adccAki Tuomi /* check that the parameters file is still the same */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* ok, we really want to generate it. */
e392fcb39a06609af20a9e79017683f194de3ddeTimo Sirainen i_fatal("ftruncate(%s) failed: %m", temp_path);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 1024);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (ssl_iostream_generate_params(buf, ssl_dh_parameters_length,
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen i_fatal("ssl_iostream_generate_params(%u) failed: %s",
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen i_fatal("rename(%s, %s) failed: %m", temp_path, path);
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi i_fatal("close(%s) failed: %m", temp_path);
d2cbbecf76de3f4eb945895fab5760ed0a28281cMartti Rannanjärvi i_info("SSL parameters regeneration completed");
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvistatic void ssl_params_close_listeners(void)
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi unsigned int i;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi /* we have forked, but the fds are still shared. we can't go
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi io_remove()ing the fds from ioloop, because with many ioloops
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi (e.g. epoll) the fds get removed from the main process's ioloop
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi as well. so we'll just do the closing here manually. */
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi for (i = 0; i < master_service_get_socket_count(master_service); i++) {
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainenstatic void ssl_params_rebuild(struct ssl_params *param)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* child - close listener fds so a long-running ssl-params
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen doesn't cause Dovecot restart to fail */
a525be16a69367f43765d20c873b5f168c5b7ea3Martti Rannanjärvi ssl_params_if_unchanged(param->path, param->last_mtime,
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi /* <bitsize><length><data>... */
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi i_warning("Regenerating %s for ssl_dh_parameters_length=%u",
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi param->path, param->set.ssl_dh_parameters_length);
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi if (bitsize == param->set.ssl_dh_parameters_length)
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvistatic int ssl_params_read(struct ssl_params *param)
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen unsigned char *buffer;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (st.st_size == 0 || st.st_size > MAX_PARAM_FILE_SIZE) {
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi i_error("read(%s) failed: %m", param->path);
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen else if (ret == 0) {
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen i_error("File unexpectedly shrank: %s", param->path);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen } else if (!ssl_params_verify(param, buffer, st.st_size)) {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenssl_params_init(const char *path, ssl_params_callback_t *callback,
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainenvoid ssl_params_refresh(struct ssl_params *param)