1 /*-
2  * Copyright 2016-2017 Vsevolod Stakhov
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef RSPAMD_MAIN_H
18 #define RSPAMD_MAIN_H
19 
20 #include "config.h"
21 #include "libutil/fstring.h"
22 #include "libutil/mem_pool.h"
23 #include "libutil/util.h"
24 #include "libserver/logger.h"
25 #include "libserver/http/http_connection.h"
26 #include "libutil/upstream.h"
27 #include "libutil/radix.h"
28 #include "libserver/cfg_file.h"
29 #include "libserver/url.h"
30 #include "libserver/protocol.h"
31 #include "libserver/async_session.h"
32 #include "libserver/roll_history.h"
33 #include "libserver/task.h"
34 
35 #include <openssl/ssl.h>
36 
37 /* Default values */
38 #define FIXED_CONFIG_FILE RSPAMD_CONFDIR "/rspamd.conf"
39 /* Time in seconds to exit for old worker */
40 #define SOFT_SHUTDOWN_TIME 10
41 
42 /* Spam subject */
43 #define SPAM_SUBJECT "*** SPAM *** %s"
44 
45 #ifdef CRLF
46 #undef CRLF
47 #undef CR
48 #undef LF
49 #endif
50 
51 #define CRLF "\r\n"
52 #define CR '\r'
53 #define LF '\n'
54 
55 #ifdef  __cplusplus
56 extern "C" {
57 #endif
58 
59 struct rspamd_main;
60 
61 enum rspamd_worker_flags {
62 	RSPAMD_WORKER_HAS_SOCKET = (1 << 0),
63 	RSPAMD_WORKER_UNIQUE = (1 << 1),
64 	RSPAMD_WORKER_THREADED = (1 << 2),
65 	RSPAMD_WORKER_KILLABLE = (1 << 3),
66 	RSPAMD_WORKER_ALWAYS_START = (1 << 4),
67 	RSPAMD_WORKER_SCANNER = (1 << 5),
68 	RSPAMD_WORKER_CONTROLLER = (1 << 6),
69 	RSPAMD_WORKER_NO_TERMINATE_DELAY = (1 << 7),
70 	RSPAMD_WORKER_OLD_CONFIG = (1 << 8),
71 };
72 
73 struct rspamd_worker_accept_event {
74 	ev_io accept_ev;
75 	ev_timer throttling_ev;
76 	struct ev_loop *event_loop;
77 	struct rspamd_worker_accept_event *prev, *next;
78 };
79 
80 typedef void (*rspamd_worker_term_cb) (EV_P_ ev_child *, struct rspamd_main *,
81 									   struct rspamd_worker *);
82 
83 struct rspamd_worker_heartbeat {
84 	ev_timer heartbeat_ev;          /**< used by main for checking heartbeats and by workers to send heartbeats */
85 	ev_tstamp last_event;           /**< last heartbeat received timestamp */
86 	gint64 nbeats;                  /**< positive for beats received, negative for beats missed */
87 };
88 
89 enum rspamd_worker_state {
90 	rspamd_worker_state_running = 0,
91 	rspamd_worker_state_wanna_die,
92 	rspamd_worker_state_terminating,
93 	rspamd_worker_wait_connections,
94 	rspamd_worker_wait_final_scripts,
95 	rspamd_worker_wanna_die
96 };
97 
98 /**
99  * Worker process structure
100  */
101 struct rspamd_worker {
102 	pid_t pid;                      /**< pid of worker									*/
103 	pid_t ppid;                     /**< pid of parent									*/
104 	guint index;                    /**< index number									*/
105 	guint nconns;                   /**< current connections count						*/
106 	enum rspamd_worker_state state; /**< current worker state							*/
107 	gboolean cores_throttled;       /**< set to true if cores throttling took place		*/
108 	gdouble start_time;             /**< start time										*/
109 	struct rspamd_main *srv;        /**< pointer to server structure					*/
110 	GQuark type;                    /**< process type									*/
111 	GHashTable *signal_events;      /**< signal events									*/
112 	struct rspamd_worker_accept_event *accept_events; /**< socket events				*/
113 	struct rspamd_worker_conf *cf;  /**< worker config data								*/
114 	gpointer ctx;                   /**< worker's specific data							*/
115 	gint flags;                     /**< worker's flags (enum rspamd_worker_flags)		*/
116 	gint control_pipe[2];           /**< control pipe. [0] is used by main process,
117 	                                                   [1] is used by a worker			*/
118 	gint srv_pipe[2];               /**< used by workers to request something from the
119 	                                     main process. [0] - main, [1] - worker			*/
120 	ev_io srv_ev;                   /**< used by main for read workers' requests		*/
121 	struct rspamd_worker_heartbeat hb; /**< heartbeat data */
122 	gpointer control_data;          /**< used by control protocol to handle commands	*/
123 	gpointer tmp_data;              /**< used to avoid race condition to deal with control messages */
124 	ev_child cld_ev;                /**< to allow reaping								*/
125 	rspamd_worker_term_cb term_handler; /**< custom term handler						*/
126 	GHashTable *control_events_pending; /**< control events pending indexed by ptr		*/
127 };
128 
129 struct rspamd_abstract_worker_ctx {
130 	guint64 magic;
131 	/* Events base */
132 	struct ev_loop *event_loop;
133 	/* DNS resolver */
134 	struct rspamd_dns_resolver *resolver;
135 	/* Config */
136 	struct rspamd_config *cfg;
137 	char data[];
138 };
139 
140 struct rspamd_worker_signal_handler;
141 
142 typedef gboolean (*rspamd_worker_signal_cb_t) (
143 		struct rspamd_worker_signal_handler *, void *ud);
144 
145 struct rspamd_worker_signal_handler_elt {
146 	rspamd_worker_signal_cb_t handler;
147 	void *handler_data;
148 	struct rspamd_worker_signal_handler_elt *next, *prev;
149 };
150 
151 struct rspamd_worker_signal_handler {
152 	gint signo;
153 	gboolean enabled;
154 	ev_signal ev_sig;
155 	struct ev_loop *event_loop;
156 	struct rspamd_worker *worker;
157 	struct rspamd_worker_signal_handler_elt *cb;
158 };
159 
160 /**
161  * Common structure representing C module context
162  */
163 struct module_s;
164 
165 struct module_ctx {
166 	gint (*filter) (struct rspamd_task *task);                   /**< pointer to headers process function			*/
167 	struct module_s *mod;                                        /**< module pointer									*/
168 	gboolean enabled;                                            /**< true if module is enabled in configuration		*/
169 };
170 
171 #ifndef WITH_HYPERSCAN
172 #define RSPAMD_FEATURE_HYPERSCAN "0"
173 #else
174 #define RSPAMD_FEATURE_HYPERSCAN "1"
175 #endif
176 #ifndef WITH_PCRE2
177 #define RSPAMD_FEATURE_PCRE2 "0"
178 #else
179 #define RSPAMD_FEATURE_PCRE2 "1"
180 #endif
181 #ifndef WITH_FANN
182 #define RSPAMD_FEATURE_FANN "0"
183 #else
184 #define RSPAMD_FEATURE_FANN "1"
185 #endif
186 #ifndef WITH_SNOWBALL
187 #define RSPAMD_FEATURE_SNOWBALL "0"
188 #else
189 #define RSPAMD_FEATURE_SNOWBALL "1"
190 #endif
191 
192 #define RSPAMD_CUR_MODULE_VERSION 0x1
193 #define RSPAMD_CUR_WORKER_VERSION 0x2
194 
195 #define RSPAMD_FEATURES \
196         RSPAMD_FEATURE_HYPERSCAN RSPAMD_FEATURE_PCRE2 \
197         RSPAMD_FEATURE_FANN RSPAMD_FEATURE_SNOWBALL
198 
199 #define RSPAMD_MODULE_VER \
200         RSPAMD_CUR_MODULE_VERSION, /* Module version */ \
201         RSPAMD_VERSION_NUM, /* Rspamd version */ \
202         RSPAMD_FEATURES /* Compilation features */ \
203 
204 #define RSPAMD_WORKER_VER \
205         RSPAMD_CUR_WORKER_VERSION, /* Worker version */ \
206         RSPAMD_VERSION_NUM, /* Rspamd version */ \
207         RSPAMD_FEATURES /* Compilation features */ \
208 /**
209  * Module
210  */
211 typedef struct module_s {
212 	const gchar *name;
213 
214 	int (*module_init_func) (struct rspamd_config *cfg, struct module_ctx **ctx);
215 
216 	int (*module_config_func) (struct rspamd_config *cfg, bool validate);
217 
218 	int (*module_reconfig_func) (struct rspamd_config *cfg);
219 
220 	int (*module_attach_controller_func) (struct module_ctx *ctx,
221 										  GHashTable *custom_commands);
222 
223 	guint module_version;
224 	guint64 rspamd_version;
225 	const gchar *rspamd_features;
226 	guint ctx_offset;
227 } module_t;
228 
229 enum rspamd_worker_socket_type {
230 	RSPAMD_WORKER_SOCKET_NONE = 0,
231 	RSPAMD_WORKER_SOCKET_TCP = (1 << 0),
232 	RSPAMD_WORKER_SOCKET_UDP = (1 << 1),
233 };
234 
235 struct rspamd_worker_listen_socket {
236 	const rspamd_inet_addr_t *addr;
237 	gint fd;
238 	enum rspamd_worker_socket_type type;
239 	bool is_systemd;
240 };
241 
242 typedef struct worker_s {
243 	const gchar *name;
244 
245 	gpointer (*worker_init_func) (struct rspamd_config *cfg);
246 
247 	void (*worker_start_func) (struct rspamd_worker *worker);
248 
249 	int flags;
250 	int listen_type;
251 	guint worker_version;
252 	guint64 rspamd_version;
253 	const gchar *rspamd_features;
254 } worker_t;
255 
256 /**
257  * Check if loaded worker is compatible with rspamd
258  * @param cfg
259  * @param wrk
260  * @return
261  */
262 gboolean rspamd_check_worker (struct rspamd_config *cfg, worker_t *wrk);
263 
264 /**
265  * Check if loaded module is compatible with rspamd
266  * @param cfg
267  * @param wrk
268  * @return
269  */
270 gboolean rspamd_check_module (struct rspamd_config *cfg, module_t *wrk);
271 
272 struct pidfh;
273 struct rspamd_config;
274 struct tokenizer;
275 struct rspamd_stat_classifier;
276 struct rspamd_classifier_config;
277 struct rspamd_mime_part;
278 struct rspamd_dns_resolver;
279 struct rspamd_task;
280 struct rspamd_cryptobox_library_ctx;
281 
282 /**
283  * Server statistics
284  */
285 struct rspamd_stat {
286 	guint messages_scanned;                             /**< total number of messages scanned				*/
287 	guint actions_stat[METRIC_ACTION_MAX];              /**< statistic for each action						*/
288 	guint connections_count;                            /**< total connections count						*/
289 	guint control_connections_count;                    /**< connections count to control interface			*/
290 	guint messages_learned;                             /**< messages learned								*/
291 };
292 
293 /**
294  * Struct that determine main server object (for logging purposes)
295  */
296 struct rspamd_main {
297 	struct rspamd_config *cfg;                                  /**< pointer to config structure					*/
298 	pid_t pid;                                                  /**< main pid										*/
299 	/* Pid file structure */
300 	rspamd_pidfh_t *pfh;                                        /**< struct pidfh for pidfile						*/
301 	GQuark type;                                                /**< process type									*/
302 	struct rspamd_stat *stat;                                   /**< pointer to statistics							*/
303 
304 	rspamd_mempool_t *server_pool;                              /**< server's memory pool							*/
305 	rspamd_mempool_mutex_t *start_mtx;                          /**< server is starting up							*/
306 	GHashTable *workers;                                        /**< workers pool indexed by pid                    */
307 	GHashTable *spairs;                                         /**< socket pairs requested by workers				*/
308 	rspamd_logger_t *logger;
309 	uid_t workers_uid;                                          /**< worker's uid running to                        */
310 	gid_t workers_gid;                                          /**< worker's gid running to						*/
311 	gboolean is_privilleged;                                    /**< true if run in privilleged mode                */
312 	gboolean wanna_die;                                         /**< no respawn of processes						*/
313 	gboolean cores_throttling;                                  /**< turn off cores when limits are exceeded		*/
314 	struct roll_history *history;                               /**< rolling history								*/
315 	struct ev_loop *event_loop;
316 	ev_signal term_ev, int_ev, hup_ev, usr1_ev;                 /**< signals 										*/
317 	struct rspamd_http_context *http_ctx;
318 };
319 
320 /**
321  * Control session object
322  */
323 struct controller_command;
324 struct controller_session;
325 
326 typedef gboolean (*controller_func_t) (gchar **args,
327 									   struct controller_session *session);
328 
329 struct controller_session {
330 	struct rspamd_worker *worker;                               /**< pointer to worker structure (controller in fact) */
331 	gint sock;                                                  /**< socket descriptor								*/
332 	struct controller_command *cmd;                             /**< real command									*/
333 	struct rspamd_config *cfg;                                  /**< pointer to config file							*/
334 	GList *parts;                                               /**< extracted mime parts							*/
335 	struct rspamd_async_session *s;                             /**< async session object							*/
336 	struct rspamd_dns_resolver *resolver;                       /**< DNS resolver									*/
337 	struct ev_loop *ev_base;                                 /**< Event base										*/
338 };
339 
340 struct zstd_dictionary {
341 	void *dict;
342 	gsize size;
343 	guint id;
344 };
345 
346 struct rspamd_external_libs_ctx {
347 	void **local_addrs;
348 	struct rspamd_cryptobox_library_ctx *crypto_ctx;
349 	struct ottery_config *ottery_cfg;
350 	SSL_CTX *ssl_ctx;
351 	SSL_CTX *ssl_ctx_noverify;
352 	struct zstd_dictionary *in_dict;
353 	struct zstd_dictionary *out_dict;
354 	void *out_zstream;
355 	void *in_zstream;
356 	ref_entry_t ref;
357 };
358 
359 
360 /**
361  * Register custom controller function
362  */
363 void register_custom_controller_command (const gchar *name,
364 										 controller_func_t handler,
365 										 gboolean privilleged,
366 										 gboolean require_message);
367 
368 #ifdef  __cplusplus
369 }
370 #endif
371 
372 #endif