Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright 2024 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_SPF_H
  17. #define RSPAMD_SPF_H
  18. #include "config.h"
  19. #include "ref.h"
  20. #include "addr.h"
  21. #ifdef __cplusplus
  22. extern "C" {
  23. #endif
  24. struct rspamd_task;
  25. struct spf_resolved;
  26. typedef void (*spf_cb_t)(struct spf_resolved *record,
  27. struct rspamd_task *task, gpointer cbdata);
  28. typedef enum spf_mech_e {
  29. SPF_FAIL,
  30. SPF_SOFT_FAIL,
  31. SPF_PASS,
  32. SPF_NEUTRAL
  33. } spf_mech_t;
  34. static inline char spf_mech_char(spf_mech_t mech)
  35. {
  36. switch (mech) {
  37. case SPF_FAIL:
  38. return '-';
  39. case SPF_SOFT_FAIL:
  40. return '~';
  41. case SPF_PASS:
  42. return '+';
  43. case SPF_NEUTRAL:
  44. default:
  45. return '?';
  46. }
  47. }
  48. typedef enum spf_action_e {
  49. SPF_RESOLVE_MX,
  50. SPF_RESOLVE_A,
  51. SPF_RESOLVE_PTR,
  52. SPF_RESOLVE_AAA,
  53. SPF_RESOLVE_REDIRECT,
  54. SPF_RESOLVE_INCLUDE,
  55. SPF_RESOLVE_EXISTS,
  56. SPF_RESOLVE_EXP
  57. } spf_action_t;
  58. #define RSPAMD_SPF_FLAG_IPV6 (1u << 0u)
  59. #define RSPAMD_SPF_FLAG_IPV4 (1u << 1u)
  60. #define RSPAMD_SPF_FLAG_PROCESSED (1u << 2u)
  61. #define RSPAMD_SPF_FLAG_ANY (1u << 3u)
  62. #define RSPAMD_SPF_FLAG_PARSED (1u << 4u)
  63. #define RSPAMD_SPF_FLAG_INVALID (1u << 5u)
  64. #define RSPAMD_SPF_FLAG_REFERENCE (1u << 6u)
  65. #define RSPAMD_SPF_FLAG_REDIRECT (1u << 7u)
  66. #define RSPAMD_SPF_FLAG_TEMPFAIL (1u << 8u)
  67. #define RSPAMD_SPF_FLAG_NA (1u << 9u)
  68. #define RSPAMD_SPF_FLAG_PERMFAIL (1u << 10u)
  69. #define RSPAMD_SPF_FLAG_RESOLVED (1u << 11u)
  70. #define RSPAMD_SPF_FLAG_CACHED (1u << 12u)
  71. /** Default SPF limits for avoiding abuse **/
  72. #define SPF_MAX_NESTING 10
  73. #define SPF_MAX_DNS_REQUESTS 30
  74. #define SPF_MIN_CACHE_TTL (60 * 5) /* 5 minutes */
  75. struct spf_addr {
  76. unsigned char addr6[sizeof(struct in6_addr)];
  77. unsigned char addr4[sizeof(struct in_addr)];
  78. union {
  79. struct {
  80. uint16_t mask_v4;
  81. uint16_t mask_v6;
  82. } dual;
  83. uint32_t idx;
  84. } m;
  85. unsigned int flags;
  86. spf_mech_t mech;
  87. char *spf_string;
  88. struct spf_addr *prev, *next;
  89. };
  90. enum rspamd_spf_resolved_flags {
  91. RSPAMD_SPF_RESOLVED_NORMAL = 0,
  92. RSPAMD_SPF_RESOLVED_TEMP_FAILED = (1u << 0u),
  93. RSPAMD_SPF_RESOLVED_PERM_FAILED = (1u << 1u),
  94. RSPAMD_SPF_RESOLVED_NA = (1u << 2u),
  95. };
  96. struct spf_resolved {
  97. char *domain;
  98. char *top_record;
  99. unsigned int ttl;
  100. int flags;
  101. double timestamp;
  102. uint64_t digest;
  103. GArray *elts; /* Flat list of struct spf_addr */
  104. ref_entry_t ref; /* Refcounting */
  105. };
  106. struct rspamd_spf_cred {
  107. char *local_part;
  108. char *domain;
  109. char *sender;
  110. };
  111. /*
  112. * Resolve spf record for specified task and call a callback after resolution fails/succeed
  113. */
  114. gboolean rspamd_spf_resolve(struct rspamd_task *task,
  115. spf_cb_t callback,
  116. gpointer cbdata,
  117. struct rspamd_spf_cred *cred);
  118. /*
  119. * Get a domain for spf for specified task
  120. */
  121. const char *rspamd_spf_get_domain(struct rspamd_task *task);
  122. struct rspamd_spf_cred *rspamd_spf_get_cred(struct rspamd_task *task);
  123. /*
  124. * Increase refcount
  125. */
  126. struct spf_resolved *_spf_record_ref(struct spf_resolved *rec, const char *loc);
  127. #define spf_record_ref(rec) \
  128. _spf_record_ref((rec), G_STRLOC)
  129. /*
  130. * Decrease refcount
  131. */
  132. void _spf_record_unref(struct spf_resolved *rec, const char *loc);
  133. #define spf_record_unref(rec) \
  134. _spf_record_unref((rec), G_STRLOC)
  135. /**
  136. * Prints address + mask in a freshly allocated string (must be freed)
  137. * @param addr
  138. * @return
  139. */
  140. char *spf_addr_mask_to_string(struct spf_addr *addr);
  141. /**
  142. * Returns spf address that matches the specific task (or nil if not matched)
  143. * @param task
  144. * @param rec
  145. * @return
  146. */
  147. struct spf_addr *spf_addr_match_task(struct rspamd_task *task,
  148. struct spf_resolved *rec);
  149. void spf_library_config(const ucl_object_t *obj);
  150. #ifdef __cplusplus
  151. }
  152. #endif
  153. #endif