1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
|
/* $Id: acl.h,v 1.57 2016/11/02 17:41:05 manu Exp $ */
/*
* Copyright (c) 2004-2012 Emmanuel Dreyfus
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Emmanuel Dreyfus
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ACL_H_
#define _ACL_H_
#include "config.h"
#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
#include "queue.h"
#else
#include <sys/queue.h>
#endif
#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <regex.h>
typedef enum { A_GREYLIST, A_WHITELIST, A_BLACKLIST, A_CONTINUE, } acl_type_t;
typedef enum { AS_NONE, AS_RCPT, AS_DATA, AS_ANY, } acl_stage_t;
typedef enum { AT_NONE, AT_STRING, AT_REGEX, AT_NETBLOCK, AT_OPNUM,
AT_CLOCKSPEC, AT_DNSRBL, AT_MX, AT_URLCHECK, AT_MACRO,
AT_LIST, AT_PROP, AT_SPF, AT_DKIM, AT_NSUPDATE,
AT_LDAPCHECK, AT_TIME, AT_RATELIMIT } acl_data_type_t;
typedef enum {
AC_NONE,
AC_LIST,
AC_EMAIL,
AC_REGEX,
AC_STRING,
AC_STRING_PROP,
AC_HELO,
AC_HELO_RE,
AC_HELO_LIST,
AC_FROM,
AC_FROM_RE,
AC_FROM_LIST,
AC_RAWFROM,
AC_RAWFROM_RE,
AC_RAWFROM_LIST,
AC_RCPT,
AC_RCPT_RE,
AC_RCPT_LIST,
AC_DOMAIN,
AC_DOMAIN_RE,
AC_DOMAIN_LIST,
AC_NETBLOCK,
AC_NETBLOCK_LIST,
AC_BODY,
AC_BODY_LIST,
AC_BODY_RE,
AC_BODY_PROP,
AC_HEADER,
AC_HEADER_LIST,
AC_HEADER_RE,
AC_HEADER_PROP,
AC_DNSRBL,
AC_DNSRBL_LIST,
AC_MX,
AC_MACRO,
AC_MACRO_RE,
AC_MACRO_LIST,
AC_URLCHECK,
AC_URLCHECK_LIST,
AC_LDAPCHECK,
AC_PROP_STR,
AC_PROP_GLOB,
AC_PROP_NUM,
AC_PROP_PROP,
AC_PROP_RE,
AC_HEADERPROP,
AC_AUTH,
AC_AUTH_RE,
AC_AUTH_LIST,
AC_TLS,
AC_TLS_RE,
AC_TLS_LIST,
AC_SPF,
AC_DKIM,
AC_MSGSIZE,
AC_MSGSIZE_PROP,
AC_RCPTCOUNT,
AC_RCPTCOUNT_PROP,
AC_CLOCKSPEC,
AC_CLOCKSPEC_LIST,
AC_GEOIP,
AC_GEOIP_LIST,
AC_P0F,
AC_P0F_RE,
AC_P0F_LIST,
AC_SA,
AC_SASCORE,
AC_SASCORE_PROP,
AC_TARPIT,
AC_RATELIMIT,
AC_NSUPDATE,
AC_EQSET,
AC_EQRSET,
AC_INCSET,
AC_INCRSET,
AC_DECSET,
AC_DECRSET,
AC_EQSETPROP,
AC_EQRSETPROP,
AC_INCSETPROP,
AC_INCRSETPROP,
AC_DECSETPROP,
AC_DECRSETPROP,
AC_LOG,
} acl_clause_t;
typedef union acl_data acl_data_t;
struct acl_clause;
struct acl_param;
#include "pending.h"
#include "milter-greylist.h"
#ifdef USE_NSUPDATE
#include "nsupdate.h"
#endif
#define ACL_WRLOCK WRLOCK(acl_lock)
#define ACL_RDLOCK RDLOCK(acl_lock)
#define ACL_UNLOCK UNLOCK(acl_lock)
TAILQ_HEAD(acllist, acl_entry);
enum operator { OP_EQ, OP_NE, OP_GT, OP_LT, OP_GE, OP_LE };
struct acl_opnum_data {
enum operator op;
int num;
};
struct acl_netblock_data {
struct sockaddr *addr;
ipaddr *mask;
socklen_t salen;
int cidr;
};
struct acl_param {
acl_type_t ap_type;
time_t ap_delay;
time_t ap_autowhite;
time_t ap_tarpit;
time_t ap_tarpitted;
tarpit_scope_t ap_tarpit_scope;
int ap_flags;
char *ap_id;
char *ap_code;
char *ap_ecode;
char *ap_msg;
char *ap_report;
char *ap_addheader;
int ap_addheader_index;
char *ap_addfooter;
char *ap_subjtag;
int ap_maxpeek;
int ap_nmatch;
char **ap_pmatch;
};
/* a_flags */
#define A_FLUSHADDR 0x001
#define A_FREE_CODE 0x002
#define A_FREE_ECODE 0x004
#define A_FREE_MSG 0x008
#define A_FREE_REPORT 0x010
#define A_FREE_ID 0x020
#define A_DROP_ACL 0x040
#define A_NOLOG 0x080
#define A_FREE_ADDHEADER 0x100
#define A_FREE_ADDFOOTER 0x200
#define A_FREE_SUBJTAG 0x400
struct all_list_entry;
union acl_data {
struct acl_netblock_data netblock;
char *string;
struct {
regex_t *re;
char *re_copy;
int nmatch;
} regex;
struct all_list_entry *list;
struct macro_entry *macro;
#ifdef USE_DNSRBL
struct dnsrbl_entry *dnsrbl;
#endif
#ifdef USE_MX
int mx_cidr;
#endif
#ifdef USE_CURL
struct urlcheck_entry *urlcheck;
#endif
#ifdef USE_LDAP
struct ldapcheck_entry *ldapcheck;
#endif
struct prop_data *prop;
struct acl_opnum_prop *aonp;
struct acl_prop_pop *apop;
struct acl_opnum_data opnum;
struct clockspec *clockspec;
#if (defined(HAVE_SPF) || defined(HAVE_SPF_ALT) || \
defined(HAVE_SPF2_10) || defined(HAVE_SPF2))
enum spf_status spf_status;
#endif
#ifdef USE_DKIM
enum spf_status dkim_status;
#endif
time_t time;
struct ratelimit_conf *ratelimit_conf;
#ifdef USE_NSUPDATE
struct nsupdate_entry *nsupdate;
#endif
};
struct acl_clause_rec {
acl_clause_t acr_type;
enum { UNIQUE, MULTIPLE_OK } acr_unicity;
acl_stage_t acr_stage;
char *acr_name;
acl_data_type_t acr_data_type;
acl_clause_t acr_list_type;
acl_clause_t acr_item_type;
long long acr_exf;
char *(*acr_print)(acl_data_t *, char *, size_t);
void (*acr_add)(acl_data_t *, void *data);
void (*acr_free)(acl_data_t *);
int (*acr_filter)(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
};
struct acl_clause {
acl_clause_t ac_type;
enum { PLAIN, NEGATED } ac_negation;
union acl_data ac_data;
struct acl_clause_rec *ac_acr;
TAILQ_ENTRY(acl_clause) ac_list;
};
#define a_addr a_netblock.nb_addr
#define a_addrlen a_netblock.nb_addrlen
#define a_mask a_netblock.nb_mask
struct acl_entry {
int a_line;
char *a_id;
acl_type_t a_type;
acl_stage_t a_stage;
TAILQ_HEAD(,acl_clause) a_clause;
time_t a_delay;
time_t a_autowhite;
time_t a_tarpit;
tarpit_scope_t a_tarpit_scope;
int a_flags;
char *a_code;
char *a_ecode;
char *a_msg;
char *a_report;
char *a_addheader;
int a_addheader_index;
char *a_addfooter;
char *a_subjtag;
int a_maxpeek;
TAILQ_ENTRY(acl_entry) a_list;
};
extern int testmode;
extern pthread_rwlock_t acl_lock;
char *stage_string(acl_stage_t);
struct acl_clause_rec *get_acl_clause_rec(acl_clause_t);
struct acl_clause_rec *acl_list_item_fixup(acl_clause_t, acl_clause_t);
void acl_init(void);
void acl_drop(void);
void acl_clear(void);
void acl_add_clause(acl_clause_t, void *);
void acl_negate_clause(void);
void acl_add_delay(time_t);
void acl_add_autowhite(time_t);
void acl_add_tarpit_scope(tarpit_scope_t);
void acl_add_flushaddr(void);
void acl_add_nolog(void);
void acl_add_id(char *);
void acl_add_code(char *);
void acl_add_ecode(char *);
void acl_add_msg(char *);
void acl_add_report(char *);
void acl_add_addheader(char *, int);
void acl_add_addfooter(char *);
void acl_add_subjtag(char *);
void acl_add_maxpeek(int);
void acl_maxpeek_fixup(int);
struct acl_entry *acl_register_entry_first(acl_stage_t, acl_type_t);
struct acl_entry *acl_register_entry_last(acl_stage_t, acl_type_t);
int acl_filter(acl_stage_t, SMFICTX *, struct mlfi_priv *);
char *acl_entry(char *, size_t, struct acl_entry *);
void acl_dump(void);
int emailcmp(char *, char *);
int acl_netblock_filter(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_list_filter(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_tarpit_filter(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_helo_strstr(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_helo_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_from_cmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_rawfrom_cmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_from_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_rawfrom_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_rcpt_cmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_rcpt_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_auth_strcmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_auth_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_tls_strcmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_tls_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_domain_cmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_domain_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_body_strstr(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_header_strstr(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_body_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_header_regexec(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_rcptcount_cmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_msgsize_cmp(acl_data_t *, acl_stage_t,
struct acl_param *, struct mlfi_priv *);
int acl_opnum_cmp(int, enum operator, int);
int myregexec(struct mlfi_priv *, acl_data_t *,
struct acl_param *, const char *);
int acl_modify_by_prop(char *, char *, struct acl_param *);
/* acl_filter() return codes */
#define EXF_UNSET 0
#define EXF_GREYLIST (1LL << 0)
#define EXF_WHITELIST (1LL << 1)
#define EXF_DEFAULT (1LL << 2)
#define EXF_ADDR (1LL << 3)
#define EXF_DOMAIN (1LL << 4)
#define EXF_FROM (1LL << 5)
#define EXF_RCPT (1LL << 6)
#define EXF_AUTO (1LL << 7)
#define EXF_NONE (1LL << 8)
#define EXF_AUTH (1LL << 9)
#define EXF_SPF (1LL << 10)
#define EXF_NONIP (1LL << 11)
#define EXF_STARTTLS (1LL << 12)
#define EXF_ACCESSDB (1LL << 13)
#define EXF_DRAC (1LL << 14)
#define EXF_DNSRBL (1LL << 15)
#define EXF_BLACKLIST (1LL << 16)
#define EXF_MACRO (1LL << 17)
#define EXF_URLCHECK (1LL << 18)
#define EXF_HEADER (1LL << 19)
#define EXF_BODY (1LL << 20)
#define EXF_MSGSIZE (1LL << 21)
#define EXF_RCPTCOUNT (1LL << 22)
#define EXF_CLOCKSPEC (1LL << 23)
#define EXF_GEOIP (1LL << 24)
#define EXF_PROP (1LL << 25)
#define EXF_HELO (1LL << 26)
#define EXF_LDAPCHECK (1LL << 27)
#define EXF_NOLOG (1LL << 28)
#define EXF_P0F (1LL << 29)
#define EXF_SA (1LL << 30)
#define EXF_TARPIT (1LL << 31)
#define EXF_MX (1LL << 32) /* Need long long (64b) */
#define EXF_DKIM (1LL << 33)
#endif /* _ACL_H_ */
|