You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mime_headers.h 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright 2023 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 SRC_LIBMIME_MIME_HEADERS_H_
  17. #define SRC_LIBMIME_MIME_HEADERS_H_
  18. #include "config.h"
  19. #include "libutil/mem_pool.h"
  20. #include "libutil/addr.h"
  21. #include "khash.h"
  22. #include "contrib/libucl/ucl.h"
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. struct rspamd_task;
  27. enum rspamd_rfc2047_encoding {
  28. RSPAMD_RFC2047_QP = 0,
  29. RSPAMD_RFC2047_BASE64,
  30. };
  31. enum rspamd_mime_header_flags {
  32. RSPAMD_HEADER_GENERIC = 0u,
  33. RSPAMD_HEADER_RECEIVED = 1u << 0u,
  34. RSPAMD_HEADER_TO = 1u << 2u,
  35. RSPAMD_HEADER_CC = 1u << 3u,
  36. RSPAMD_HEADER_BCC = 1u << 4u,
  37. RSPAMD_HEADER_FROM = 1u << 5u,
  38. RSPAMD_HEADER_MESSAGE_ID = 1u << 6u,
  39. RSPAMD_HEADER_SUBJECT = 1u << 7u,
  40. RSPAMD_HEADER_RETURN_PATH = 1u << 8u,
  41. RSPAMD_HEADER_DELIVERED_TO = 1u << 9u,
  42. RSPAMD_HEADER_SENDER = 1u << 10u,
  43. RSPAMD_HEADER_RCPT = 1u << 11u,
  44. RSPAMD_HEADER_UNIQUE = 1u << 12u,
  45. RSPAMD_HEADER_EMPTY_SEPARATOR = 1u << 13u,
  46. RSPAMD_HEADER_TAB_SEPARATED = 1u << 14u,
  47. RSPAMD_HEADER_MODIFIED = 1u << 15u, /* Means we need to check modified chain */
  48. RSPAMD_HEADER_ADDED = 1u << 16u, /* A header has been artificially added */
  49. RSPAMD_HEADER_REMOVED = 1u << 17u, /* A header has been artificially removed */
  50. RSPAMD_HEADER_NON_EXISTING = 1u << 18u, /* Header was not in the original message */
  51. };
  52. struct rspamd_mime_header {
  53. const char *raw_value; /* As it is in the message (unfolded and unparsed) */
  54. gsize raw_len;
  55. unsigned int order;
  56. int flags; /* see enum rspamd_mime_header_flags */
  57. /* These are zero terminated (historically) */
  58. char *name; /* Also used for key */
  59. char *value;
  60. char *separator;
  61. char *decoded;
  62. struct rspamd_mime_header *modified_chain; /* Headers modified during transform */
  63. struct rspamd_mime_header *prev, *next; /* Headers with the same name */
  64. struct rspamd_mime_header *ord_next; /* Overall order of headers, slist */
  65. };
  66. struct rspamd_mime_headers_table;
  67. /**
  68. * Process headers and store them in `target`
  69. * @param task
  70. * @param target
  71. * @param in
  72. * @param len
  73. * @param check_newlines
  74. */
  75. void rspamd_mime_headers_process(struct rspamd_task *task,
  76. struct rspamd_mime_headers_table *target,
  77. struct rspamd_mime_header **order_ptr,
  78. const char *in, gsize len,
  79. gboolean check_newlines);
  80. /**
  81. * Perform rfc2047 decoding of a header
  82. * @param pool
  83. * @param in
  84. * @param inlen
  85. * @return
  86. */
  87. char *rspamd_mime_header_decode(rspamd_mempool_t *pool, const char *in,
  88. gsize inlen, gboolean *invalid_utf);
  89. /**
  90. * Encode mime header if needed
  91. * @param in
  92. * @param len
  93. * @return newly allocated encoded header
  94. */
  95. char *rspamd_mime_header_encode(const char *in, gsize len);
  96. /**
  97. * Generate new unique message id
  98. * @param fqdn
  99. * @return
  100. */
  101. char *rspamd_mime_message_id_generate(const char *fqdn);
  102. /**
  103. * Get an array of header's values with specified header's name using raw headers
  104. * @param task worker task structure
  105. * @param field header's name
  106. * @return An array of header's values or NULL. It is NOT permitted to free array or values.
  107. */
  108. struct rspamd_mime_header *
  109. rspamd_message_get_header_array(struct rspamd_task *task,
  110. const char *field,
  111. gboolean need_modified);
  112. /**
  113. * Get an array of header's values with specified header's name using raw headers
  114. * @param htb hash table indexed by header name (caseless) with ptr arrays as elements
  115. * @param field header's name
  116. * @return An array of header's values or NULL. It is NOT permitted to free array or values.
  117. */
  118. struct rspamd_mime_header *
  119. rspamd_message_get_header_from_hash(struct rspamd_mime_headers_table *hdrs,
  120. const char *field,
  121. gboolean need_modified);
  122. /**
  123. * Modifies a header (or insert one if not found)
  124. * @param hdrs
  125. * @param hdr_name
  126. * @param obj an array of modified values
  127. *
  128. */
  129. void rspamd_message_set_modified_header(struct rspamd_task *task,
  130. struct rspamd_mime_headers_table *hdrs,
  131. const char *hdr_name,
  132. const ucl_object_t *obj,
  133. struct rspamd_mime_header **order_ptr);
  134. /**
  135. * Cleans up hash table of the headers
  136. * @param htb
  137. */
  138. void rspamd_message_headers_unref(struct rspamd_mime_headers_table *hdrs);
  139. struct rspamd_mime_headers_table *rspamd_message_headers_ref(struct rspamd_mime_headers_table *hdrs);
  140. /**
  141. * Init headers hash
  142. * @return
  143. */
  144. struct rspamd_mime_headers_table *rspamd_message_headers_new(void);
  145. /**
  146. * Returns size for a headers table
  147. * @param hdrs
  148. * @return
  149. */
  150. gsize rspamd_mime_headers_count(struct rspamd_mime_headers_table *hdrs);
  151. typedef bool(rspamd_hdr_traverse_func_t)(const char *, const struct rspamd_mime_header *, void *);
  152. /**
  153. * Traverse all headers in a table
  154. * @param func
  155. * @param ud
  156. * @return
  157. */
  158. bool rspamd_mime_headers_foreach(const struct rspamd_mime_headers_table *,
  159. rspamd_hdr_traverse_func_t func, void *ud);
  160. /**
  161. * Strip rfc822 CFWS sequences from a string in place
  162. * @param input input
  163. * @param len length of the input
  164. * @return new length of the input
  165. */
  166. gsize rspamd_strip_smtp_comments_inplace(char *input, gsize len);
  167. /**
  168. * Unfold header in place
  169. * @param hdr header value
  170. * @param len length of the header
  171. * @return new unfolded length
  172. */
  173. gsize rspamd_message_header_unfold_inplace(char *hdr, gsize len);
  174. #ifdef __cplusplus
  175. }
  176. #endif
  177. #endif /* SRC_LIBMIME_MIME_HEADERS_H_ */