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