Lines 202-204
get_local_port(int sock)
Link Here
|
202 |
{ |
202 |
{ |
203 |
return get_sock_port(sock, 1); |
203 |
return get_sock_port(sock, 1); |
204 |
} |
204 |
} |
|
|
205 |
|
206 |
/* |
207 |
* Returns the remote DNS hostname as a string. The returned string must not |
208 |
* be freed. NB. this will usually trigger a DNS query the first time it is |
209 |
* called. |
210 |
* This function does additional checks on the hostname to mitigate some |
211 |
* attacks on legacy rhosts-style authentication. |
212 |
* XXX is RhostsRSAAuthentication vulnerable to these? |
213 |
* XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) |
214 |
*/ |
215 |
|
216 |
static char * |
217 |
remote_hostname(struct ssh *ssh) |
218 |
{ |
219 |
struct sockaddr_storage from; |
220 |
socklen_t fromlen; |
221 |
struct addrinfo hints, *ai, *aitop; |
222 |
char name[NI_MAXHOST], ntop2[NI_MAXHOST]; |
223 |
const char *ntop = ssh_remote_ipaddr(ssh); |
224 |
|
225 |
/* Get IP address of client. */ |
226 |
fromlen = sizeof(from); |
227 |
memset(&from, 0, sizeof(from)); |
228 |
if (getpeername(ssh_packet_get_connection_in(ssh), |
229 |
(struct sockaddr *)&from, &fromlen) == -1) { |
230 |
debug("getpeername failed: %.100s", strerror(errno)); |
231 |
return xstrdup(ntop); |
232 |
} |
233 |
|
234 |
ipv64_normalise_mapped(&from, &fromlen); |
235 |
if (from.ss_family == AF_INET6) |
236 |
fromlen = sizeof(struct sockaddr_in6); |
237 |
|
238 |
debug3("Trying to reverse map address %.100s.", ntop); |
239 |
/* Map the IP address to a host name. */ |
240 |
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), |
241 |
NULL, 0, NI_NAMEREQD) != 0) { |
242 |
/* Host name not found. Use ip address. */ |
243 |
return xstrdup(ntop); |
244 |
} |
245 |
|
246 |
/* |
247 |
* if reverse lookup result looks like a numeric hostname, |
248 |
* someone is trying to trick us by PTR record like following: |
249 |
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 |
250 |
*/ |
251 |
memset(&hints, 0, sizeof(hints)); |
252 |
hints.ai_socktype = SOCK_DGRAM; /*dummy*/ |
253 |
hints.ai_flags = AI_NUMERICHOST; |
254 |
if (getaddrinfo(name, NULL, &hints, &ai) == 0) { |
255 |
logit("Nasty PTR record \"%s\" is set up for %s, ignoring", |
256 |
name, ntop); |
257 |
freeaddrinfo(ai); |
258 |
return xstrdup(ntop); |
259 |
} |
260 |
|
261 |
/* Names are stored in lowercase. */ |
262 |
lowercase(name); |
263 |
|
264 |
/* |
265 |
* Map it back to an IP address and check that the given |
266 |
* address actually is an address of this host. This is |
267 |
* necessary because anyone with access to a name server can |
268 |
* define arbitrary names for an IP address. Mapping from |
269 |
* name to IP address can be trusted better (but can still be |
270 |
* fooled if the intruder has access to the name server of |
271 |
* the domain). |
272 |
*/ |
273 |
memset(&hints, 0, sizeof(hints)); |
274 |
hints.ai_family = from.ss_family; |
275 |
hints.ai_socktype = SOCK_STREAM; |
276 |
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { |
277 |
logit("reverse mapping checking getaddrinfo for %.700s " |
278 |
"[%s] failed.", name, ntop); |
279 |
return xstrdup(ntop); |
280 |
} |
281 |
/* Look for the address from the list of addresses. */ |
282 |
for (ai = aitop; ai; ai = ai->ai_next) { |
283 |
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, |
284 |
sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && |
285 |
(strcmp(ntop, ntop2) == 0)) |
286 |
break; |
287 |
} |
288 |
freeaddrinfo(aitop); |
289 |
/* If we reached the end of the list, the address was not there. */ |
290 |
if (ai == NULL) { |
291 |
/* Address not found for the host name. */ |
292 |
logit("Address %.100s maps to %.600s, but this does not " |
293 |
"map back to the address.", ntop, name); |
294 |
return xstrdup(ntop); |
295 |
} |
296 |
return xstrdup(name); |
297 |
} |
298 |
|
299 |
/* |
300 |
* Return the canonical name of the host in the other side of the current |
301 |
* connection. The host name is cached, so it is efficient to call this |
302 |
* several times. |
303 |
*/ |
304 |
|
305 |
const char * |
306 |
auth_get_canonical_hostname(struct ssh *ssh, int use_dns) |
307 |
{ |
308 |
static char *dnsname; |
309 |
|
310 |
if (!use_dns) |
311 |
return ssh_remote_ipaddr(ssh); |
312 |
else if (dnsname != NULL) |
313 |
return dnsname; |
314 |
else { |
315 |
dnsname = remote_hostname(ssh); |
316 |
return dnsname; |
317 |
} |
318 |
} |