|
Lines 66-71
Link Here
|
| 66 |
#include "ssherr.h" |
66 |
#include "ssherr.h" |
| 67 |
#include "authfd.h" |
67 |
#include "authfd.h" |
| 68 |
|
68 |
|
|
|
69 |
#ifdef LINUX_IPV6_PREF_FLAGS |
| 70 |
# include <linux/in6.h> |
| 71 |
#endif |
| 72 |
|
| 69 |
char *client_version_string = NULL; |
73 |
char *client_version_string = NULL; |
| 70 |
char *server_version_string = NULL; |
74 |
char *server_version_string = NULL; |
| 71 |
Key *previous_host_key = NULL; |
75 |
Key *previous_host_key = NULL; |
|
Lines 267-272
ssh_kill_proxy_command(void)
Link Here
|
| 267 |
kill(proxy_command_pid, SIGHUP); |
271 |
kill(proxy_command_pid, SIGHUP); |
| 268 |
} |
272 |
} |
| 269 |
|
273 |
|
|
|
274 |
#ifdef HAS_IPV6_SRC_PREF |
| 275 |
enum ssh_bindpref {BINDPREF_PUB, BINDPREF_TMP}; |
| 276 |
|
| 277 |
static int |
| 278 |
ssh_mod_ipv6bindpref(int fd, enum ssh_bindpref pref) |
| 279 |
{ |
| 280 |
# ifdef LINUX_IPV6_PREF_FLAGS |
| 281 |
int val; |
| 282 |
int err; |
| 283 |
socklen_t len = sizeof(val); |
| 284 |
int add = 0; |
| 285 |
switch (pref) { |
| 286 |
case BINDPREF_PUB: |
| 287 |
add = IPV6_PREFER_SRC_PUBLIC; |
| 288 |
break; |
| 289 |
case BINDPREF_TMP: |
| 290 |
add = IPV6_PREFER_SRC_TMP; |
| 291 |
break; |
| 292 |
default: |
| 293 |
error("Unknown ssh_bindpref value"); |
| 294 |
return -1; |
| 295 |
} |
| 296 |
err = getsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &val, &len); |
| 297 |
if (err < 0) { |
| 298 |
error("getsockopt IPV6_ADDR_PREFERENCES: %.100s", |
| 299 |
strerror(errno)); |
| 300 |
return err; |
| 301 |
} |
| 302 |
|
| 303 |
val &= ~(IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP| |
| 304 |
IPV6_PREFER_SRC_PUBTMP_DEFAULT); |
| 305 |
val |= add; |
| 306 |
err = setsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &val, len); |
| 307 |
if (err < 0) { |
| 308 |
error("setsockopt IPV6_ADDR_PREFERENCES: %.100s", |
| 309 |
strerror(errno)); |
| 310 |
} |
| 311 |
return err; |
| 312 |
# else |
| 313 |
error("Setting IPv6 address source address not supported"); |
| 314 |
return -1; |
| 315 |
# endif |
| 316 |
} |
| 317 |
#endif |
| 318 |
|
| 270 |
/* |
319 |
/* |
| 271 |
* Creates a (possibly privileged) socket for use as the ssh connection. |
320 |
* Creates a (possibly privileged) socket for use as the ssh connection. |
| 272 |
*/ |
321 |
*/ |
|
Lines 275-280
ssh_create_socket(int privileged, struct addrinfo *ai)
Link Here
|
| 275 |
{ |
324 |
{ |
| 276 |
int sock, r, gaierr; |
325 |
int sock, r, gaierr; |
| 277 |
struct addrinfo hints, *res = NULL; |
326 |
struct addrinfo hints, *res = NULL; |
|
|
327 |
char *bind_address = options.bind_address; |
| 278 |
|
328 |
|
| 279 |
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
329 |
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
| 280 |
if (sock < 0) { |
330 |
if (sock < 0) { |
|
Lines 283-301
ssh_create_socket(int privileged, struct addrinfo *ai)
Link Here
|
| 283 |
} |
333 |
} |
| 284 |
fcntl(sock, F_SETFD, FD_CLOEXEC); |
334 |
fcntl(sock, F_SETFD, FD_CLOEXEC); |
| 285 |
|
335 |
|
|
|
336 |
/* Set IPV6_ADDR_PREFERENCES through magic bind address */ |
| 337 |
if (bind_address && bind_address[0] == '%') { |
| 338 |
#if defined(HAS_IPV6_SRC_PREF) |
| 339 |
if (ai->ai_family != AF_INET6) { |
| 340 |
debug("Not setting address preference on" |
| 341 |
" non-IPv6 socket"); |
| 342 |
} else if (strcmp(bind_address, "%pub") == 0 || |
| 343 |
strcmp(bind_address, "%public") == 0) { |
| 344 |
debug("Setting preference for public IPv6 address"); |
| 345 |
ssh_mod_ipv6bindpref(sock, BINDPREF_PUB); |
| 346 |
} else if (strcmp(bind_address, "%tmp") == 0 || |
| 347 |
strcmp(bind_address, "%temp") == 0) { |
| 348 |
debug("Setting preference for temporary IPv6 address"); |
| 349 |
ssh_mod_ipv6bindpref(sock, BINDPREF_TMP); |
| 350 |
} else { |
| 351 |
error("Unknown bind address preference: '%s'", |
| 352 |
bind_address); |
| 353 |
} |
| 354 |
#else |
| 355 |
error("IPv6 address preference selection not supported"); |
| 356 |
#endif |
| 357 |
bind_address = NULL; |
| 358 |
} |
| 286 |
/* Bind the socket to an alternative local IP address */ |
359 |
/* Bind the socket to an alternative local IP address */ |
| 287 |
if (options.bind_address == NULL && !privileged) |
360 |
if (bind_address == NULL && !privileged) |
| 288 |
return sock; |
361 |
return sock; |
| 289 |
|
362 |
|
| 290 |
if (options.bind_address) { |
363 |
if (bind_address) { |
| 291 |
memset(&hints, 0, sizeof(hints)); |
364 |
memset(&hints, 0, sizeof(hints)); |
| 292 |
hints.ai_family = ai->ai_family; |
365 |
hints.ai_family = ai->ai_family; |
| 293 |
hints.ai_socktype = ai->ai_socktype; |
366 |
hints.ai_socktype = ai->ai_socktype; |
| 294 |
hints.ai_protocol = ai->ai_protocol; |
367 |
hints.ai_protocol = ai->ai_protocol; |
| 295 |
hints.ai_flags = AI_PASSIVE; |
368 |
hints.ai_flags = AI_PASSIVE; |
| 296 |
gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); |
369 |
gaierr = getaddrinfo(bind_address, NULL, &hints, &res); |
| 297 |
if (gaierr) { |
370 |
if (gaierr) { |
| 298 |
error("getaddrinfo: %s: %s", options.bind_address, |
371 |
error("getaddrinfo: %s: %s", bind_address, |
| 299 |
ssh_gai_strerror(gaierr)); |
372 |
ssh_gai_strerror(gaierr)); |
| 300 |
close(sock); |
373 |
close(sock); |
| 301 |
return -1; |
374 |
return -1; |
|
Lines 316-322
ssh_create_socket(int privileged, struct addrinfo *ai)
Link Here
|
| 316 |
} |
389 |
} |
| 317 |
} else { |
390 |
} else { |
| 318 |
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
391 |
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
| 319 |
error("bind: %s: %s", options.bind_address, |
392 |
error("bind: %s: %s", bind_address, |
| 320 |
strerror(errno)); |
393 |
strerror(errno)); |
| 321 |
fail: |
394 |
fail: |
| 322 |
close(sock); |
395 |
close(sock); |
| 323 |
- |
|
|