1 /*-
2  * Copyright 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 #ifndef RSPAMD_MILTER_H
17 #define RSPAMD_MILTER_H
18 
19 #include "config.h"
20 #include "fstring.h"
21 #include "addr.h"
22 #include "contrib/libucl/ucl.h"
23 #include "contrib/libev/ev.h"
24 #include "ref.h"
25 
26 #ifdef  __cplusplus
27 extern "C" {
28 #endif
29 
30 enum rspamd_milter_reply {
31 	RSPAMD_MILTER_ADDRCPT = '+',
32 	RSPAMD_MILTER_DELRCPT = '-',
33 	RSPAMD_MILTER_ACCEPT = 'a',
34 	RSPAMD_MILTER_CONTINUE = 'c',
35 	RSPAMD_MILTER_DISCARD = 'd',
36 	RSPAMD_MILTER_CHGFROM = 'e',
37 	RSPAMD_MILTER_ADDHEADER = 'h',
38 	RSPAMD_MILTER_CHGHEADER = 'm',
39 	RSPAMD_MILTER_INSHEADER = 'i',
40 	RSPAMD_MILTER_REPLBODY = 'b',
41 	RSPAMD_MILTER_REJECT = 'r',
42 	RSPAMD_MILTER_TEMPFAIL = 't',
43 	RSPAMD_MILTER_REPLYCODE = 'y',
44 	RSPAMD_MILTER_OPTNEG = 'O',
45 	RSPAMD_MILTER_PROGRESS = 'p',
46 	RSPAMD_MILTER_QUARANTINE = 'q',
47 };
48 
49 struct rspamd_email_address;
50 struct ev_loop;
51 struct rspamd_http_message;
52 struct rspamd_config;
53 
54 struct rspamd_milter_context {
55 	const gchar *spam_header;
56 	const gchar *client_ca_name;
57 	const gchar *reject_message;
58 	void *sessions_cache;
59 	struct rspamd_config *cfg;
60 	gboolean discard_on_reject;
61 	gboolean quarantine_on_reject;
62 };
63 
64 struct rspamd_milter_session {
65 	GHashTable *macros;
66 	rspamd_inet_addr_t *addr;
67 	struct rspamd_email_address *from;
68 	GPtrArray *rcpts;
69 	rspamd_fstring_t *helo;
70 	rspamd_fstring_t *hostname;
71 	rspamd_fstring_t *message;
72 	void *priv;
73 	ref_entry_t ref;
74 };
75 
76 typedef void (*rspamd_milter_finish) (gint fd,
77 									  struct rspamd_milter_session *session, void *ud);
78 
79 typedef void (*rspamd_milter_error) (gint fd,
80 									 struct rspamd_milter_session *session,
81 									 void *ud, GError *err);
82 
83 /**
84  * Handles socket with milter protocol
85  * @param fd
86  * @param finish_cb
87  * @param error_cb
88  * @param ud
89  * @return
90  */
91 gboolean rspamd_milter_handle_socket (gint fd, ev_tstamp timeout,
92 									  rspamd_mempool_t *pool,
93 									  struct ev_loop *ev_base, rspamd_milter_finish finish_cb,
94 									  rspamd_milter_error error_cb, void *ud);
95 
96 /**
97  * Updates userdata for a session, returns previous userdata
98  * @param session
99  * @param ud
100  * @return
101  */
102 void *rspamd_milter_update_userdata (struct rspamd_milter_session *session,
103 									 void *ud);
104 
105 /**
106  * Sets SMTP reply string
107  * @param session
108  * @param rcode
109  * @param xcode
110  * @param reply
111  * @return
112  */
113 gboolean rspamd_milter_set_reply (struct rspamd_milter_session *session,
114 								  rspamd_fstring_t *rcode,
115 								  rspamd_fstring_t *xcode,
116 								  rspamd_fstring_t *reply);
117 
118 /**
119  * Send some action to the MTA
120  * @param fd
121  * @param session
122  * @param act
123  * @return
124  */
125 gboolean rspamd_milter_send_action (struct rspamd_milter_session *session,
126 									enum rspamd_milter_reply act, ...);
127 
128 /**
129  * Adds some header
130  * @param session
131  * @param name
132  * @param value
133  * @return
134  */
135 gboolean rspamd_milter_add_header (struct rspamd_milter_session *session,
136 								   GString *name, GString *value);
137 
138 /**
139  * Removes some header
140  * @param session
141  * @param name
142  * @return
143  */
144 gboolean rspamd_milter_del_header (struct rspamd_milter_session *session,
145 								   GString *name);
146 
147 void rspamd_milter_session_unref (struct rspamd_milter_session *session);
148 
149 struct rspamd_milter_session *rspamd_milter_session_ref (
150 		struct rspamd_milter_session *session);
151 
152 /**
153  * Converts milter session to HTTP session that is suitable for Rspamd
154  * @param session
155  * @return
156  */
157 struct rspamd_http_message *rspamd_milter_to_http (
158 		struct rspamd_milter_session *session);
159 
160 /**
161  * Sends task results to the
162  * @param session
163  * @param results
164  */
165 void rspamd_milter_send_task_results (struct rspamd_milter_session *session,
166 									  const ucl_object_t *results,
167 									  const gchar *new_body,
168 									  gsize bodylen);
169 
170 /**
171  * Init internal milter context
172  * @param spam_header spam header name (must NOT be NULL)
173  */
174 void rspamd_milter_init_library (const struct rspamd_milter_context *ctx);
175 
176 /**
177  * Returns pool for a session
178  * @param session
179  * @return
180  */
181 rspamd_mempool_t *rspamd_milter_get_session_pool (
182 		struct rspamd_milter_session *session);
183 
184 #ifdef  __cplusplus
185 }
186 #endif
187 
188 #endif
189