]>
Commit | Line | Data |
---|---|---|
949c99f8 JR |
1 | Based on patch by: James F. Hranicky (jfhcise.ufl.edu) |
2 | ||
3 | diff -urN -x '*~' -x '*.orig' postfix-2.2.5/src/global/mail_params.h postfix-2.2.5-ident/src/global/mail_params.h | |
4 | --- postfix-2.2.5/src/global/mail_params.h 2006-02-15 23:44:13.000000000 +0100 | |
5 | +++ postfix-2.2.5-ident/src/global/mail_params.h 2006-02-15 23:30:50.000000000 +0100 | |
6 | @@ -2346,6 +2346,9 @@ | |
7 | #define DEF_SMTP_EHLO_DIS_MAPS "" | |
8 | extern char *var_smtp_ehlo_dis_maps; | |
9 | ||
10 | +#define VAR_SMTPD_IDENT_LOOKUP "smtpd_ident_lookup" | |
11 | +#define DEF_SMTPD_IDENT_LOOKUP 0 | |
12 | +extern bool var_smtpd_ident_lookup; | |
13 | /* | |
14 | * SMTPD messages | |
15 | */ | |
16 | Files postfix-2.2.5/src/smtpd/.smtpd_peer.c.swp and postfix-2.2.5-ident/src/smtpd/.smtpd_peer.c.swp differ | |
17 | diff -urN -x '*~' -x '*.orig' postfix-2.2.5/src/smtpd/Makefile.in postfix-2.2.5-ident/src/smtpd/Makefile.in | |
18 | --- postfix-2.2.5/src/smtpd/Makefile.in 2005-04-29 23:12:28.000000000 +0200 | |
19 | +++ postfix-2.2.5-ident/src/smtpd/Makefile.in 2006-02-15 22:09:42.000000000 +0100 | |
20 | @@ -1,10 +1,10 @@ | |
21 | SHELL = /bin/sh | |
22 | SRCS = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \ | |
23 | smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \ | |
24 | - smtpd_xforward.c | |
25 | + smtpd_xforward.c smtpd_ident.c | |
26 | OBJS = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \ | |
27 | smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \ | |
28 | - smtpd_xforward.o | |
29 | + smtpd_xforward.o smtpd_ident.o | |
30 | HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \ | |
31 | smtpd_sasl_glue.h smtpd_proxy.h | |
32 | TESTSRC = smtpd_token_test.c | |
33 | diff -urN -x '*~' -x '*.orig' postfix-2.2.5/src/smtpd/smtpd.c postfix-2.2.5-ident/src/smtpd/smtpd.c | |
34 | --- postfix-2.2.5/src/smtpd/smtpd.c 2006-02-15 23:44:13.000000000 +0100 | |
35 | +++ postfix-2.2.5-ident/src/smtpd/smtpd.c 2006-02-15 22:31:33.000000000 +0100 | |
36 | @@ -900,6 +900,7 @@ | |
37 | char *var_local_rwr_clients; | |
38 | char *var_smtpd_ehlo_dis_words; | |
39 | char *var_smtpd_ehlo_dis_maps; | |
40 | +bool var_smtpd_ident_lookup; | |
41 | ||
42 | bool var_smtpd_use_tls; | |
43 | bool var_smtpd_enforce_tls; | |
44 | @@ -1951,10 +1952,18 @@ | |
45 | * intermediate proxy. | |
46 | */ | |
47 | if (!state->proxy || state->xforward.flags == 0) { | |
48 | - out_fprintf(out_stream, REC_TYPE_NORM, | |
49 | - "Received: from %s (%s [%s])", | |
50 | - state->helo_name ? state->helo_name : state->name, | |
51 | - state->name, state->rfc_addr); | |
52 | + if (var_smtpd_ident_lookup) { | |
53 | + out_fprintf(out_stream, REC_TYPE_NORM, | |
54 | + "Received: from %s (%s [%s] ident=%s)", | |
55 | + state->helo_name ? state->helo_name : state->name, | |
56 | + state->name, state->rfc_addr, | |
57 | + state->ident_user); | |
58 | + } else { | |
59 | + out_fprintf(out_stream, REC_TYPE_NORM, | |
60 | + "Received: from %s (%s [%s])", | |
61 | + state->helo_name ? state->helo_name : state->name, | |
62 | + state->name, state->rfc_addr); | |
63 | + } | |
64 | #ifdef USE_TLS | |
65 | if (var_smtpd_tls_received_header && state->tls_context) { | |
66 | out_fprintf(out_stream, REC_TYPE_NORM, | |
67 | @@ -3375,6 +3384,7 @@ | |
68 | VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls, | |
69 | VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls, | |
70 | VAR_SMTPD_TLS_WRAPPER, DEF_SMTPD_TLS_WRAPPER, &var_smtpd_tls_wrappermode, | |
71 | + VAR_SMTPD_IDENT_LOOKUP, DEF_SMTPD_IDENT_LOOKUP, &var_smtpd_ident_lookup, | |
72 | #ifdef USE_TLS | |
73 | VAR_SMTPD_TLS_AUTH_ONLY, DEF_SMTPD_TLS_AUTH_ONLY, &var_smtpd_tls_auth_only, | |
74 | VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert, | |
75 | diff -urN -x '*~' -x '*.orig' postfix-2.2.5/src/smtpd/smtpd.h postfix-2.2.5-ident/src/smtpd/smtpd.h | |
76 | --- postfix-2.2.5/src/smtpd/smtpd.h 2005-01-30 22:45:31.000000000 +0100 | |
77 | +++ postfix-2.2.5-ident/src/smtpd/smtpd.h 2006-02-15 21:11:46.000000000 +0100 | |
78 | @@ -75,6 +75,7 @@ | |
79 | char *addr; /* client host address string */ | |
80 | char *namaddr; /* combined name and address */ | |
81 | char *rfc_addr; /* address for RFC 2821 */ | |
82 | + char *ident_user; /* user name returned by ident RFC 1413 */ | |
83 | struct sockaddr_storage sockaddr; /* binary client endpoint */ | |
84 | int peer_code; /* 2=ok, 4=soft, 5=hard */ | |
85 | int error_count; /* reset after DOT */ | |
86 | @@ -232,6 +233,8 @@ | |
87 | extern void smtpd_peer_init(SMTPD_STATE *state); | |
88 | extern void smtpd_peer_reset(SMTPD_STATE *state); | |
89 | ||
90 | +extern char *smtpd_ident(struct sockaddr_in *peer_addr, struct sockaddr_in *smtpd_addr); | |
91 | + | |
92 | #define SMTPD_PEER_CODE_OK 2 | |
93 | #define SMTPD_PEER_CODE_TEMP 4 | |
94 | #define SMTPD_PEER_CODE_PERM 5 | |
95 | diff -urN -x '*~' -x '*.orig' postfix-2.2.5/src/smtpd/smtpd_ident.c postfix-2.2.5-ident/src/smtpd/smtpd_ident.c | |
96 | --- postfix-2.2.5/src/smtpd/smtpd_ident.c 1970-01-01 01:00:00.000000000 +0100 | |
97 | +++ postfix-2.2.5-ident/src/smtpd/smtpd_ident.c 2006-02-15 23:44:04.000000000 +0100 | |
98 | @@ -0,0 +1,138 @@ | |
99 | +#include <sys_defs.h> | |
100 | +#include <sys/socket.h> | |
101 | +#include <netinet/in.h> | |
102 | +#include <arpa/inet.h> | |
103 | +#include <stdio.h> /* strerror() */ | |
104 | +#include <errno.h> | |
105 | +#include <string.h> | |
106 | +#include <mymalloc.h> | |
107 | +#include <sys/types.h> | |
108 | +#include <sys/time.h> | |
109 | +#include <unistd.h> | |
110 | +#include <vstream.h> | |
111 | + | |
112 | +#include <iostuff.h> | |
113 | +#include "smtpd.h" | |
114 | + | |
115 | +#define IDENT_MSGSIZE 256 | |
116 | +#define IDENT_TIMEOUT 10 | |
117 | + | |
118 | +#define CHOMP(STR) { char *tmp; tmp = STR; while (*tmp) { \ | |
119 | + if (*tmp == '\n' || *tmp == '\r') *tmp = '\0'; tmp++ ; } } | |
120 | + | |
121 | +char *smtpd_ident(struct sockaddr_in *peer_addr, struct sockaddr_in *smtpd_addr) | |
122 | +{ | |
123 | + int ident_sock; | |
124 | + char ident_msg[IDENT_MSGSIZE + 1], *sp; | |
125 | + char ident_user[IDENT_MSGSIZE + 1]; | |
126 | + struct sockaddr_in local_addr; | |
127 | + struct sockaddr_in ident_addr; | |
128 | + char *return_val; | |
129 | + VSTREAM *ident_stream; | |
130 | + | |
131 | + memset(ident_msg, 0, IDENT_MSGSIZE + 1); | |
132 | + memset(ident_user, 0, IDENT_MSGSIZE + 1); | |
133 | + | |
134 | + /* | |
135 | + * Bind the local sockaddr to the same interface as smtpd before | |
136 | + * connecting back to the auth port on the peer. This helps | |
137 | + * with multihomed postfix servers. First, set up the address. | |
138 | + */ | |
139 | + | |
140 | + /* Local sockname */ | |
141 | + | |
142 | + memset((char *) &local_addr, 0, sizeof(local_addr)); | |
143 | + local_addr.sin_family = AF_INET; | |
144 | + memcpy((void *) &local_addr.sin_addr, (void *) &smtpd_addr->sin_addr, sizeof(local_addr.sin_addr)); | |
145 | + | |
146 | + /* Remote sockname + port */ | |
147 | + | |
148 | + memset((char *) &ident_addr, 0, sizeof(ident_addr)); | |
149 | + ident_addr.sin_family = AF_INET; | |
150 | + memcpy((void *) &ident_addr.sin_addr, (void *) &peer_addr->sin_addr, sizeof(ident_addr.sin_addr)); | |
151 | + ident_addr.sin_port = htons(113); | |
152 | + | |
153 | + do { | |
154 | + /* socket call */ | |
155 | + | |
156 | + if ((ident_sock = socket(ident_addr.sin_family, SOCK_STREAM, 0)) < 0) { | |
157 | + msg_warn("Can't allocate socket for ident lookup: %s", strerror(errno)); | |
158 | + break; | |
159 | + } | |
160 | + | |
161 | + /* Now bind the local sock to the interface */ | |
162 | + | |
163 | + if (bind(ident_sock, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { | |
164 | + msg_warn("local bind of ident sock failed: %s", strerror(errno)); | |
165 | + break; | |
166 | + } | |
167 | + | |
168 | + /* connect() back to the smtp client host on port 113 */ | |
169 | + | |
170 | + if (connect(ident_sock, (struct sockaddr *) &ident_addr, sizeof(ident_addr )) < 0) { | |
171 | + msg_warn( "ident connect to %s: %s", inet_ntoa(peer_addr->sin_addr), | |
172 | + strerror(errno)); | |
173 | + break; | |
174 | + } | |
175 | + | |
176 | + /* Ok, make this a vstream */ | |
177 | + | |
178 | + ident_stream = vstream_fdopen(ident_sock, O_RDWR); | |
179 | + ident_stream->timeout = IDENT_TIMEOUT; | |
180 | + | |
181 | + /* Print the ident message to the remote host */ | |
182 | + | |
183 | + vstream_fprintf(ident_stream, "%d, %d\n", ntohs(peer_addr->sin_port), ntohs(smtpd_addr->sin_port)); | |
184 | + if (vstream_ftimeout(ident_stream)) { | |
185 | + msg_warn( "ident write timed out to %s", inet_ntoa(peer_addr->sin_addr)); | |
186 | + break; | |
187 | + } | |
188 | + | |
189 | + /* Read back the result */ | |
190 | + | |
191 | + vstream_fread(ident_stream, ident_msg, IDENT_MSGSIZE); | |
192 | + if (vstream_ftimeout(ident_stream)) { | |
193 | + msg_warn( "ident read timed out to %s", inet_ntoa(peer_addr->sin_addr)); | |
194 | + break; | |
195 | + } | |
196 | + | |
197 | + /* | |
198 | + * Should I even bother with this? | |
199 | + * | |
200 | + * Even if so, don't worry about this failing, set the timeout low | |
201 | + */ | |
202 | + | |
203 | + ident_stream->timeout = 2; | |
204 | + vstream_fwrite(ident_stream, "quit\n", strlen("quit\n")); | |
205 | + | |
206 | + if (strlen(ident_msg) == 0) { | |
207 | + msg_warn( "Failed to get ident string from %s", inet_ntoa(peer_addr->sin_addr)); | |
208 | + break; | |
209 | + } | |
210 | + | |
211 | + if ((sp = strrchr(ident_msg, ':')) == NULL) { | |
212 | + msg_warn( "Invalid ident string from %s", inet_ntoa(peer_addr->sin_addr)); | |
213 | + break; | |
214 | + } | |
215 | + sp++; | |
216 | + CHOMP(sp); | |
217 | + while (*sp && (*sp == ' ' || *sp == '\t')) { | |
218 | + sp++; | |
219 | + } | |
220 | + | |
221 | + /* If we break before this line, we know we had some sort of bad error */ | |
222 | + | |
223 | + strncpy(ident_user, sp, IDENT_MSGSIZE); | |
224 | + msg_info( "Received ident string %s from %s", sp, inet_ntoa(peer_addr->sin_addr)); | |
225 | + | |
226 | + } while (0); | |
227 | + | |
228 | + if (strlen(ident_user) == 0) { | |
229 | + msg_warn( "Failed to get ident user for %s", inet_ntoa(peer_addr->sin_addr)); | |
230 | + return NULL; | |
231 | + } | |
232 | + | |
233 | + vstream_fclose(ident_stream); | |
234 | + return_val = mystrdup(ident_user); | |
235 | + return return_val; | |
236 | +} | |
237 | diff -urN -x '*~' -x '*.orig' postfix-2.2.5/src/smtpd/smtpd_peer.c postfix-2.2.5-ident/src/smtpd/smtpd_peer.c | |
238 | --- postfix-2.2.5/src/smtpd/smtpd_peer.c 2005-01-30 22:42:18.000000000 +0100 | |
239 | +++ postfix-2.2.5-ident/src/smtpd/smtpd_peer.c 2006-02-15 23:29:08.000000000 +0100 | |
240 | @@ -56,6 +56,7 @@ | |
241 | ||
242 | #include <sys_defs.h> | |
243 | #include <sys/socket.h> | |
244 | +#include <sys/types.h> | |
245 | #include <netinet/in.h> | |
246 | #include <arpa/inet.h> | |
247 | #include <stdio.h> /* strerror() */ | |
248 | @@ -75,6 +76,7 @@ | |
249 | /* Global library. */ | |
250 | ||
251 | #include <mail_proto.h> | |
252 | +#include <mail_params.h> | |
253 | #include <valid_mailhost_addr.h> | |
254 | ||
255 | /* Application-specific. */ | |
256 | @@ -88,6 +90,8 @@ | |
257 | char *myname = "smtpd_peer_init"; | |
258 | SOCKADDR_SIZE sa_len; | |
259 | struct sockaddr *sa; | |
260 | + struct sockaddr_in serv_sin; | |
261 | + char *ident_user = NULL; | |
262 | INET_PROTO_INFO *proto_info = inet_proto_info(); | |
263 | ||
264 | sa = (struct sockaddr *) & (state->sockaddr); | |
265 | @@ -108,6 +112,9 @@ | |
266 | state->addr = mystrdup(CLIENT_ADDR_UNKNOWN); | |
267 | state->rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN); | |
268 | state->peer_code = SMTPD_PEER_CODE_PERM; | |
269 | + if (var_smtpd_ident_lookup) { | |
270 | + state->ident_user = mystrdup("NO-USER"); | |
271 | + } | |
272 | } | |
273 | ||
274 | /* | |
275 | @@ -218,6 +225,9 @@ | |
276 | if (aierr) { | |
277 | msg_warn("%s: hostname %s verification failed: %s", | |
278 | state->addr, state->name, MAI_STRERROR(aierr)); | |
279 | + if (var_smtpd_ident_lookup) { | |
280 | + state->ident_user = mystrdup("NO-USER"); | |
281 | + } | |
282 | REJECT_PEER_NAME(state, (TEMP_AI_ERROR(aierr) ? | |
283 | SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM)); | |
284 | } else { | |
285 | @@ -239,6 +249,19 @@ | |
286 | freeaddrinfo(res0); | |
287 | } | |
288 | } | |
289 | + | |
290 | + if (var_smtpd_ident_lookup) { | |
291 | + /* If getsockname fails, just forget it */ | |
292 | + sa_len = sizeof(serv_sin); | |
293 | + if (getsockname(vstream_fileno(state->client), (struct sockaddr *)&serv_sin, &sa_len) >= 0) { | |
294 | + ident_user = smtpd_ident((struct sockaddr_in *)sa, &serv_sin); | |
295 | + if (ident_user == NULL) | |
296 | + state->ident_user = mystrdup("NO-USER"); | |
297 | + else | |
298 | + state->ident_user = ident_user; | |
299 | + } else | |
300 | + msg_warn("getsockname failed while doing ident lookup: %s", strerror(errno)); | |
301 | + } | |
302 | } | |
303 | ||
304 | /* | |
305 | @@ -250,6 +273,9 @@ | |
306 | state->addr = mystrdup("127.0.0.1"); /* XXX bogus. */ | |
307 | state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */ | |
308 | state->peer_code = SMTPD_PEER_CODE_OK; | |
309 | + if (var_smtpd_ident_lookup) { | |
310 | + state->ident_user = mystrdup("NO-USER"); | |
311 | + } | |
312 | } | |
313 | ||
314 | /* | |
315 | @@ -267,4 +293,7 @@ | |
316 | myfree(state->addr); | |
317 | myfree(state->namaddr); | |
318 | myfree(state->rfc_addr); | |
319 | + if (var_smtpd_ident_lookup) { | |
320 | + myfree(state->ident_user); | |
321 | + } | |
322 | } |