00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "rsync.h"
00035
00036 static const char default_name[] = "UNKNOWN";
00037 extern int am_server;
00038
00039
00040
00041
00042
00043 char *client_addr(int fd)
00044 {
00045 static char addr_buf[100];
00046 static int initialised;
00047 struct sockaddr_storage ss;
00048 socklen_t length = sizeof ss;
00049 char *ssh_info, *p;
00050
00051 if (initialised)
00052 return addr_buf;
00053
00054 initialised = 1;
00055
00056 if (am_server) {
00057 strcpy(addr_buf, "0.0.0.0");
00058 if ((ssh_info = getenv("SSH_CONNECTION")) != NULL
00059 || (ssh_info = getenv("SSH_CLIENT")) != NULL
00060 || (ssh_info = getenv("SSH2_CLIENT")) != NULL) {
00061 strlcpy(addr_buf, ssh_info, sizeof addr_buf);
00062
00063 if ((p = strchr(addr_buf, ' ')) != NULL)
00064 *p = '\0';
00065 }
00066 } else {
00067 client_sockaddr(fd, &ss, &length);
00068 getnameinfo((struct sockaddr *)&ss, length,
00069 addr_buf, sizeof addr_buf, NULL, 0, NI_NUMERICHOST);
00070 }
00071
00072 return addr_buf;
00073 }
00074
00075
00076 static int get_sockaddr_family(const struct sockaddr_storage *ss)
00077 {
00078 return ((struct sockaddr *) ss)->sa_family;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 char *client_name(int fd)
00096 {
00097 static char name_buf[100];
00098 static char port_buf[100];
00099 static int initialised;
00100 struct sockaddr_storage ss;
00101 socklen_t ss_len;
00102
00103 if (initialised)
00104 return name_buf;
00105
00106 strcpy(name_buf, default_name);
00107 initialised = 1;
00108
00109 memset(&ss, 0, sizeof ss);
00110
00111 if (am_server) {
00112 char *addr = client_addr(fd);
00113 struct addrinfo hint, *answer;
00114 int err;
00115
00116 memset(&hint, 0, sizeof hint);
00117
00118 #ifdef AI_NUMERICHOST
00119 hint.ai_flags = AI_NUMERICHOST;
00120 #endif
00121 hint.ai_socktype = SOCK_STREAM;
00122
00123 if ((err = getaddrinfo(addr, NULL, &hint, &answer)) != 0) {
00124 rprintf(FLOG, "malformed address %s: %s\n",
00125 addr, gai_strerror(err));
00126 return name_buf;
00127 }
00128
00129 switch (answer->ai_family) {
00130 case AF_INET:
00131 ss_len = sizeof (struct sockaddr_in);
00132 memcpy(&ss, answer->ai_addr, ss_len);
00133 break;
00134 #ifdef INET6
00135 case AF_INET6:
00136 ss_len = sizeof (struct sockaddr_in6);
00137 memcpy(&ss, answer->ai_addr, ss_len);
00138 break;
00139 #endif
00140 }
00141 freeaddrinfo(answer);
00142 } else {
00143 ss_len = sizeof ss;
00144 client_sockaddr(fd, &ss, &ss_len);
00145 }
00146
00147 if (lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf,
00148 port_buf, sizeof port_buf) == 0)
00149 check_name(fd, &ss, name_buf);
00150
00151 return name_buf;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 void client_sockaddr(int fd,
00163 struct sockaddr_storage *ss,
00164 socklen_t *ss_len)
00165 {
00166 memset(ss, 0, sizeof *ss);
00167
00168 if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
00169
00170 rsyserr(FLOG, errno, "getpeername on fd%d failed", fd);
00171 exit_cleanup(RERR_SOCKETIO);
00172 }
00173
00174 #ifdef INET6
00175 if (get_sockaddr_family(ss) == AF_INET6 &&
00176 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
00177
00178
00179
00180
00181
00182
00183 struct sockaddr_in6 sin6;
00184 struct sockaddr_in *sin;
00185
00186 memcpy(&sin6, ss, sizeof sin6);
00187 sin = (struct sockaddr_in *)ss;
00188 memset(sin, 0, sizeof *sin);
00189 sin->sin_family = AF_INET;
00190 *ss_len = sizeof (struct sockaddr_in);
00191 #ifdef HAVE_SOCKADDR_IN_LEN
00192 sin->sin_len = *ss_len;
00193 #endif
00194 sin->sin_port = sin6.sin6_port;
00195
00196
00197
00198
00199 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
00200 sizeof sin->sin_addr);
00201 }
00202 #endif
00203 }
00204
00205
00206
00207
00208
00209
00210
00211 int lookup_name(int fd, const struct sockaddr_storage *ss,
00212 socklen_t ss_len,
00213 char *name_buf, size_t name_buf_len,
00214 char *port_buf, size_t port_buf_len)
00215 {
00216 int name_err;
00217
00218
00219 name_err = getnameinfo((struct sockaddr *) ss, ss_len,
00220 name_buf, name_buf_len,
00221 port_buf, port_buf_len,
00222 NI_NAMEREQD | NI_NUMERICSERV);
00223 if (name_err != 0) {
00224 strcpy(name_buf, default_name);
00225 rprintf(FLOG, "name lookup failed for %s: %s\n",
00226 client_addr(fd), gai_strerror(name_err));
00227 return name_err;
00228 }
00229
00230 return 0;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240 int compare_addrinfo_sockaddr(const struct addrinfo *ai,
00241 const struct sockaddr_storage *ss)
00242 {
00243 int ss_family = get_sockaddr_family(ss);
00244 const char fn[] = "compare_addrinfo_sockaddr";
00245
00246 if (ai->ai_family != ss_family) {
00247 rprintf(FLOG, "%s: response family %d != %d\n",
00248 fn, ai->ai_family, ss_family);
00249 return 1;
00250 }
00251
00252
00253 if (ss_family == AF_INET) {
00254 const struct sockaddr_in *sin1, *sin2;
00255
00256 sin1 = (const struct sockaddr_in *) ss;
00257 sin2 = (const struct sockaddr_in *) ai->ai_addr;
00258
00259 return memcmp(&sin1->sin_addr, &sin2->sin_addr,
00260 sizeof sin1->sin_addr);
00261 }
00262
00263 #ifdef INET6
00264 if (ss_family == AF_INET6) {
00265 const struct sockaddr_in6 *sin1, *sin2;
00266
00267 sin1 = (const struct sockaddr_in6 *) ss;
00268 sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
00269
00270 if (ai->ai_addrlen < sizeof (struct sockaddr_in6)) {
00271 rprintf(FLOG, "%s: too short sockaddr_in6; length=%d\n",
00272 fn, ai->ai_addrlen);
00273 return 1;
00274 }
00275
00276 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
00277 sizeof sin1->sin6_addr))
00278 return 1;
00279
00280 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
00281 if (sin1->sin6_scope_id != sin2->sin6_scope_id)
00282 return 1;
00283 #endif
00284 return 0;
00285 }
00286 #endif
00287
00288
00289 return 1;
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 int check_name(int fd,
00304 const struct sockaddr_storage *ss,
00305 char *name_buf)
00306 {
00307 struct addrinfo hints, *res, *res0;
00308 int error;
00309 int ss_family = get_sockaddr_family(ss);
00310
00311 memset(&hints, 0, sizeof hints);
00312 hints.ai_family = ss_family;
00313 hints.ai_flags = AI_CANONNAME;
00314 hints.ai_socktype = SOCK_STREAM;
00315 error = getaddrinfo(name_buf, NULL, &hints, &res0);
00316 if (error) {
00317 rprintf(FLOG, "forward name lookup for %s failed: %s\n",
00318 name_buf, gai_strerror(error));
00319 strcpy(name_buf, default_name);
00320 return error;
00321 }
00322
00323
00324
00325 for (res = res0; res; res = res->ai_next) {
00326 if (!compare_addrinfo_sockaddr(res, ss))
00327 break;
00328 }
00329
00330 if (!res0) {
00331
00332
00333 rprintf(FLOG, "no known address for \"%s\": "
00334 "spoofed address?\n", name_buf);
00335 strcpy(name_buf, default_name);
00336 } else if (res == NULL) {
00337
00338
00339 rprintf(FLOG, "%s is not a known address for \"%s\": "
00340 "spoofed address?\n", client_addr(fd), name_buf);
00341 strcpy(name_buf, default_name);
00342 }
00343
00344 freeaddrinfo(res0);
00345 return 0;
00346 }