Marcus Meissner
a4faf550b7
Fix breakage of IPv6 address handling [bsc#914527, bsc#899185] OBS-URL: https://build.opensuse.org/request/show/319256 OBS-URL: https://build.opensuse.org/package/show/network:utilities/tcpd?expand=0&rev=23
298 lines
8.2 KiB
Diff
298 lines
8.2 KiB
Diff
---
|
|
ip6utils.h | 2 +
|
|
rfc931.c | 101 +++++++++++++++++++++++++++++++++++++++----------------------
|
|
scaffold.c | 9 +----
|
|
socket.c | 14 +-------
|
|
tcpd.h | 8 +---
|
|
update.c | 4 +-
|
|
6 files changed, 76 insertions(+), 62 deletions(-)
|
|
|
|
Index: tcp_wrappers_7.6/ip6utils.h
|
|
===================================================================
|
|
--- tcp_wrappers_7.6.orig/ip6utils.h
|
|
+++ tcp_wrappers_7.6/ip6utils.h
|
|
@@ -1,6 +1,8 @@
|
|
#ifndef IP6UTILS_H
|
|
#define IP6UTILS_H
|
|
|
|
+#include <netinet/in.h>
|
|
+
|
|
/* inet_pton_mapped()
|
|
- works like inet_pton(3) but always returns IPv6 address
|
|
in dst - either "real" or v4mapped (::ffff:1.2.3.4) in
|
|
Index: tcp_wrappers_7.6/rfc931.c
|
|
===================================================================
|
|
--- tcp_wrappers_7.6.orig/rfc931.c
|
|
+++ tcp_wrappers_7.6/rfc931.c
|
|
@@ -65,28 +65,69 @@ int sig;
|
|
siglongjmp(timebuf, sig);
|
|
}
|
|
|
|
+static inline unsigned int
|
|
+sockaddr_len(const struct sockaddr_storage *ap)
|
|
+{
|
|
+ switch (ap->ss_family) {
|
|
+ case AF_INET:
|
|
+ return sizeof(struct sockaddr_in);
|
|
+
|
|
+ case AF_INET6:
|
|
+ return sizeof(struct sockaddr_in6);
|
|
+
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static inline unsigned short
|
|
+sockaddr_port(const struct sockaddr_storage *ap)
|
|
+{
|
|
+ unsigned short num;
|
|
+
|
|
+ switch (ap->ss_family) {
|
|
+ case AF_INET:
|
|
+ num = ((const struct sockaddr_in *) ap)->sin_port;
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ num = ((const struct sockaddr_in6 *) ap)->sin6_port;
|
|
+ break;
|
|
+ default:
|
|
+ num = 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ntohs(num);
|
|
+}
|
|
+
|
|
+static inline void
|
|
+sockaddr_set_port(struct sockaddr_storage *ap, unsigned short port)
|
|
+{
|
|
+ unsigned short num = htons(port);
|
|
+
|
|
+ switch (ap->ss_family) {
|
|
+ case AF_INET:
|
|
+ ((struct sockaddr_in *) ap)->sin_port = num;
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ ((struct sockaddr_in6 *) ap)->sin6_port = num;
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
/* rfc931 - return remote user name, given socket structures */
|
|
|
|
void rfc931(rmt_sin, our_sin, dest)
|
|
-#ifdef INET6
|
|
-struct sockaddr *rmt_sin;
|
|
-struct sockaddr *our_sin;
|
|
-#else
|
|
-struct sockaddr_in *rmt_sin;
|
|
-struct sockaddr_in *our_sin;
|
|
-#endif
|
|
+struct sockaddr_storage *rmt_sin;
|
|
+struct sockaddr_storage *our_sin;
|
|
char *dest;
|
|
{
|
|
unsigned rmt_port;
|
|
unsigned our_port;
|
|
-#ifdef INET6
|
|
struct sockaddr_storage rmt_query_sin;
|
|
struct sockaddr_storage our_query_sin;
|
|
int alen;
|
|
-#else
|
|
- struct sockaddr_in rmt_query_sin;
|
|
- struct sockaddr_in our_query_sin;
|
|
-#endif
|
|
char user[256]; /* XXX */
|
|
char buffer[512]; /* XXX */
|
|
char *cp;
|
|
@@ -97,18 +138,13 @@ char *dest;
|
|
|
|
#ifdef INET6
|
|
/* address family must be the same */
|
|
- if (rmt_sin->sa_family != our_sin->sa_family) {
|
|
+ if (rmt_sin->ss_family != our_sin->ss_family) {
|
|
STRN_CPY(dest, result, STRING_LENGTH);
|
|
return;
|
|
}
|
|
- switch (our_sin->sa_family) {
|
|
- case AF_INET:
|
|
- alen = sizeof(struct sockaddr_in);
|
|
- break;
|
|
- case AF_INET6:
|
|
- alen = sizeof(struct sockaddr_in6);
|
|
- break;
|
|
- default:
|
|
+
|
|
+ alen = sockaddr_len(our_sin);
|
|
+ if (alen == 0) {
|
|
STRN_CPY(dest, result, STRING_LENGTH);
|
|
return;
|
|
}
|
|
@@ -125,7 +161,7 @@ char *dest;
|
|
*/
|
|
|
|
#ifdef INET6
|
|
- if ((fp = fsocket(our_sin->sa_family, SOCK_STREAM, 0)) != 0) {
|
|
+ if ((fp = fsocket(our_sin->ss_family, SOCK_STREAM, 0)) != 0) {
|
|
#else
|
|
if ((fp = fsocket(AF_INET, SOCK_STREAM, 0)) != 0) {
|
|
#endif
|
|
@@ -154,18 +190,11 @@ char *dest;
|
|
*/
|
|
|
|
#ifdef INET6
|
|
- memcpy(&our_query_sin, our_sin, alen);
|
|
- memcpy(&rmt_query_sin, rmt_sin, alen);
|
|
- switch (our_sin->sa_family) {
|
|
- case AF_INET:
|
|
- ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
|
|
- ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC931_PORT);
|
|
- break;
|
|
- case AF_INET6:
|
|
- ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
|
|
- ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC931_PORT);
|
|
- break;
|
|
- }
|
|
+ our_query_sin = *our_sin;
|
|
+ sockaddr_set_port(&our_query_sin, ANY_PORT);
|
|
+
|
|
+ rmt_query_sin = *rmt_sin;
|
|
+ sockaddr_set_port(&rmt_query_sin, RFC931_PORT);
|
|
|
|
if (bind(fileno(fp), (struct sockaddr *) & our_query_sin,
|
|
alen) >= 0 &&
|
|
@@ -191,8 +220,8 @@ char *dest;
|
|
|
|
fprintf(fp, "%u,%u\r\n",
|
|
#ifdef INET6
|
|
- ntohs(((struct sockaddr_in *)rmt_sin)->sin_port),
|
|
- ntohs(((struct sockaddr_in *)our_sin)->sin_port));
|
|
+ sockaddr_port(rmt_sin),
|
|
+ sockaddr_port(our_sin));
|
|
#else
|
|
ntohs(rmt_sin->sin_port),
|
|
ntohs(our_sin->sin_port));
|
|
Index: tcp_wrappers_7.6/scaffold.c
|
|
===================================================================
|
|
--- tcp_wrappers_7.6.orig/scaffold.c
|
|
+++ tcp_wrappers_7.6/scaffold.c
|
|
@@ -336,13 +336,8 @@ struct request_info *request;
|
|
/* ARGSUSED */
|
|
|
|
void rfc931(rmt_sin, our_sin, dest)
|
|
-#ifndef INET6
|
|
-struct sockaddr_in *rmt_sin;
|
|
-struct sockaddr_in *our_sin;
|
|
-#else
|
|
-struct sockaddr *rmt_sin;
|
|
-struct sockaddr *our_sin;
|
|
-#endif
|
|
+struct sockaddr_storage *rmt_sin;
|
|
+struct sockaddr_storage *our_sin;
|
|
char *dest;
|
|
{
|
|
strcpy(dest, unknown);
|
|
Index: tcp_wrappers_7.6/tcpd.h
|
|
===================================================================
|
|
--- tcp_wrappers_7.6.orig/tcpd.h
|
|
+++ tcp_wrappers_7.6/tcpd.h
|
|
@@ -19,11 +19,7 @@
|
|
struct host_info {
|
|
char name[STRING_LENGTH]; /* access via eval_hostname(host) */
|
|
char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */
|
|
-#ifdef INET6
|
|
- struct sockaddr *sin; /* socket address or 0 */
|
|
-#else
|
|
- struct sockaddr_in *sin; /* socket address or 0 */
|
|
-#endif
|
|
+ struct sockaddr_storage *sin; /* socket address or 0 */
|
|
struct t_unitdata *unit; /* TLI transport address or 0 */
|
|
struct request_info *request; /* for shared information */
|
|
};
|
|
@@ -86,7 +82,7 @@ extern void fromhost(); /* get/validat
|
|
extern int hosts_access(struct request_info *);
|
|
extern void shell_cmd(char *);
|
|
extern char *percent_x(char *, int, char *, struct request_info *);
|
|
-extern void rfc931(struct sockaddr *, struct sockaddr *, char *);
|
|
+extern void rfc931(struct sockaddr_storage *, struct sockaddr_storage *, char *);
|
|
extern void clean_exit(struct request_info *);
|
|
extern void refuse(struct request_info *);
|
|
extern char *xgets(char *, int, FILE *);
|
|
Index: tcp_wrappers_7.6/socket.c
|
|
===================================================================
|
|
--- tcp_wrappers_7.6.orig/socket.c
|
|
+++ tcp_wrappers_7.6/socket.c
|
|
@@ -116,11 +116,7 @@ struct request_info *request;
|
|
memset(buf, 0 sizeof(buf));
|
|
#endif
|
|
}
|
|
-#ifdef INET6
|
|
- request->client->sin = (struct sockaddr *)&client;
|
|
-#else
|
|
request->client->sin = &client;
|
|
-#endif
|
|
|
|
/*
|
|
* Determine the server binding. This is used for client username
|
|
@@ -133,11 +129,7 @@ struct request_info *request;
|
|
tcpd_warn("getsockname: %m");
|
|
return;
|
|
}
|
|
-#ifdef INET6
|
|
- request->server->sin = (struct sockaddr *)&server;
|
|
-#else
|
|
request->server->sin = &server;
|
|
-#endif
|
|
}
|
|
|
|
|
|
@@ -180,7 +172,7 @@ struct request_info *request;
|
|
sock_methods(request);
|
|
|
|
memcpy(&client, res->ai_addr, res->ai_addrlen);
|
|
- request->client->sin = (struct sockaddr *)&client;
|
|
+ request->client->sin = &client;
|
|
freeaddrinfo(res);
|
|
|
|
request->client->name[0] = 0;
|
|
@@ -193,7 +185,7 @@ void sock_hostaddr(host)
|
|
struct host_info *host;
|
|
{
|
|
#ifdef INET6
|
|
- struct sockaddr *sin = host->sin;
|
|
+ struct sockaddr *sin = (struct sockaddr *) host->sin;
|
|
char *ap;
|
|
int alen;
|
|
|
|
@@ -227,7 +219,7 @@ void
|
|
sock_hostname(struct host_info *host)
|
|
{
|
|
struct addrinfo hints, *res, *resbase;
|
|
- struct sockaddr *sa = host->sin;
|
|
+ struct sockaddr *sa = (struct sockaddr *) host->sin;
|
|
struct sockaddr_in6 *sin6, sin6buf;
|
|
int errcode;
|
|
|
|
Index: tcp_wrappers_7.6/update.c
|
|
===================================================================
|
|
--- tcp_wrappers_7.6.orig/update.c
|
|
+++ tcp_wrappers_7.6/update.c
|
|
@@ -48,14 +48,14 @@ va_list ap;
|
|
continue;
|
|
case RQ_CLIENT_SIN:
|
|
#ifdef INET6
|
|
- request->client->sin = va_arg(ap, struct sockaddr *);
|
|
+ request->client->sin = va_arg(ap, struct sockaddr_storage *);
|
|
#else
|
|
request->client->sin = va_arg(ap, struct sockaddr_in *);
|
|
#endif
|
|
continue;
|
|
case RQ_SERVER_SIN:
|
|
#ifdef INET6
|
|
- request->server->sin = va_arg(ap, struct sockaddr *);
|
|
+ request->server->sin = va_arg(ap, struct sockaddr_storage *);
|
|
#else
|
|
request->server->sin = va_arg(ap, struct sockaddr_in *);
|
|
#endif
|