ssl-params.c revision 7cb128dc4cae2a03a742f63ba7afee23c78e3af0
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2009-2015 Dovecot authors, see the included COPYING file */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "lib.h"
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen#include "ioloop.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "buffer.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "file-lock.h"
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen#include "read-full.h"
2d8b23805db6f06b8b38174fb6e135386694f429Timo Sirainen#include "write-full.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "master-interface.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "master-service.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "master-service-settings.h"
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen#include "iostream-ssl.h"
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen#include "ssl-params-settings.h"
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen#include "ssl-params.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#include <stdio.h>
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include <stdlib.h>
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include <fcntl.h>
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen#include <sys/stat.h>
6b0e35b29f65a95fe8ae22ed8b5f0f36720c9f45Timo Sirainen#ifdef HAVE_SYS_TIME_H
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen# include <sys/time.h>
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#endif
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#ifdef HAVE_SYS_RESOURCE_H
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen# include <sys/resource.h>
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen#endif
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#define MAX_PARAM_FILE_SIZE 1024*1024
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#define SSL_BUILD_PARAM_TIMEOUT_SECS (60*30)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#define SSL_PARAMS_PRIORITY 15
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstruct ssl_params {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen char *path;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov struct ssl_params_settings set;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov time_t last_mtime;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov ssl_params_callback_t *callback;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov};
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainenstatic void
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenssl_params_if_unchanged(const char *path, time_t mtime,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen unsigned int ssl_dh_parameters_length ATTR_UNUSED)
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen{
eca38954bcf972618f6b85932a3690acbd2b673aTimo Sirainen const char *temp_path, *error;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct file_lock *lock;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov struct stat st, st2;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov mode_t old_mask;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov int fd, ret;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov buffer_t *buf;
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov
1f166c4a7498b4b6bdf6f072edeaebb388cc53ebSergey Kitov#ifdef HAVE_SETPRIORITY
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (setpriority(PRIO_PROCESS, 0, SSL_PARAMS_PRIORITY) < 0)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_error("setpriority(%d) failed: %m", SSL_PARAMS_PRIORITY);
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen#endif
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen temp_path = t_strconcat(path, ".tmp", NULL);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen old_mask = umask(0);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen fd = open(temp_path, O_WRONLY | O_CREAT, 0644);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen umask(old_mask);
fde14422caabc3c4ac4a6c5e3e5cf176cedd90a6Timo Sirainen
fde14422caabc3c4ac4a6c5e3e5cf176cedd90a6Timo Sirainen if (fd == -1)
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen i_fatal("creat(%s) failed: %m", temp_path);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen /* If multiple dovecot instances are running, only one of them needs
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen to regenerate this file. */
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen ret = file_wait_lock(fd, temp_path, F_WRLCK,
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk FILE_LOCK_METHOD_FCNTL,
f0339f522dc9c8e2e8a29ef9a3f937c431c6bd1bTimo Sirainen SSL_BUILD_PARAM_TIMEOUT_SECS, &lock);
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen if (ret < 0)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_fatal("file_try_lock(%s) failed: %m", temp_path);
92d1458b00f4f236c4cec96a696253d3bbf8b05aTimo Sirainen if (ret == 0) {
92d1458b00f4f236c4cec96a696253d3bbf8b05aTimo Sirainen /* someone else is writing this */
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_fatal("Timeout while waiting for %s generation to complete",
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen path);
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen }
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen
9346506a9f4dd9a6285fe8595588e73161849235Timo Sirainen /* make sure the .tmp file is still the one we created */
20e04227229970d148801c507946666e2a9bd838Timo Sirainen if (fstat(fd, &st) < 0)
9b61a6db87c026656f8d2ae214e4486b98a069c0Timo Sirainen i_fatal("fstat(%s) failed: %m", temp_path);
10399559650f552a23949772be79eb6a80198c5aTimo Sirainen if (stat(temp_path, &st2) < 0) {
eca38954bcf972618f6b85932a3690acbd2b673aTimo Sirainen if (errno != ENOENT)
10399559650f552a23949772be79eb6a80198c5aTimo Sirainen i_fatal("stat(%s) failed: %m", temp_path);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen st2.st_ino = st.st_ino+1;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (st.st_ino != st2.st_ino) {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* nope. so someone else just generated the file. */
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_close_fd(&fd);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen }
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen
3764f786a6d13b23c49c9990b816be1e23a1adccAki Tuomi /* check that the parameters file is still the same */
3764f786a6d13b23c49c9990b816be1e23a1adccAki Tuomi if (stat(path, &st) == 0) {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (st.st_mtime != mtime) {
3764f786a6d13b23c49c9990b816be1e23a1adccAki Tuomi i_close_fd(&fd);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen }
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen } else if (errno != ENOENT)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen i_fatal("stat(%s) failed: %m", path);
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* ok, we really want to generate it. */
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (ftruncate(fd, 0) < 0)
e392fcb39a06609af20a9e79017683f194de3ddeTimo Sirainen i_fatal("ftruncate(%s) failed: %m", temp_path);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen i_info("Generating SSL parameters");
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 1024);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (ssl_iostream_generate_params(buf, ssl_dh_parameters_length,
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen &error) < 0) {
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen i_fatal("ssl_iostream_generate_params(%u) failed: %s",
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi ssl_dh_parameters_length, error);
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi }
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen if (write_full(fd, buf->data, buf->used) < 0)
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen i_fatal("write(%s) failed: %m", temp_path);
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
d2cbbecf76de3f4eb945895fab5760ed0a28281cMartti Rannanjärvi if (rename(temp_path, path) < 0)
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen i_fatal("rename(%s, %s) failed: %m", temp_path, path);
d2cbbecf76de3f4eb945895fab5760ed0a28281cMartti Rannanjärvi if (close(fd) < 0)
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi i_fatal("close(%s) failed: %m", temp_path);
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi file_lock_free(&lock);
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
d2cbbecf76de3f4eb945895fab5760ed0a28281cMartti Rannanjärvi i_info("SSL parameters regeneration completed");
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen}
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvistatic void ssl_params_close_listeners(void)
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi{
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi unsigned int i;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
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++) {
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi int fd = MASTER_LISTEN_FD_FIRST + i;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen if (close(fd) < 0)
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen i_error("close(listener %d) failed: %m", fd);
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen }
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen}
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainen
1bb7fb04a0583f0d5160706f24b2df08d31ada46Timo Sirainenstatic void ssl_params_rebuild(struct ssl_params *param)
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen{
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen switch (fork()) {
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen case -1:
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen i_fatal("fork() failed: %m");
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen case 0:
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_close_listeners();
a525be16a69367f43765d20c873b5f168c5b7ea3Martti Rannanjärvi ssl_params_if_unchanged(param->path, param->last_mtime,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen param->set.ssl_dh_parameters_length);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen exit(0);
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen default:
f8ead0942a9b7c8fcf91414ed1b534d5807ca555Timo Sirainen /* parent */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen break;
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen }
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen}
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainen
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainenstatic bool
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainenssl_params_verify(struct ssl_params *param,
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen const unsigned char *data, size_t size)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen{
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi unsigned int bitsize, len;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi bool found = FALSE;
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi /* <bitsize><length><data>... */
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi while (size >= sizeof(bitsize)) {
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi memcpy(&bitsize, data, sizeof(bitsize));
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi if (bitsize == 0) {
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi if (found)
5729882717902b5f3f5d62f71ddf2894b67fc7a6Martti Rannanjärvi return TRUE;
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 return FALSE;
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi }
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi data += sizeof(bitsize);
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi size -= sizeof(bitsize);
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi if (bitsize == param->set.ssl_dh_parameters_length)
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi found = TRUE;
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi if (size < sizeof(len))
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi break;
995c0a88e9a32e0ec1460567ce5f2ce6e7ba1f13Martti Rannanjärvi memcpy(&len, data, sizeof(len));
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (len > size - sizeof(len))
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen break;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen data += sizeof(bitsize) + len;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen size -= sizeof(bitsize) + len;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen }
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen i_error("Corrupted %s", param->path);
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi return FALSE;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen}
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvistatic int ssl_params_read(struct ssl_params *param)
2b4e421b76d997e2ad18c74200d9d8521bed165cMartti Rannanjärvi{
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen unsigned char *buffer;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen struct stat st;
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen int fd, ret;
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen fd = open(param->path, O_RDONLY);
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen if (fd == -1) {
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen if (errno != ENOENT)
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen i_error("open(%s) failed: %m", param->path);
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen return -1;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen }
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen if (fstat(fd, &st) < 0) {
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen i_error("fstat(%s) failed: %m", param->path);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen i_close_fd(&fd);
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen return -1;
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen }
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen param->last_mtime = st.st_mtime;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (st.st_size == 0 || st.st_size > MAX_PARAM_FILE_SIZE) {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_error("Corrupted file: %s", param->path);
7b3b617e946d5b32078baa821f5fc05f775e1dfeMartti Rannanjärvi i_close_fd(&fd);
7b3b617e946d5b32078baa821f5fc05f775e1dfeMartti Rannanjärvi (void)unlink(param->path);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return -1;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
51dbc2d559815da774f8ee5faf0e28df3c8d40c0Timo Sirainen
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen buffer = t_malloc(st.st_size);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen ret = read_full(fd, buffer, st.st_size);
39dea5f2e78f6bfc3adc0655176f596ee211938fTimo Sirainen if (ret < 0)
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);
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen ret = -1;
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen } else if (!ssl_params_verify(param, buffer, st.st_size)) {
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen ret = -1;
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen } else {
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen param->callback(buffer, st.st_size);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen }
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen if (close(fd) < 0)
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen i_error("close(%s) failed: %m", param->path);
8f7e81b327b8b5bf34262f6755df6d4481760d23Timo Sirainen return ret;
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen}
02d91785bcf42ced46080db91c29bb534fbe2d1cTimo Sirainen
62300a38f91227b9de043a9a8ec1d4f1978e1138Timo Sirainenstruct ssl_params *
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenssl_params_init(const char *path, ssl_params_callback_t *callback,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen const struct ssl_params_settings *set)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen{
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen struct ssl_params *param;
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen param = i_new(struct ssl_params, 1);
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen param->path = i_strdup(path);
c4478af52de63804efef2055580adf1dfc8679c6Timo Sirainen param->set = *set;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen param->callback = callback;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen ssl_params_refresh(param);
c4478af52de63804efef2055580adf1dfc8679c6Timo Sirainen return param;
54a8bb6e9b852d9a96a8cdda1bb55a85ce0e10daTimo Sirainen}
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainen
048e40f9364fa68482bc276dd4a5d595a3d742e9Timo Sirainenvoid ssl_params_refresh(struct ssl_params *param)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen{
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi if (ssl_params_read(param) < 0)
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi ssl_params_rebuild(param);
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi}
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvivoid ssl_params_deinit(struct ssl_params **_param)
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi{
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi struct ssl_params *param = *_param;
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi *_param = NULL;
5997118fa7aee2535edac28092261ca085a958aeMartti Rannanjärvi i_free(param->path);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen i_free(param);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen}