netcat: fix report_sock-related bugs

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

netcat: fix report_sock-related bugs

astian
There were 3 related bugs here:
  1. The same report_sock call would sometimes print information about
     the peer socket and sometimes about the local socket.  This
     confusion may have been enabled by its duplicitous API.  This is
     fixed by dropping the path parameter and renaming it to
     report_addr.  Additionally, a new report_sock is added which first
     obtains the address for the given socket and then calls
     report_addr.
  2. In the case of "uflag && !kflag" branch of a listening socket there
     was a call to report_sock which neglected to adjust the argument
     depending on the address family: unix sockets would cause netcat to
     die.
  3. report_sock printed awkward messages because it always tacked "on"
     to the user-provided message, even though sometimes a different
     preposition was needed.  This is fixed by no longer adding anything
     to the user message.

This patch applies to netcat.c CVS 1.206.

diff --git netcat.c netcat.c
index c04298f..27ecc4e 100644
--- netcat.c
+++ netcat.c
@@ -138,7 +138,8 @@ void set_common_sockopts(int, int);
 int process_tos_opt(char *, int *);
 int process_tls_opt(char *, int *);
 void save_peer_cert(struct tls *_tls_ctx, FILE *_fp);
-void report_sock(const char *, const struct sockaddr *, socklen_t, char *);
+void report_addr(const char *, const struct sockaddr *, socklen_t);
+void report_sock(const char *, int sockfd);
 void report_tls(struct tls *tls_ctx, char * host);
 void usage(int);
 ssize_t drainbuf(int, unsigned char *, size_t *, struct tls *);
@@ -599,8 +600,8 @@ main(int argc, char *argv[])
  err(1, "connect");
 
  if (vflag)
- report_sock("Connection received",
-    (struct sockaddr *)&z, len, NULL);
+ report_addr("Connection received from",
+    (struct sockaddr *)&z, len);
 
  readwrite(s, NULL);
  } else {
@@ -615,9 +616,8 @@ main(int argc, char *argv[])
  err(1, "accept");
  }
  if (vflag)
- report_sock("Connection received",
-    (struct sockaddr *)&cliaddr, len,
-    family == AF_UNIX ? host : NULL);
+ report_addr("Connection received from",
+    (struct sockaddr *)&cliaddr, len);
  if ((usetls) &&
     (tls_cctx = tls_setup_server(tls_ctx, connfd, host)))
  readwrite(connfd, tls_cctx);
@@ -760,7 +760,8 @@ unix_bind(char *path, int flags)
  return -1;
  }
  if (vflag)
- report_sock("Bound", NULL, 0, path);
+ report_addr("Bound to", (struct sockaddr *)&s_un,
+    sizeof(s_un));
 
  return s;
 }
@@ -905,7 +906,7 @@ unix_listen(char *path)
  return -1;
  }
  if (vflag)
- report_sock("Listening", NULL, 0, path);
+ report_sock("Listening on", s);
 
  return s;
 }
@@ -1047,16 +1048,8 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
  if (listen(s, 1) == -1)
  err(1, "listen");
  }
- if (vflag && s != -1) {
- struct sockaddr_storage ss;
- socklen_t len;
-
- len = sizeof(ss);
- if (getsockname(s, (struct sockaddr *)&ss, &len) == -1)
- err(1, "getsockname");
- report_sock(uflag ? "Bound" : "Listening",
-    (struct sockaddr *)&ss, len, NULL);
- }
+ if (vflag && s != -1)
+ report_sock(uflag ? "Bound to" : "Listening on", s);
 
  freeaddrinfo(res0);
 
@@ -1713,15 +1706,18 @@ report_tls(struct tls * tls_ctx, char * host)
 }
 
 void
-report_sock(const char *msg, const struct sockaddr *sa, socklen_t salen,
-    char *path)
+report_addr(const char *msg, const struct sockaddr *sa, socklen_t salen)
 {
  char host[NI_MAXHOST], port[NI_MAXSERV];
  int herr;
  int flags = NI_NUMERICSERV;
 
- if (path != NULL) {
- fprintf(stderr, "%s on %s\n", msg, path);
+ if (sa->sa_family == AF_UNIX) {
+ const struct sockaddr_un *sun = (struct sockaddr_un *) sa;
+ const char *path = (salen < sizeof(struct sockaddr_un))
+    ? "[unknown address]"
+    : sun->sun_path;
+ fprintf(stderr, "%s %s\n", msg, path);
  return;
  }
 
@@ -1736,7 +1732,19 @@ report_sock(const char *msg, const struct sockaddr *sa, socklen_t salen,
  errx(1, "getnameinfo: %s", gai_strerror(herr));
  }
 
- fprintf(stderr, "%s on %s %s\n", msg, host, port);
+ fprintf(stderr, "%s %s %s\n", msg, host, port);
+}
+
+void
+report_sock(const char *msg, int sockfd)
+{
+ struct sockaddr_storage ss;
+ socklen_t len;
+
+ len = sizeof(ss);
+ if (getsockname(sockfd, (struct sockaddr *)&ss, &len) == -1)
+ err(1, "getsockname");
+ report_addr(msg, (struct sockaddr *)&ss, len);
 }
 
 void