1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* Copyright (c) The Exim Maintainers 2020 */
7 /* See the file NOTICE for conditions of use and distribution. */
8
9
10 #include "../exim.h"
11 #include "rf_functions.h"
12 #include "ipliteral.h"
13
14
15 /* Options specific to the ipliteral router. Because some compilers do not like
16 empty declarations ("undefined" in the Standard) we put in a dummy value. */
17
18 optionlist ipliteral_router_options[] = {
19 { "", opt_hidden, {NULL} }
20 };
21
22 /* Size of the options list. An extern variable has to be used so that its
23 address can appear in the tables drtables.c. */
24
25 int ipliteral_router_options_count =
26 sizeof(ipliteral_router_options)/sizeof(optionlist);
27
28 /* Default private options block for the ipliteral router. Again, a dummy
29 value is present to keep some compilers happy. */
30
31 ipliteral_router_options_block ipliteral_router_option_defaults = { 0 };
32
33
34 #ifdef MACRO_PREDEF
35
36 /* Dummy entries */
ipliteral_router_init(router_instance * rblock)37 void ipliteral_router_init(router_instance *rblock) {}
ipliteral_router_entry(router_instance * rblock,address_item * addr,struct passwd * pw,int verify,address_item ** addr_local,address_item ** addr_remote,address_item ** addr_new,address_item ** addr_succeed)38 int ipliteral_router_entry(router_instance *rblock, address_item *addr,
39 struct passwd *pw, int verify, address_item **addr_local,
40 address_item **addr_remote, address_item **addr_new,
41 address_item **addr_succeed) {return 0;}
42
43 #else /*!MACRO_PREDEF*/
44
45
46 /*************************************************
47 * Initialization entry point *
48 *************************************************/
49
50 /* Called for each instance, after its options have been read, to enable
51 consistency checks to be done, or anything else that needs to be set up. */
52
53 void
ipliteral_router_init(router_instance * rblock)54 ipliteral_router_init(router_instance *rblock)
55 {
56 /*
57 ipliteral_router_options_block *ob =
58 (ipliteral_router_options_block *)(rblock->options_block);
59 */
60 }
61
62
63
64 /*************************************************
65 * Main entry point *
66 *************************************************/
67
68 /* See local README for interface details. This router returns:
69
70 DECLINE
71 . the domain is not in the form of an IP literal
72
73 DEFER
74 . verifying the errors address caused a deferment or a big disaster such
75 as an expansion failure (rf_get_errors_address)
76 . expanding a headers_{add,remove} string caused a deferment or another
77 expansion error (rf_get_munge_headers)
78 . a problem in rf_get_transport: no transport when one is needed;
79 failed to expand dynamic transport; failed to find dynamic transport
80 . failure to expand or find a uid/gid (rf_get_ugid via rf_queue_add)
81 . self = "freeze", self = "defer"
82
83 PASS
84 . self = "pass"
85
86 REROUTED
87 . self = "reroute"
88
89 FAIL
90 . self = "fail"
91
92 OK
93 added address to addr_local or addr_remote, as appropriate for the
94 type of transport; this includes the self="send" case.
95 */
96
97 int
ipliteral_router_entry(router_instance * rblock,address_item * addr,struct passwd * pw,int verify,address_item ** addr_local,address_item ** addr_remote,address_item ** addr_new,address_item ** addr_succeed)98 ipliteral_router_entry(
99 router_instance *rblock, /* data for this instantiation */
100 address_item *addr, /* address we are working on */
101 struct passwd *pw, /* passwd entry after check_local_user */
102 int verify, /* v_none/v_recipient/v_sender/v_expn */
103 address_item **addr_local, /* add it to this if it's local */
104 address_item **addr_remote, /* add it to this if it's remote */
105 address_item **addr_new, /* put new addresses on here */
106 address_item **addr_succeed) /* put old address here on success */
107 {
108 /*
109 ipliteral_router_options_block *ob =
110 (ipliteral_router_options_block *)(rblock->options_block);
111 */
112 host_item *h;
113 const uschar *domain = addr->domain;
114 const uschar *ip;
115 int len = Ustrlen(domain);
116 int rc, ipv;
117
118 DEBUG(D_route) debug_printf("%s router called for %s: domain = %s\n",
119 rblock->name, addr->address, addr->domain);
120
121 /* Check that the domain is an IP address enclosed in square brackets. Remember
122 to allow for the "official" form of IPv6 addresses. If not, the router
123 declines. Otherwise route to the single IP address, setting the host name to
124 "(unnamed)". */
125
126 if (domain[0] != '[' || domain[len-1] != ']') return DECLINE;
127 ip = string_copyn(domain+1, len-2);
128 if (strncmpic(ip, US"IPV6:", 5) == 0 || strncmpic(ip, US"IPV4:", 5) == 0)
129 ip += 5;
130
131 ipv = string_is_ip_address(ip, NULL);
132 if (ipv == 0 || (disable_ipv6 && ipv == 6))
133 return DECLINE;
134
135 /* It seems unlikely that ignore_target_hosts will be used with this router,
136 but if it is set, it should probably work. */
137
138 if (verify_check_this_host(CUSS&rblock->ignore_target_hosts,
139 NULL, domain, ip, NULL) == OK)
140 {
141 DEBUG(D_route)
142 debug_printf("%s is in ignore_target_hosts\n", ip);
143 addr->message = US"IP literal host explicitly ignored";
144 return DECLINE;
145 }
146
147 /* Set up a host item */
148
149 h = store_get(sizeof(host_item), FALSE);
150
151 h->next = NULL;
152 h->address = string_copy(ip);
153 h->port = PORT_NONE;
154 h->name = domain;
155 h->mx = MX_NONE;
156 h->status = hstatus_unknown;
157 h->why = hwhy_unknown;
158 h->last_try = 0;
159
160 /* Determine whether the host is the local host, and if so, take action
161 according to the configuration. */
162
163 if (host_scan_for_local_hosts(h, &h, NULL) == HOST_FOUND_LOCAL)
164 {
165 int rc = rf_self_action(addr, h, rblock->self_code, rblock->self_rewrite,
166 rblock->self, addr_new);
167 if (rc != OK) return rc;
168 }
169
170 /* Address is routed to this host */
171
172 addr->host_list = h;
173
174 /* Set up the errors address, if any. */
175
176 rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
177 if (rc != OK) return rc;
178
179 /* Set up the additional and removable headers for this address. */
180
181 rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
182 &addr->prop.remove_headers);
183 if (rc != OK) return rc;
184
185 /* Fill in the transport, queue the address for local or remote delivery, and
186 yield success. For local delivery, of course, the IP address won't be used. If
187 just verifying, there need not be a transport, in which case it doesn't matter
188 which queue we put the address on. This is all now handled by the route_queue()
189 function. */
190
191 if (!rf_get_transport(rblock->transport_name, &(rblock->transport),
192 addr, rblock->name, NULL))
193 return DEFER;
194
195 addr->transport = rblock->transport;
196
197 return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
198 OK : DEFER;
199 }
200
201 #endif /*!MACRO_PREDEF*/
202 /* End of routers/ipliteral.c */
203