aboutsummaryrefslogtreecommitdiffstats
path: root/src/smtp.h
blob: a5a9533bc9e5ff244facfd9cb3c3f9e2be38baad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifndef RSPAMD_SMTP_H
#define RSPAMD_SMTP_H

#include "config.h"
#include "main.h"
#include "upstream.h"

struct smtp_upstream {
	struct upstream up;
	
	const gchar *name;
	struct in_addr addr;
	guint16 port;
	gboolean is_unix;
}; 

struct rspamd_dns_resolver;

#define MAX_UPSTREAM 128
#define DEFAULT_MAX_ERRORS 10

enum rspamd_smtp_stage {
	SMTP_STAGE_CONNECT = 0,
	SMTP_STAGE_HELO,
	SMTP_STAGE_MAIL,
	SMTP_STAGE_RCPT,
	SMTP_STAGE_DATA,
	SMTP_STAGE_MAX
};

struct smtp_worker_ctx {
	struct smtp_upstream upstreams[MAX_UPSTREAM];
	size_t upstream_num;
	gchar *upstreams_str;
	
	memory_pool_t *pool;
	gchar *smtp_banner;
	gchar *smtp_banner_str;
	guint32 smtp_delay;
	guint32 delay_jitter;
	guint32 smtp_timeout_raw;
	struct timeval smtp_timeout;

	gboolean use_xclient;
	gboolean helo_required;
	gchar *smtp_capabilities;
	gchar *smtp_capabilities_str;
	gchar *reject_message;
	gsize max_size;
	guint32 max_errors;
	gchar *metric;
	GList *smtp_filters[SMTP_STAGE_MAX];
	struct rspamd_dns_resolver *resolver;
};

enum rspamd_smtp_state {
	SMTP_STATE_RESOLVE_REVERSE = 0,
	SMTP_STATE_RESOLVE_NORMAL,
	SMTP_STATE_DELAY,
	SMTP_STATE_GREETING,
	SMTP_STATE_HELO,
	SMTP_STATE_FROM,
	SMTP_STATE_RCPT,
	SMTP_STATE_BEFORE_DATA,
	SMTP_STATE_DATA,
	SMTP_STATE_AFTER_DATA,
	SMTP_STATE_END,
	SMTP_STATE_QUIT,
	SMTP_STATE_WAIT_UPSTREAM,
	SMTP_STATE_IN_SENDFILE,
	SMTP_STATE_ERROR,
	SMTP_STATE_CRITICAL_ERROR,
	SMTP_STATE_WRITE_ERROR
};

struct smtp_session {
	struct smtp_worker_ctx *ctx;
	struct config_file *cfg;
	memory_pool_t *pool;

	enum rspamd_smtp_state state;
	enum rspamd_smtp_state upstream_state;
	struct rspamd_worker *worker;
	struct worker_task *task;
	struct in_addr client_addr;
	gchar *hostname;
	gchar *error;
	gchar *temp_name;
	gint sock;
	gint upstream_sock;
	gint temp_fd;
	size_t temp_size;
	time_t session_time;

	gchar *helo;
	GList *from;
	GList *rcpt;
	GList *cur_rcpt;

	guint errors;
	
	struct rspamd_async_session *s;
	rspamd_io_dispatcher_t *dispatcher;
	rspamd_io_dispatcher_t *upstream_dispatcher;

	struct smtp_upstream *upstream;

	struct event *delay_timer;

	gboolean resolved;
	gboolean esmtp;
	struct rspamd_dns_resolver *resolver;
};

typedef gboolean (*smtp_filter_t)(struct smtp_session *session, gpointer filter_data);

struct smtp_filter {
	smtp_filter_t filter;
	gpointer filter_data;
};

/*
 * Perform initialization of SMTP worker
 */
gpointer init_smtp_worker (void);

/*
 * Start SMTP worker
 */
void start_smtp_worker (struct rspamd_worker *worker);

/*
 * Register new SMTP filter
 * XXX: work is still in progress
 */
void register_smtp_filter (struct smtp_worker_ctx *ctx, enum rspamd_smtp_stage stage, smtp_filter_t filter, gpointer filter_data);

#endif