summaryrefslogtreecommitdiffstats
path: root/src/lib-smtp/smtp-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-smtp/smtp-client.c')
-rw-r--r--src/lib-smtp/smtp-client.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/lib-smtp/smtp-client.c b/src/lib-smtp/smtp-client.c
new file mode 100644
index 0000000..653dd0e
--- /dev/null
+++ b/src/lib-smtp/smtp-client.c
@@ -0,0 +1,142 @@
+/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "net.h"
+#include "str.h"
+#include "hash.h"
+#include "array.h"
+#include "ioloop.h"
+#include "istream.h"
+#include "ostream.h"
+#include "connection.h"
+#include "dns-lookup.h"
+#include "iostream-rawlog.h"
+#include "iostream-ssl.h"
+
+#include "smtp-client-private.h"
+
+#define SMTP_DEFAULT_PORT 80
+#define SSMTP_DEFAULT_PORT 465
+
+static struct event_category event_category_smtp_client = {
+ .name = "smtp-client"
+};
+
+/*
+ * Client
+ */
+
+struct smtp_client *smtp_client_init(const struct smtp_client_settings *set)
+{
+ struct smtp_client *client;
+ pool_t pool;
+
+ pool = pool_alloconly_create("smtp client", 1024);
+ client = p_new(pool, struct smtp_client, 1);
+ client->pool = pool;
+
+ client->set.my_ip = set->my_ip;
+ client->set.my_hostname = p_strdup(pool, set->my_hostname);
+
+ client->set.forced_capabilities = set->forced_capabilities;
+ if (set->extra_capabilities != NULL) {
+ client->set.extra_capabilities =
+ p_strarray_dup(pool, set->extra_capabilities);
+ }
+
+ client->set.dns_client = set->dns_client;
+ client->set.dns_client_socket_path =
+ p_strdup(pool, set->dns_client_socket_path);
+ client->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
+
+ if (set->ssl != NULL) {
+ client->set.ssl =
+ ssl_iostream_settings_dup(client->pool, set->ssl);
+ }
+
+ client->set.master_user = p_strdup_empty(pool, set->master_user);
+ client->set.username = p_strdup_empty(pool, set->username);
+ client->set.sasl_mech = set->sasl_mech;
+ if (set->sasl_mech == NULL) {
+ client->set.sasl_mechanisms =
+ p_strdup(pool, set->sasl_mechanisms);
+ }
+
+ client->set.connect_timeout_msecs = set->connect_timeout_msecs != 0 ?
+ set->connect_timeout_msecs :
+ SMTP_DEFAULT_CONNECT_TIMEOUT_MSECS;
+ client->set.command_timeout_msecs = set->command_timeout_msecs != 0 ?
+ set->command_timeout_msecs :
+ SMTP_DEFAULT_COMMAND_TIMEOUT_MSECS;
+ client->set.max_reply_size = set->max_reply_size != 0 ?
+ set->max_reply_size : SMTP_DEFAULT_MAX_REPLY_SIZE;
+ client->set.max_data_chunk_size = set->max_data_chunk_size != 0 ?
+ set->max_data_chunk_size : SMTP_DEFAULT_MAX_DATA_CHUNK_SIZE;
+ client->set.max_data_chunk_pipeline = set->max_data_chunk_pipeline != 0 ?
+ set->max_data_chunk_pipeline : SMTP_DEFAULT_MAX_DATA_CHUNK_PIPELINE;
+
+ client->set.socket_send_buffer_size = set->socket_send_buffer_size;
+ client->set.socket_recv_buffer_size = set->socket_recv_buffer_size;
+ client->set.debug = set->debug;
+ client->set.verbose_user_errors = set->verbose_user_errors;
+
+ smtp_proxy_data_merge(pool, &client->set.proxy_data, &set->proxy_data);
+
+ client->conn_list = smtp_client_connection_list_init();
+
+ /* There is no event log prefix added here, since the client itself does
+ not log anything and the prefix is protocol-dependent. */
+ client->event = event_create(set->event_parent);
+ event_add_category(client->event, &event_category_smtp_client);
+ event_set_forced_debug(client->event, set->debug);
+
+ return client;
+}
+
+void smtp_client_deinit(struct smtp_client **_client)
+{
+ struct smtp_client *client = *_client;
+
+ connection_list_deinit(&client->conn_list);
+
+ if (client->ssl_ctx != NULL)
+ ssl_iostream_context_unref(&client->ssl_ctx);
+ event_unref(&client->event);
+ pool_unref(&client->pool);
+ *_client = NULL;
+}
+
+void smtp_client_switch_ioloop(struct smtp_client *client)
+{
+ struct connection *_conn = client->conn_list->connections;
+
+ /* move connections */
+ for (; _conn != NULL; _conn = _conn->next) {
+ struct smtp_client_connection *conn =
+ (struct smtp_client_connection *)_conn;
+
+ smtp_client_connection_switch_ioloop(conn);
+ }
+}
+
+int smtp_client_init_ssl_ctx(struct smtp_client *client, const char **error_r)
+{
+ const char *error;
+
+ if (client->ssl_ctx != NULL)
+ return 0;
+
+ if (client->set.ssl == NULL) {
+ *error_r = "Requested SSL connection, but no SSL settings given";
+ return -1;
+ }
+ if (ssl_iostream_client_context_cache_get(client->set.ssl,
+ &client->ssl_ctx, &error) < 0) {
+ *error_r = t_strdup_printf("Couldn't initialize SSL context: %s",
+ error);
+ return -1;
+ }
+ return 0;
+}
+
+// FIXME: Implement smtp_client_run()