Verbose messages for spoof check... doesn't work on old linux libc?
[rsync/rsync.git] / socket.c
CommitLineData
7c1b4daa
MP
1/* -*- c-file-style: "linux" -*-
2
d54765c4
MP
3 rsync -- fast file replication program
4
eecd22ff 5 Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
362099a5 6 Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
bc2e93eb
AT
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
d5d4b282
MP
23/**
24 * @file socket.c
25 *
26 * Socket functions used in rsync.
362099a5
MP
27 *
28 * This file is now converted to use the new-style getaddrinfo()
29 * interface, which supports IPv6 but is also supported on recent
30 * IPv4-only machines. On systems that don't have that interface, we
31 * emulate it using the KAME implementation.
d5d4b282 32 **/
bc2e93eb 33
f0fca04e
AT
34#include "rsync.h"
35
885448d7
MP
36static const char default_name[] = "UNKNOWN";
37
9a5a8673 38
660c6fbd
MP
39/* Establish a proxy connection on an open socket to a web roxy by
40 * using the CONNECT method. */
4c3b4b25
AT
41static int establish_proxy_connection(int fd, char *host, int port)
42{
43 char buffer[1024];
44 char *cp;
45
8950ac03 46 snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
00d943d5 47 if (write(fd, buffer, strlen(buffer)) != (int) strlen(buffer)) {
660c6fbd 48 rprintf(FERROR, "failed to write to proxy: %s\n",
4c3b4b25
AT
49 strerror(errno));
50 return -1;
51 }
52
53 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
54 if (read(fd, cp, 1) != 1) {
660c6fbd
MP
55 rprintf(FERROR, "failed to read from proxy: %s\n",
56 strerror(errno));
4c3b4b25
AT
57 return -1;
58 }
59 if (*cp == '\n')
60 break;
61 }
62
63 if (*cp != '\n')
64 cp++;
65 *cp-- = '\0';
66 if (*cp == '\r')
67 *cp = '\0';
68 if (strncmp(buffer, "HTTP/", 5) != 0) {
69 rprintf(FERROR, "bad response from proxy - %s\n",
70 buffer);
71 return -1;
72 }
73 for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
74 ;
75 while (*cp == ' ')
76 cp++;
77 if (*cp != '2') {
78 rprintf(FERROR, "bad response from proxy - %s\n",
79 buffer);
80 return -1;
81 }
82 /* throw away the rest of the HTTP header */
83 while (1) {
84 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
85 cp++) {
86 if (read(fd, cp, 1) != 1) {
660c6fbd
MP
87 rprintf(FERROR, "failed to read from proxy: %s\n",
88 strerror(errno));
4c3b4b25
AT
89 return -1;
90 }
91 if (*cp == '\n')
92 break;
93 }
94 if ((cp > buffer) && (*cp == '\n'))
95 cp--;
96 if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
97 break;
98 }
99 return 0;
100}
101
102
f8be7d42
MP
103/**
104 * Try to set the local address for a newly-created socket. Return -1
105 * if this fails.
106 **/
107int try_bind_local(int s,
108 int ai_family, int ai_socktype,
109 const char *bind_address)
110{
111 int error;
112 struct addrinfo bhints, *bres_all, *r;
113
114 memset(&bhints, 0, sizeof(bhints));
115 bhints.ai_family = ai_family;
116 bhints.ai_socktype = ai_socktype;
117 bhints.ai_flags = AI_PASSIVE;
98355b80 118 if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
f8be7d42
MP
119 rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
120 bind_address, gai_strerror(error));
121 return -1;
122 }
123
124 for (r = bres_all; r; r = r->ai_next) {
9ec75284 125 if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
f8be7d42
MP
126 continue;
127 return s;
128 }
129
130 /* no error message; there might be some problem that allows
131 * creation of the socket but not binding, perhaps if the
132 * machine has no ipv6 address of this name. */
133 return -1;
134}
135
eecd22ff 136
d5d4b282
MP
137/**
138 * Open a socket to a tcp remote host with the specified port .
06963d0f 139 *
d5d4b282
MP
140 * Based on code from Warren. Proxy support by Stephen Rothwell.
141 * getaddrinfo() rewrite contributed by KAME.net.
06963d0f 142 *
d5d4b282
MP
143 * Now that we support IPv6 we need to look up the remote machine's
144 * address first, using @p af_hint to set a preference for the type
145 * of address. Then depending on whether it has v4 or v6 addresses we
146 * try to open a connection.
06963d0f 147 *
d5d4b282
MP
148 * The loop allows for machines with some addresses which may not be
149 * reachable, perhaps because we can't e.g. route ipv6 to that network
150 * but we can get ip4 packets through.
151 *
152 * @param bind_address Local address to use. Normally NULL to bind
153 * the wildcard address.
154 *
155 * @param af_hint Address family, e.g. AF_INET or AF_INET6.
06963d0f 156 **/
d5d4b282
MP
157int open_socket_out(char *host, int port, const char *bind_address,
158 int af_hint)
bc2e93eb 159{
f0fca04e 160 int type = SOCK_STREAM;
06963d0f
MP
161 int error;
162 int s;
06963d0f
MP
163 struct addrinfo hints, *res0, *res;
164 char portbuf[10];
4c3b4b25 165 char *h;
4c3b4b25
AT
166 int proxied = 0;
167 char buffer[1024];
168 char *cp;
169
660c6fbd
MP
170 /* if we have a RSYNC_PROXY env variable then redirect our
171 * connetcion via a web proxy at the given address. The format
172 * is hostname:port */
4c3b4b25
AT
173 h = getenv("RSYNC_PROXY");
174 proxied = (h != NULL) && (*h != '\0');
175
176 if (proxied) {
177 strlcpy(buffer, h, sizeof(buffer));
178 cp = strchr(buffer, ':');
179 if (cp == NULL) {
660c6fbd
MP
180 rprintf(FERROR,
181 "invalid proxy specification: should be HOST:PORT\n");
4c3b4b25
AT
182 return -1;
183 }
184 *cp++ = '\0';
06963d0f 185 strcpy(portbuf, cp);
4c3b4b25
AT
186 h = buffer;
187 } else {
06963d0f 188 snprintf(portbuf, sizeof(portbuf), "%d", port);
4c3b4b25 189 h = host;
4c3b4b25 190 }
f0fca04e 191
06963d0f 192 memset(&hints, 0, sizeof(hints));
d5d4b282 193 hints.ai_family = af_hint;
06963d0f
MP
194 hints.ai_socktype = type;
195 error = getaddrinfo(h, portbuf, &hints, &res0);
196 if (error) {
d5d4b282
MP
197 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
198 h, portbuf, gai_strerror(error));
f0fca04e
AT
199 return -1;
200 }
201
06963d0f 202 s = -1;
2d6dbe29
MP
203 /* Try to connect to all addresses for this machine until we get
204 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
205 * addresses. We need to create a socket for each record, since the
206 * address record tells us what protocol to use to try to connect. */
06963d0f
MP
207 for (res = res0; res; res = res->ai_next) {
208 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
209 if (s < 0)
210 continue;
f0fca04e 211
f8be7d42
MP
212 if (bind_address)
213 if (try_bind_local(s, res->ai_family, type,
214 bind_address) == -1) {
215 close(s);
216 s = -1;
06963d0f
MP
217 continue;
218 }
e30f0657 219
06963d0f
MP
220 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
221 close(s);
222 s = -1;
223 continue;
224 }
225 if (proxied &&
226 establish_proxy_connection(s, host, port) != 0) {
227 close(s);
228 s = -1;
229 continue;
230 } else
231 break;
4c3b4b25 232 }
06963d0f
MP
233 freeaddrinfo(res0);
234 if (s < 0) {
7ef6aa64
MP
235 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
236 h, strerror(errno));
f0fca04e
AT
237 return -1;
238 }
06963d0f 239 return s;
f0fca04e
AT
240}
241
242
eecd22ff
MP
243/**
244 * Open an outgoing socket, but allow for it to be intercepted by
245 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
246 * socketpair rather than really opening a socket.
247 *
248 * We use this primarily in testing to detect TCP flow bugs, but not
249 * cause security problems by really opening remote connections.
250 *
251 * This is based on the Samba LIBSMB_PROG feature.
06963d0f
MP
252 *
253 * @param bind_address Local address to use. Normally NULL to get the stack default.
eecd22ff
MP
254 **/
255int open_socket_out_wrapped (char *host,
256 int port,
d5d4b282
MP
257 const char *bind_address,
258 int af_hint)
eecd22ff
MP
259{
260 char *prog;
261
262 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
263 return sock_exec (prog);
264 else
d5d4b282
MP
265 return open_socket_out (host, port, bind_address,
266 af_hint);
eecd22ff
MP
267}
268
269
270
06963d0f
MP
271/**
272 * Open a socket of the specified type, port and address for incoming data
273 *
b8771f96
MP
274 * Try to be better about handling the results of getaddrinfo(): when
275 * opening an inbound socket, we might get several address results,
276 * e.g. for the machine's ipv4 and ipv6 name.
277 *
278 * If binding a wildcard, then any one of them should do. If an address
279 * was specified but it's insufficiently specific then that's not our
280 * fault.
281 *
282 * However, some of the advertized addresses may not work because e.g. we
283 * don't have IPv6 support in the kernel. In that case go on and try all
284 * addresses until one succeeds.
285 *
06963d0f
MP
286 * @param bind_address Local address to bind, or NULL to allow it to
287 * default.
288 **/
d5d4b282
MP
289static int open_socket_in(int type, int port, const char *bind_address,
290 int af_hint)
f0fca04e 291{
f0fca04e 292 int one=1;
06963d0f 293 int s;
13e29995 294 struct addrinfo hints, *all_ai, *resp;
06963d0f
MP
295 char portbuf[10];
296 int error;
297
298 memset(&hints, 0, sizeof(hints));
d5d4b282 299 hints.ai_family = af_hint;
06963d0f
MP
300 hints.ai_socktype = type;
301 hints.ai_flags = AI_PASSIVE;
302 snprintf(portbuf, sizeof(portbuf), "%d", port);
13e29995 303 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
06963d0f 304 if (error) {
7ef6aa64
MP
305 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
306 bind_address, gai_strerror(error));
06963d0f
MP
307 return -1;
308 }
06963d0f 309
13e29995
MP
310 /* We may not be able to create the socket, if for example the
311 * machine knows about IPv6 in the C library, but not in the
312 * kernel. */
313 for (resp = all_ai; resp; resp = resp->ai_next) {
314 s = socket(resp->ai_family, resp->ai_socktype,
315 resp->ai_protocol);
316
317 if (s == -1)
318 /* See if there's another address that will work... */
319 continue;
320
321 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
322 (char *)&one, sizeof one);
323
324 /* now we've got a socket - we need to bind it */
325 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
326 /* Nope, try another */
327 close(s);
328 continue;
b8771f96
MP
329 }
330
13e29995 331 return s;
f0fca04e
AT
332 }
333
13e29995
MP
334 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
335 "%s\n",
336 port,
337 strerror(errno));
b8771f96 338
13e29995 339 freeaddrinfo(all_ai);
b8771f96 340 return -1;
f0fca04e
AT
341}
342
343
7c1b4daa
MP
344/*
345 * Determine if a file descriptor is in fact a socket
346 */
f0fca04e
AT
347int is_a_socket(int fd)
348{
ac2a1a44
MP
349 int v;
350 socklen_t l;
3eb38818 351 l = sizeof(int);
7c1b4daa
MP
352
353 /* Parameters to getsockopt, setsockopt etc are very
354 * unstandardized across platforms, so don't be surprised if
ac2a1a44
MP
355 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
356 * It seems they all eventually get the right idea.
7c1b4daa
MP
357 *
358 * Debian says: ``The fifth argument of getsockopt and
359 * setsockopt is in reality an int [*] (and this is what BSD
360 * 4.* and libc4 and libc5 have). Some POSIX confusion
361 * resulted in the present socklen_t. The draft standard has
362 * not been adopted yet, but glibc2 already follows it and
363 * also has socklen_t [*]. See also accept(2).''
364 *
365 * We now return to your regularly scheduled programming. */
3eb38818 366 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
f0fca04e
AT
367}
368
369
8ef4ffd6 370void start_accept_loop(int port, int (*fn)(int ))
f0fca04e
AT
371{
372 int s;
06963d0f 373 extern char *bind_address;
13e29995 374 extern int default_af_hint;
f0fca04e 375
f0fca04e 376 /* open an incoming socket */
13e29995 377 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
f0fca04e 378 if (s == -1)
65417579 379 exit_cleanup(RERR_SOCKETIO);
f0fca04e
AT
380
381 /* ready to listen */
382 if (listen(s, 5) == -1) {
383 close(s);
65417579 384 exit_cleanup(RERR_SOCKETIO);
f0fca04e
AT
385 }
386
387
388 /* now accept incoming connections - forking a new process
389 for each incoming connection */
390 while (1) {
391 fd_set fds;
392 int fd;
2d6dbe29 393 struct sockaddr_storage addr;
d54765c4 394 socklen_t addrlen = sizeof addr;
f0fca04e 395
15b84e14
DD
396 /* close log file before the potentially very long select so
397 file can be trimmed by another process instead of growing
398 forever */
399 log_close();
45a83540 400
f0fca04e
AT
401 FD_ZERO(&fds);
402 FD_SET(s, &fds);
403
404 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
405 continue;
406 }
407
408 if(!FD_ISSET(s, &fds)) continue;
409
2d6dbe29 410 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
f0fca04e
AT
411
412 if (fd == -1) continue;
413
31f440e6
AT
414 signal(SIGCHLD, SIG_IGN);
415
416 /* we shouldn't have any children left hanging around
417 but I have had reports that on Digital Unix zombies
418 are produced, so this ensures that they are reaped */
419#ifdef WNOHANG
0503f060 420 while (waitpid(-1, NULL, WNOHANG) > 0);
31f440e6
AT
421#endif
422
f0fca04e
AT
423 if (fork()==0) {
424 close(s);
15b84e14
DD
425 /* open log file in child before possibly giving
426 up privileges */
427 log_open();
f0fca04e
AT
428 _exit(fn(fd));
429 }
430
431 close(fd);
432 }
f0fca04e
AT
433}
434
435
436enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
437
438struct
439{
440 char *name;
441 int level;
442 int option;
443 int value;
444 int opttype;
445} socket_options[] = {
446 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
447 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
448 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
449#ifdef TCP_NODELAY
450 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
451#endif
452#ifdef IPTOS_LOWDELAY
453 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
454#endif
455#ifdef IPTOS_THROUGHPUT
456 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
457#endif
458#ifdef SO_SNDBUF
459 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
460#endif
461#ifdef SO_RCVBUF
462 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
463#endif
464#ifdef SO_SNDLOWAT
465 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
466#endif
467#ifdef SO_RCVLOWAT
468 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
469#endif
470#ifdef SO_SNDTIMEO
471 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
472#endif
473#ifdef SO_RCVTIMEO
474 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
475#endif
476 {NULL,0,0,0,0}};
477
478
479
480/****************************************************************************
481set user socket options
482****************************************************************************/
483void set_socket_options(int fd, char *options)
484{
485 char *tok;
a6801c39
AT
486 if (!options || !*options) return;
487
f0fca04e
AT
488 options = strdup(options);
489
490 if (!options) out_of_memory("set_socket_options");
491
492 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
493 int ret=0,i;
494 int value = 1;
495 char *p;
496 int got_value = 0;
497
498 if ((p = strchr(tok,'='))) {
499 *p = 0;
500 value = atoi(p+1);
501 got_value = 1;
502 }
503
504 for (i=0;socket_options[i].name;i++)
505 if (strcmp(socket_options[i].name,tok)==0)
506 break;
507
508 if (!socket_options[i].name) {
509 rprintf(FERROR,"Unknown socket option %s\n",tok);
510 continue;
511 }
512
513 switch (socket_options[i].opttype) {
514 case OPT_BOOL:
515 case OPT_INT:
516 ret = setsockopt(fd,socket_options[i].level,
517 socket_options[i].option,(char *)&value,sizeof(int));
518 break;
519
520 case OPT_ON:
521 if (got_value)
522 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
523
524 {
525 int on = socket_options[i].value;
526 ret = setsockopt(fd,socket_options[i].level,
527 socket_options[i].option,(char *)&on,sizeof(int));
528 }
529 break;
530 }
531
532 if (ret != 0)
660c6fbd
MP
533 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
534 strerror(errno));
f0fca04e
AT
535 }
536
537 free(options);
538}
539
540/****************************************************************************
541become a daemon, discarding the controlling terminal
542****************************************************************************/
543void become_daemon(void)
544{
b11ed3b1
AT
545 int i;
546
c46ded46 547 if (fork()) {
f0fca04e 548 _exit(0);
c46ded46 549 }
f0fca04e
AT
550
551 /* detach from the terminal */
552#ifdef HAVE_SETSID
553 setsid();
554#else
555#ifdef TIOCNOTTY
c46ded46
AT
556 i = open("/dev/tty", O_RDWR);
557 if (i >= 0) {
558 ioctl(i, (int) TIOCNOTTY, (char *)0);
559 close(i);
f0fca04e
AT
560 }
561#endif /* TIOCNOTTY */
562#endif
b11ed3b1
AT
563 /* make sure that stdin, stdout an stderr don't stuff things
564 up (library functions, for example) */
565 for (i=0;i<3;i++) {
566 close(i);
567 open("/dev/null", O_RDWR);
568 }
bc2e93eb 569}
ff8b29b8 570
1f0fa931
MP
571/**
572 * Return the IP addr of the client as a string
573 **/
ff8b29b8
AT
574char *client_addr(int fd)
575{
2d6dbe29 576 struct sockaddr_storage ss;
d54765c4 577 socklen_t length = sizeof ss;
ff8b29b8 578 static char addr_buf[100];
11a5a3c7
AT
579 static int initialised;
580
581 if (initialised) return addr_buf;
582
583 initialised = 1;
ff8b29b8 584
07d70ff5 585 client_sockaddr(fd, &ss, &length);
06963d0f 586
2d6dbe29 587 getnameinfo((struct sockaddr *)&ss, length,
07d70ff5
MP
588 addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
589
ff8b29b8
AT
590 return addr_buf;
591}
592
593
51f289d1 594static int get_sockaddr_family(const struct sockaddr_storage *ss)
d91c8c50
MP
595{
596 return ((struct sockaddr *) ss)->sa_family;
597}
598
599
1f0fa931 600/**
d1d15050
MP
601 * Return the DNS name of the client.
602 *
603 * The name is statically cached so that repeated lookups are quick,
604 * so there is a limit of one lookup per customer.
885448d7
MP
605 *
606 * If anything goes wrong, including the name->addr->name check, then
607 * we just use "UNKNOWN", so you can use that value in hosts allow
608 * lines.
1f0fa931 609 **/
ff8b29b8
AT
610char *client_name(int fd)
611{
2d6dbe29 612 struct sockaddr_storage ss;
9a5a8673 613 socklen_t ss_len = sizeof ss;
ff8b29b8 614 static char name_buf[100];
06963d0f 615 static char port_buf[100];
11a5a3c7
AT
616 static int initialised;
617
618 if (initialised) return name_buf;
619
885448d7 620 strcpy(name_buf, default_name);
11a5a3c7 621 initialised = 1;
ff8b29b8 622
07d70ff5 623 client_sockaddr(fd, &ss, &ss_len);
ff8b29b8 624
2974e205
MP
625 if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
626 check_name(fd, &ss, ss_len, name_buf, port_buf);
9a5a8673
MP
627
628 return name_buf;
629}
630
631
07d70ff5 632
9a5a8673 633/**
07d70ff5 634 * Get the sockaddr for the client.
9a5a8673 635 **/
07d70ff5
MP
636void client_sockaddr(int fd,
637 struct sockaddr_storage *ss,
638 socklen_t *ss_len)
9a5a8673 639{
5fdcc397 640 if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
07d70ff5
MP
641 /* FIXME: Can we really not continue? */
642 rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
643 fd, strerror(errno));
644 exit_cleanup(RERR_SOCKETIO);
645 }
646
06963d0f 647#ifdef INET6
9a5a8673
MP
648 if (get_sockaddr_family(ss) == AF_INET6 &&
649 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
362099a5
MP
650 /* OK, so ss is in the IPv6 family, but it is really
651 * an IPv4 address: something like
652 * "::ffff:10.130.1.2". If we use it as-is, then the
653 * reverse lookup might fail or perhaps something else
654 * bad might happen. So instead we convert it to an
655 * equivalent address in the IPv4 address family. */
06963d0f
MP
656 struct sockaddr_in6 sin6;
657 struct sockaddr_in *sin;
658
9a5a8673
MP
659 memcpy(&sin6, ss, sizeof(sin6));
660 sin = (struct sockaddr_in *)ss;
06963d0f
MP
661 memset(sin, 0, sizeof(*sin));
662 sin->sin_family = AF_INET;
07d70ff5 663 *ss_len = sizeof(struct sockaddr_in);
06963d0f 664#ifdef HAVE_SOCKADDR_LEN
07d70ff5 665 sin->sin_len = *ss_len;
06963d0f
MP
666#endif
667 sin->sin_port = sin6.sin6_port;
07d70ff5
MP
668
669 /* There is a macro to extract the mapped part
670 * (IN6_V4MAPPED_TO_SINADDR ?), but it does not seem
671 * to be present in the Linux headers. */
06963d0f
MP
672 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
673 sizeof(sin->sin_addr));
674 }
675#endif
07d70ff5
MP
676}
677
06963d0f 678
07d70ff5
MP
679/**
680 * Look up a name from @p ss into @p name_buf.
681 **/
682int lookup_name(int fd, const struct sockaddr_storage *ss,
683 socklen_t ss_len,
684 char *name_buf, size_t name_buf_len,
685 char *port_buf, size_t port_buf_len)
686{
687 int name_err;
688
06963d0f 689 /* reverse lookup */
b14545b3
MP
690 name_err = getnameinfo((struct sockaddr *) ss, ss_len,
691 name_buf, name_buf_len,
692 port_buf, port_buf_len,
693 NI_NAMEREQD | NI_NUMERICSERV);
694 if (name_err != 0) {
885448d7 695 strcpy(name_buf, default_name);
2974e205
MP
696 rprintf(FERROR, RSYNC_NAME ": name lookup failed for %s: %s\n",
697 client_addr(fd),
9a5a8673
MP
698 gai_strerror(name_err));
699 return name_err;
ff8b29b8
AT
700 }
701
9a5a8673
MP
702 return 0;
703}
704
705
706
707/* Do a forward lookup on name_buf and make sure it corresponds to ss
708 * -- otherwise we may be being spoofed. If we suspect we are, then
709 * we don't abort the connection but just emit a warning. */
2974e205
MP
710int check_name(int fd,
711 const struct sockaddr_storage *ss,
712 socklen_t ss_len,
713 char *name_buf,
714 const char *port_buf)
9a5a8673
MP
715{
716 struct addrinfo hints, *res, *res0;
717 int error;
0d958249 718 int ss_family = get_sockaddr_family(ss);
9a5a8673 719
06963d0f
MP
720 memset(&hints, 0, sizeof(hints));
721 hints.ai_family = PF_UNSPEC;
0d958249 722 hints.ai_flags = ss_family;
06963d0f
MP
723 hints.ai_socktype = SOCK_STREAM;
724 error = getaddrinfo(name_buf, port_buf, &hints, &res0);
725 if (error) {
7ef6aa64 726 rprintf(FERROR,
9a5a8673
MP
727 RSYNC_NAME ": forward name lookup for %s:%s failed: %s\n",
728 name_buf, port_buf,
7ef6aa64 729 gai_strerror(error));
71c780da 730 strcpy(name_buf, default_name);
9a5a8673 731 return error;
06963d0f 732 }
de5fb374 733
9a5a8673
MP
734
735 /* We expect that one of the results will be the same as ss. */
06963d0f 736 for (res = res0; res; res = res->ai_next) {
0d958249
MP
737 if (res->ai_family != ss_family) {
738 rprintf(FERROR,
739 "check_name: response family %d != %d\n",
740 res->ai_family, ss_family);
06963d0f 741 continue;
0d958249
MP
742 }
743 if (res->ai_addrlen != ss_len) {
744 rprintf(FERROR,
745 "check_name: addrlen %d != %d\n",
746 res->ai_addrlen, ss_len);
06963d0f 747 continue;
0d958249
MP
748 }
749 if (memcmp(res->ai_addr, ss, res->ai_addrlen) == 0) {
750 rprintf(FERROR,
751 "check_name: %d bytes of address identical\n",
752 res->ai_addrlen);
06963d0f 753 break;
0d958249
MP
754 } else{
755 rprintf(FERROR,
756 "check_name: %d bytes of address NOT identical\n",
757 res->ai_addrlen);
758 }
06963d0f
MP
759 }
760
0d958249
MP
761 if (!res0) {
762 /* We hit the end of the list without finding an
763 * address that was the same as ss. */
764 rprintf(FERROR, RSYNC_NAME
765 ": no known address for \"%s\": "
766 "spoofed address?\n",
767 name_buf);
768 strcpy(name_buf, default_name);
769 }
06963d0f 770 if (res == NULL) {
9a5a8673
MP
771 /* We hit the end of the list without finding an
772 * address that was the same as ss. */
773 rprintf(FERROR, RSYNC_NAME
71c780da 774 ": %s is not a known address for \"%s\": "
2974e205 775 "spoofed address?\n",
71c780da
MP
776 client_addr(fd),
777 name_buf);
778 strcpy(name_buf, default_name);
de5fb374
AT
779 }
780
06963d0f 781 freeaddrinfo(res0);
9a5a8673 782 return 0;
ff8b29b8 783}
5c9730a4 784
eecd22ff
MP
785
786/*******************************************************************
787this is like socketpair but uses tcp. It is used by the Samba
788regression test code
789The function guarantees that nobody else can attach to the socket,
790or if they do that this function fails and the socket gets closed
791returns 0 on success, -1 on failure
792the resulting file descriptors are symmetrical
793 ******************************************************************/
794static int socketpair_tcp(int fd[2])
795{
796 int listener;
797 struct sockaddr_in sock;
798 struct sockaddr_in sock2;
799 socklen_t socklen = sizeof(sock);
800 int connect_done = 0;
801
802 fd[0] = fd[1] = listener = -1;
803
804 memset(&sock, 0, sizeof(sock));
805
806 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
807
808 memset(&sock2, 0, sizeof(sock2));
809#ifdef HAVE_SOCK_SIN_LEN
810 sock2.sin_len = sizeof(sock2);
811#endif
812 sock2.sin_family = PF_INET;
813
814 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
815
816 if (listen(listener, 1) != 0) goto failed;
817
818 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
819
820 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
821
822 set_nonblocking(fd[1]);
823
824 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
825
826 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
827 if (errno != EINPROGRESS) goto failed;
828 } else {
829 connect_done = 1;
830 }
831
832 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
833
834 close(listener);
835 if (connect_done == 0) {
836 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
837 && errno != EISCONN) goto failed;
838 }
839
840 set_blocking (fd[1]);
841
842 /* all OK! */
843 return 0;
844
845 failed:
846 if (fd[0] != -1) close(fd[0]);
847 if (fd[1] != -1) close(fd[1]);
848 if (listener != -1) close(listener);
849 return -1;
850}
851
852
d02984bb
MP
853
854/**
855 * Run a program on a local tcp socket, so that we can talk to it's
255810c0
MP
856 * stdin and stdout. This is used to fake a connection to a daemon
857 * for testing -- not for the normal case of running SSH.
d02984bb
MP
858 *
859 * @return a socket which is attached to a subprocess running
860 * "prog". stdin and stdout are attached. stderr is left attached to
861 * the original stderr
862 **/
eecd22ff
MP
863int sock_exec(const char *prog)
864{
865 int fd[2];
5d264037 866
eecd22ff
MP
867 if (socketpair_tcp(fd) != 0) {
868 rprintf (FERROR, RSYNC_NAME
869 ": socketpair_tcp failed (%s)\n",
870 strerror(errno));
871 return -1;
872 }
873 if (fork() == 0) {
874 close(fd[0]);
875 close(0);
876 close(1);
877 dup(fd[1]);
878 dup(fd[1]);
5d264037
MP
879 if (verbose > 3) {
880 /* Can't use rprintf because we've forked. */
eecd22ff
MP
881 fprintf (stderr,
882 RSYNC_NAME ": execute socket program \"%s\"\n",
883 prog);
5d264037 884 }
eecd22ff
MP
885 exit (system (prog));
886 }
887 close (fd[1]);
888 return fd[0];
889}
890
891
892