115 #include <sys/socket.h>
116 #include <netinet/in.h>
117 #include <arpa/inet.h>
159 static int smtpd_peer_sockaddr_to_hostaddr(
SMTPD_STATE *state)
161 const char *myname =
"smtpd_peer_sockaddr_to_hostaddr";
162 struct sockaddr *sa = (
struct sockaddr *) &(state->
sockaddr);
171 if (sa->sa_family == AF_INET
173 || sa->sa_family == AF_INET6
186 if (strchr((
char *) proto_info->
sa_family_list, sa->sa_family) == 0)
187 msg_fatal(
"cannot handle socket type %s with \"%s = %s\"",
189 sa->sa_family == AF_INET6 ?
"AF_INET6" :
191 sa->sa_family == AF_INET ?
"AF_INET" :
199 msg_error(
"incorrect SMTP server privileges: uid=%lu euid=%lu",
200 (
unsigned long) getuid(), (
unsigned long) geteuid());
201 msg_fatal(
"the Postfix SMTP server must run with $%s privileges",
209 &client_port, 0)) != 0)
210 msg_fatal(
"%s: cannot convert client address/port to string: %s",
219 if (strchr(client_addr.
buf,
'%') != 0)
220 msg_panic(
"%s: address %s has datalink suffix",
221 myname, client_addr.
buf);
231 if (sa->sa_family == AF_INET6) {
233 && IN6_IS_ADDR_V4MAPPED(&SOCK_ADDR_IN6_ADDR(sa))
234 && (colonp = strrchr(client_addr.
buf,
':')) != 0) {
235 struct addrinfo *res0;
238 msg_info(
"%s: rewriting V4-mapped address \"%s\" to \"%s\"",
239 myname, client_addr.
buf, colonp + 1);
246 msg_fatal(
"%s: cannot convert %s from string to binary: %s",
248 sa_length = res0->ai_addrlen;
249 if (sa_length >
sizeof(state->
sockaddr))
250 sa_length =
sizeof(state->
sockaddr);
251 memcpy((
void *) sa, res0->ai_addr, sa_length);
289 &server_port, 0)) != 0)
290 msg_fatal(
"%s: cannot convert server address/port to string: %s",
309 static void smtpd_peer_sockaddr_to_hostname(
SMTPD_STATE *state)
311 struct sockaddr *sa = (
struct sockaddr *) &(state->
sockaddr);
325 #define TEMP_AI_ERROR(e) \
326 ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
328 #define REJECT_PEER_NAME(state, code) { \
329 myfree(state->name); \
330 state->name = mystrdup(CLIENT_NAME_UNKNOWN); \
331 state->name_status = code; \
348 struct addrinfo *res0;
349 struct addrinfo *res;
363 (
char *) 0, 0, &res0);
365 msg_warn(
"hostname %s does not resolve to address %s: %s",
370 for (res = res0; ; res = res->ai_next) {
372 msg_warn(
"hostname %s does not resolve to address %s",
377 if (strchr((
char *) proto_info->
sa_family_list, res->ai_family) == 0) {
378 msg_info(
"skipping address family %d for host %s",
379 res->ai_family, state->
name);
392 static void smtpd_peer_hostaddr_to_sockaddr(
SMTPD_STATE *state)
394 const char *myname =
"smtpd_peer_hostaddr_to_sockaddr";
395 struct addrinfo *res;
399 SOCK_STREAM, &res)) != 0)
400 msg_fatal(
"%s: cannot convert client address/port to string: %s",
402 if (res->ai_addrlen >
sizeof(state->
sockaddr))
403 msg_panic(
"%s: address length > struct sockaddr_storage", myname);
404 memcpy((
void *) &(state->
sockaddr), res->ai_addr, res->ai_addrlen);
411 static void smtpd_peer_not_inet(
SMTPD_STATE *state)
441 static void smtpd_peer_no_client(
SMTPD_STATE *state)
459 static void smtpd_peer_from_pass_attr(
SMTPD_STATE *state)
468 msg_fatal(
"missing client address from proxy");
469 if (strrchr(cp,
':') != 0) {
471 msg_fatal(
"bad IPv6 client address syntax from proxy: %s", cp);
477 msg_fatal(
"bad IPv4 client address syntax from proxy: %s", cp);
483 msg_fatal(
"missing client port from proxy");
485 msg_fatal(
"bad TCP client port number syntax from proxy: %s", cp);
492 msg_fatal(
"missing server address from proxy");
494 msg_fatal(
"bad IPv6 server address syntax from proxy: %s", cp);
498 msg_fatal(
"missing server port from proxy");
500 msg_fatal(
"bad TCP server port number syntax from proxy: %s", cp);
506 smtpd_peer_hostaddr_to_sockaddr(state);
511 static void smtpd_peer_from_default(
SMTPD_STATE *state)
523 (
struct sockaddr *) &state->
sockaddr,
528 if (errno == ENOTSOCK)
529 smtpd_peer_not_inet(state);
531 smtpd_peer_no_client(state);
533 if (smtpd_peer_sockaddr_to_hostaddr(state) < 0)
534 smtpd_peer_not_inet(state);
540 static void smtpd_peer_from_proxy(
SMTPD_STATE *state)
545 } SMTPD_ENDPT_LOOKUP_INFO;
546 static const SMTPD_ENDPT_LOOKUP_INFO smtpd_endpt_lookup_info[] = {
550 const SMTPD_ENDPT_LOOKUP_INFO *pp;
556 for (pp = smtpd_endpt_lookup_info; ; pp++) {
563 if (pp->endpt_lookup(state) < 0) {
564 smtpd_peer_no_client(state);
567 smtpd_peer_hostaddr_to_sockaddr(state);
604 smtpd_peer_from_pass_attr(state);
606 msg_warn(
"ignoring non-empty %s setting behind postscreen",
609 smtpd_peer_from_default(state);
611 smtpd_peer_from_proxy(state);
619 if (state->
name == 0)
620 smtpd_peer_sockaddr_to_hostname(state);
int valid_hostaddr(const char *addr, int gripe)
void msg_error(const char *fmt,...)
#define SMTPD_STAND_ALONE(state)
int valid_ipv6_hostaddr(const char *addr, int gripe)
void smtpd_peer_init(SMTPD_STATE *state)
void freeaddrinfo(struct addrinfo *ai)
#define SMTPD_PEER_CODE_PERM
char * mystrdup(const char *str)
int sock_addr_cmp_addr(const struct sockaddr *sa, const struct sockaddr *sb)
NORETURN msg_panic(const char *fmt,...)
#define HAPROXY_PROTO_NAME
#define REJECT_PEER_NAME(state, code)
#define inet_proto_info()
#define SMTPD_PEER_CODE_FORGED
bool var_smtpd_peername_lookup
int valid_hostport(const char *str, int gripe)
#define MAIL_ATTR_ACT_CLIENT_ADDR
#define MAIL_ATTR_ACT_SERVER_ADDR
#define SMTPD_BUILD_NAMADDRPORT(name, addr, port)
#define SERVER_PORT_UNKNOWN
int valid_ipv4_hostaddr(const char *addr, int gripe)
int hostaddr_to_sockaddr(const char *hostaddr, const char *service, int socktype, struct addrinfo **res)
#define vstream_context(vp)
#define SERVER_ADDR_UNKNOWN
int sockaddr_to_hostaddr(const struct sockaddr *sa, SOCKADDR_SIZE salen, MAI_HOSTADDR_STR *hostaddr, MAI_SERVPORT_STR *portnum, int unused_socktype)
char buf[MAI_HOSTADDR_STRSIZE]
#define MAIL_ATTR_ACT_CLIENT_PORT
int hostname_to_sockaddr_pf(const char *hostname, int pf, const char *service, int socktype, struct addrinfo **res)
void msg_warn(const char *fmt,...)
SOCKADDR_SIZE dest_sockaddr_len
unsigned char * sa_family_list
void * htable_find(HTABLE *table, const char *key)
#define VAR_INET_PROTOCOLS
#define MAIL_ATTR_ACT_SERVER_PORT
NORETURN msg_fatal(const char *fmt,...)
#define CLIENT_NAME_UNKNOWN
char * concatenate(const char *arg0,...)
char buf[MAI_HOSTNAME_STRSIZE]
SOCKADDR_SIZE sockaddr_len
#define CLIENT_ADDR_UNKNOWN
#define vstream_fileno(vp)
void smtpd_peer_reset(SMTPD_STATE *state)
char * var_inet_protocols
#define VAR_SMTPD_UPROXY_PROTO
int smtpd_peer_from_haproxy(SMTPD_STATE *state)
char buf[MAI_SERVPORT_STRSIZE]
#define SMTPD_PEER_CODE_TEMP
#define CLIENT_PORT_UNKNOWN
struct sockaddr_storage dest_sockaddr
int sockaddr_to_hostname(const struct sockaddr *sa, SOCKADDR_SIZE salen, MAI_HOSTNAME_STR *hostname, MAI_SERVNAME_STR *service, int socktype)
char * var_smtpd_uproxy_proto
struct sockaddr_storage sockaddr
#define SMTPD_PEER_CODE_OK
void msg_info(const char *fmt,...)
#define SMTPD_FLAG_HANGUP