Index: include/conf.h =================================================================== --- a/include/conf.h (revision 519) +++ b/include/conf.h (working copy) @@ -41,6 +41,7 @@ "stat_type", "status", \ "grey_mask", "24", \ "grey_delay", "10", \ + "grey_tuple", "user", \ "syslog_facility", "mail", \ "blocker_port", "4466", \ "blocker_weight", "1", \ @@ -80,6 +81,7 @@ "log_level", \ "grey_mask", \ "grey_delay", \ + "grey_tuple", \ "check", \ "protocol", \ "syslog_facility", \ Index: include/common.h =================================================================== --- a/include/common.h (revision 519) +++ b/include/common.h (working copy) @@ -151,6 +151,12 @@ # endif /* bool */ #endif /* HAVE_BOOL */ +typedef enum +{ + GREY_TUPLE_USER = 0, + GREY_TUPLE_SERVER, +} greytupletype_t; + typedef struct peer_s { struct sockaddr_in peer_addr; @@ -207,6 +213,7 @@ int grey_mask; int protocols; int greylist_delay; + greytupletype_t grey_tuple; postfix_config_t postfix; sjsms_config_t sjsms; blocker_config_t blocker; Index: src/gross.c =================================================================== --- a/src/gross.c (revision 519) +++ b/src/gross.c (working copy) @@ -112,7 +112,7 @@ { int ret; configlist_t *cp; - const char *updatestr; + const char *updatestr, *greytuplestr; struct hostent *host = NULL; char buffer[MAXLINELEN] = { '\0' }; params_t *pp; @@ -214,6 +214,17 @@ daemon_shutdown(EXIT_CONFIG, "Invalid updatestyle: %s", updatestr); } + greytuplestr = CONF("grey_tuple"); + if ((greytuplestr == NULL) || (strcmp(greytuplestr, "user") == 0)) { + logstr(GLOG_DEBUG, "grey_tuple: USER"); + ctx->config.grey_tuple = GREY_TUPLE_USER; + } else if (strcmp(greytuplestr, "server") == 0) { + logstr(GLOG_DEBUG, "grey_tuple: SERVER"); + ctx->config.grey_tuple = GREY_TUPLE_SERVER; + } else { + daemon_shutdown(EXIT_CONFIG, "Invalid grey_tuple: %s", greytuplestr); + } + /* we must reset errno because strtol returns 0 if it fails */ errno = 0; ctx->config.grey_mask = strtol(CONF("grey_mask"), (char **)NULL, 10); Index: src/worker.c =================================================================== --- a/src/worker.c (revision 519) +++ b/src/worker.c (working copy) @@ -186,6 +186,14 @@ } } +static const char *domain_part(const char *email) +{ + char *p = strchr(email, '@'); + if (p == NULL) + return email; + return p + 1; +} + int test_tuple(final_status_t *final, grey_tuple_t *request, tmout_action_t *ta) { @@ -233,7 +241,14 @@ } /* greylist */ - snprintf(maskedtuple, MSGSZ, "%s %s %s", chkipstr, request->sender, request->recipient); + switch (ctx->config.grey_tuple) { + case GREY_TUPLE_USER: + snprintf(maskedtuple, MSGSZ, "%s %s %s", chkipstr, request->sender, request->recipient); + break; + case GREY_TUPLE_SERVER: + snprintf(maskedtuple, MSGSZ, "%s %s %s", chkipstr, domain_part(request->sender), request->helo_name); + break; + } digest = sha256_string(maskedtuple); querylog_entry = &final->querylog_entry; Index: doc/examples/grossd.conf =================================================================== --- a/doc/examples/grossd.conf (revision 519) +++ b/doc/examples/grossd.conf (working copy) @@ -93,6 +93,13 @@ # only if response is STATUS_GREY # DEFAULT: update = grey +# 'grey_tuple' is the way greylisting tuples are created. Valid options are +# 'normal' and 'loose'. If 'grey_tuple = user' the tuple for grey listing +# will be: masked client-ip, sender email, recipient email. If 'grey_tuple = +# server' the tuple for greylisting will be client-ip, domain of sender email +# and helo. +# DEFAULT: grey_tuple = normal + # 'grey_mask' is the mask for grossd to use when matching client_ip # against the database. Default is 24, so grossd treats addresses # like a.b.c.d as a.b.c.0. Setting this to 32 makes grossd to Index: man/grossd.conf.5.in =================================================================== --- a/man/grossd.conf.5.in (revision 519) +++ b/man/grossd.conf.5.in (working copy) @@ -66,6 +66,12 @@ \fIgrossd\fP\|(8) will update the database only if the response is `\s-1STATUS_GREY\s+1'. Setting it to `always' may reduce the impact on \s-1DNS\s+1 servers. +.IP "\fBgrey_tuple\fP" 4 +is the greylisting tuple. Valid options are `user' and `server'. If set to +`user', which is the default, \fIgrossd\fP\|(8) will create the tuple from +the masked `smtp\-client\-ip', sender email and recipient email. If set to +`server' it will create the tuple from the masked `smtp\-client\-ip', the sender +email domain and helo message. .IP "\fBgrey_mask\fP" 4 is the mask for \fIgrossd\fP\|(8) to use when matching the `smtp\-client\-ip' against the database. Default is 24, which makes \fIgrossd\fP\|(8)