-I$(top_srcdir)/src/lib-index \
-I$(top_srcdir)/src/lib-master \
-I$(top_srcdir)/src/lib-lda \
+ -I$(top_srcdir)/src/lib-ssl-iostream \
-I$(top_srcdir)/src/lib-storage \
-I$(top_srcdir)/src/lib-storage/index \
-I$(top_srcdir)/src/lib-storage/index/raw
#include "var-expand.h"
#include "settings-parser.h"
#include "master-service.h"
+#include "master-service-ssl.h"
#include "master-service-settings.h"
+#include "iostream-ssl.h"
#include "mail-namespace.h"
#include "mail-storage.h"
#include "mail-storage-service.h"
if (strcmp(cmd, "LHLO") == 0)
return cmd_lhlo(client, args);
+ if (strcmp(cmd, "STARTTLS") == 0 &&
+ master_service_ssl_is_enabled(master_service))
+ return cmd_starttls(client);
if (strcmp(cmd, "MAIL") == 0)
return cmd_mail(client, args);
if (strcmp(cmd, "RCPT") == 0)
io_remove(&client->io);
if (client->to_idle != NULL)
timeout_remove(&client->to_idle);
+ if (client->ssl_iostream != NULL)
+ ssl_iostream_destroy(&client->ssl_iostream);
i_stream_destroy(&client->input);
o_stream_destroy(&client->output);
static const char *client_get_disconnect_reason(struct client *client)
{
+ const char *err;
+
+ if (client->ssl_iostream != NULL &&
+ !ssl_iostream_is_handshaked(client->ssl_iostream)) {
+ err = ssl_iostream_get_last_error(client->ssl_iostream);
+ if (err != NULL) {
+ return t_strdup_printf("TLS handshaking failed: %s",
+ err);
+ }
+ }
errno = client->input->stream_errno != 0 ?
client->input->stream_errno :
client->output->stream_errno;
struct io *io;
struct istream *input;
struct ostream *output;
+ struct ssl_iostream *ssl_iostream;
struct timeout *to_idle;
time_t last_input;
#include "restrict-access.h"
#include "settings-parser.h"
#include "master-service.h"
+#include "master-service-ssl.h"
+#include "iostream-ssl.h"
#include "rfc822-parser.h"
#include "message-date.h"
#include "auth-master.h"
client_state_reset(client);
client_send_line(client, "250-%s", client->my_domain);
+ if (master_service_ssl_is_enabled(master_service) &&
+ client->ssl_iostream == NULL)
+ client_send_line(client, "250-STARTTLS");
if (client_is_trusted(client))
client_send_line(client, "250-XCLIENT ADDR PORT TTL TIMEOUT");
client_send_line(client, "250-8BITMIME");
return 0;
}
+int cmd_starttls(struct client *client)
+{
+ struct ostream *plain_output = client->output;
+ const char *error;
+
+ if (client->ssl_iostream != NULL) {
+ o_stream_nsend_str(client->output,
+ "443 5.5.1 TLS is already active.\r\n");
+ return 0;
+ }
+
+ if (master_service_ssl_init(master_service,
+ &client->input, &client->output,
+ &client->ssl_iostream, &error) < 0) {
+ i_error("TLS initialization failed: %s", error);
+ o_stream_nsend_str(client->output,
+ "454 4.7.0 Internal error, TLS not available.\r\n");
+ return 0;
+ }
+ o_stream_nsend_str(plain_output,
+ "220 2.0.0 Begin TLS negotiation now.\r\n");
+ if (ssl_iostream_handshake(client->ssl_iostream) < 0) {
+ client_destroy(client, NULL, NULL);
+ return -1;
+ }
+ return 0;
+}
+
static int parse_address(const char *str, const char **address_r,
const char **rest_r)
{
struct client;
int cmd_lhlo(struct client *client, const char *args);
+int cmd_starttls(struct client *client);
int cmd_mail(struct client *client, const char *args);
int cmd_rcpt(struct client *client, const char *args);
int cmd_quit(struct client *client, const char *args);
&lmtp_setting_parser_info,
NULL
};
- enum master_service_flags service_flags = 0;
+ enum master_service_flags service_flags =
+ MASTER_SERVICE_FLAG_USE_SSL_SETTINGS;
enum mail_storage_service_flags storage_service_flags =
MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT |
MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP |
service_flags |= MASTER_SERVICE_FLAG_STANDALONE |
MASTER_SERVICE_FLAG_STD_CLIENT;
} else {
- service_flags |= MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN;
+ service_flags |= MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN ;
}
master_service = master_service_init("lmtp", service_flags,