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
|
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)
|