From ca691d27890a443654f7a5cb66a0a8dddb954b86 Mon Sep 17 00:00:00 2001 From: dmiller Date: Fri, 14 Oct 2022 00:58:21 +0000 Subject: [PATCH] Simplify/unify target string representation --- ncat/ncat_connect.c | 59 +++++------------- ncat/ncat_listen.c | 43 +++---------- ncat/ncat_proxy.c | 8 +-- ncat/util.c | 147 +++++++++++++++++++++++--------------------- ncat/util.h | 1 + 5 files changed, 104 insertions(+), 154 deletions(-) diff --git a/ncat/ncat_connect.c b/ncat/ncat_connect.c index ab2bebdad..f1a09c56d 100644 --- a/ncat/ncat_connect.c +++ b/ncat/ncat_connect.c @@ -230,8 +230,13 @@ static void connect_report(nsock_iod nsi) nsock_iod_get_communication_info(nsi, NULL, NULL, NULL, &peer.sockaddr, sizeof(peer.storage)); if (o.verbose) { -#define connect_report_peer_str (o.proxytype ? o.target : inet_socktop(&peer)) -#define connect_report_peer_port (o.proxytype ? o.portno : nsock_iod_get_peerport(nsi)) + char peer_str[INET6_ADDRSTRLEN + sizeof(union sockaddr_u)] = {0}; + if (o.proxytype) { + Snprintf(peer_str, sizeof(peer_str), "%s:%u", o.target, o.portno); + } + else { + Strncpy(peer_str, socktop(&peer, 0), sizeof(peer_str)); + } #ifdef HAVE_OPENSSL if (nsock_iod_check_ssl(nsi)) { X509 *cert; @@ -239,8 +244,7 @@ static void connect_report(nsock_iod nsi) char digest_buf[SHA1_STRING_LENGTH + 1]; char *fp; - loguser("SSL connection to %s:%d.", connect_report_peer_str, - connect_report_peer_port); + loguser("SSL connection to %s.", peer_str); cert = SSL_get_peer_certificate((SSL *)nsock_iod_get_ssl(nsi)); ncat_assert(cert != NULL); @@ -260,34 +264,11 @@ static void connect_report(nsock_iod nsi) fp = ssl_cert_fp_str_sha1(cert, digest_buf, sizeof(digest_buf)); ncat_assert(fp == digest_buf); loguser("SHA-1 fingerprint: %s\n", digest_buf); - } else { -#if HAVE_SYS_UN_H - if (peer.sockaddr.sa_family == AF_UNIX) - loguser("Connected to %s.\n", peer.un.sun_path); - else + } else #endif -#ifdef HAVE_LINUX_VM_SOCKETS_H - if (peer.sockaddr.sa_family == AF_VSOCK) - loguser("Connection to %u.\n", peer.vm.svm_cid); - else -#endif - loguser("Connected to %s:%d.\n", connect_report_peer_str, - connect_report_peer_port); + { + loguser("Connected to %s.\n", peer_str); } -#else -#if HAVE_SYS_UN_H - if (peer.sockaddr.sa_family == AF_UNIX) - loguser("Connected to %s.\n", peer.un.sun_path); - else -#endif -#ifdef HAVE_LINUX_VM_SOCKETS_H - if (peer.sockaddr.sa_family == AF_VSOCK) - loguser("Connection to %u.\n", peer.vm.svm_cid); - else -#endif - loguser("Connected to %s:%d.\n", connect_report_peer_str, - connect_report_peer_port); -#endif } } @@ -390,7 +371,6 @@ static int do_proxy_http(void) char *target; union sockaddr_u addr; size_t sslen; - void *addrbuf; char addrstr[INET6_ADDRSTRLEN]; request = NULL; @@ -414,17 +394,7 @@ static int do_proxy_http(void) target = o.target; } else { /* addr is now populated with either sockaddr_in or sockaddr_in6 */ - switch (addr.sockaddr.sa_family) { - case AF_INET: - addrbuf = &addr.in.sin_addr; - break; - case AF_INET6: - addrbuf = &addr.in6.sin6_addr; - break; - default: - ncat_assert(0); - } - inet_ntop(addr.sockaddr.sa_family, addrbuf, addrstr, sizeof(addrstr)); + Strncpy(addrstr, inet_socktop(&addr), sizeof(addrstr)); target = addrstr; if (o.verbose && getaddrfamily(o.target) == -1) loguser("Host %s locally resolved to %s.\n", o.target, target); @@ -609,7 +579,7 @@ static int do_proxy_socks4(void) socks4msg.address = addr.in.sin_addr.s_addr; if (o.verbose && getaddrfamily(o.target) == -1) loguser("Host %s locally resolved to %s.\n", o.target, - inet_ntoa(addr.in.sin_addr)); + inet_socktop(&addr)); } if (send(sd, (char *)&socks4msg, offsetof(struct socks4_data, data) + datalen, 0) < 0) { @@ -654,7 +624,6 @@ static int do_proxy_socks5(void) size_t sslen; void *addrbuf; size_t addrlen; - char addrstr[INET6_ADDRSTRLEN]; size_t bndaddrlen; char bndaddr[SOCKS5_DST_MAXLEN + 2]; /* IPv4/IPv6/hostname and port */ @@ -837,7 +806,7 @@ static int do_proxy_socks5(void) dstlen = addrlen; if (o.verbose && getaddrfamily(o.target) == -1) loguser("Host %s locally resolved to %s.\n", o.target, - inet_ntop(addr.sockaddr.sa_family, addrbuf, addrstr, sizeof(addrstr))); + inet_socktop(&addr)); } memcpy(socks5msg2.dst + dstlen, &proxyport, 2); diff --git a/ncat/ncat_listen.c b/ncat/ncat_listen.c index 4493bf15e..99aecf330 100644 --- a/ncat/ncat_listen.c +++ b/ncat/ncat_listen.c @@ -270,14 +270,14 @@ int ncat_listen() listen_socket[num_sockets] = new_listen_socket(type, proto, &listenaddrs[i], &listen_fds); if (listen_socket[num_sockets] == -1) { if (o.debug > 0) - logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno())); + logdebug("do_listen(\"%s\"): %s\n", socktop(&listenaddrs[i], 0), socket_strerror(socket_errno())); continue; } num_sockets++; } if (num_sockets == 0) { if (num_listenaddrs == 1) - bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno())); + bye("Unable to open listening socket on %s: %s", socktop(&listenaddrs[0], 0), socket_strerror(socket_errno())); else bye("Unable to open any listening sockets."); } @@ -444,7 +444,7 @@ static void handle_connection(int socket_accept, int type, fd_set *listen_fds) rm_fd(&client_fdlist, socket_accept); listen_socket[i] = new_listen_socket(type, (o.af == AF_INET || o.af == AF_INET6) ? o.proto : 0, &localaddr, listen_fds); if (listen_socket[i] < 0) { - bye("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno())); + bye("do_listen(\"%s\"): %s\n", socktop(&listenaddrs[i], 0), socket_strerror(socket_errno())); return; } } @@ -459,23 +459,6 @@ static void handle_connection(int socket_accept, int type, fd_set *listen_fds) return; } - if (o.verbose) { -#if HAVE_SYS_UN_H - if (remoteaddr.sockaddr.sa_family == AF_UNIX) - loguser("Connection from %s.\n", remoteaddr.un.sun_path); - else -#endif -#ifdef HAVE_LINUX_VM_SOCKETS_H - if (remoteaddr.sockaddr.sa_family == AF_VSOCK) - loguser("Connection from %u.\n", remoteaddr.vm.svm_cid); - else -#endif - if (o.chat) - loguser("Connection from %s on file descriptor %d.\n", inet_socktop(&remoteaddr), s.fd); - else - loguser("Connection from %s.\n", inet_socktop(&remoteaddr)); - } - if (!o.keepopen && !o.broker) { int i; for (i = 0; i < num_listenaddrs; i++) { @@ -486,18 +469,10 @@ static void handle_connection(int socket_accept, int type, fd_set *listen_fds) } if (o.verbose) { -#if HAVE_SYS_UN_H - if (remoteaddr.sockaddr.sa_family == AF_UNIX) - loguser("Connection from %s.\n", remoteaddr.un.sun_path); - else -#endif -#ifdef HAVE_LINUX_VM_SOCKETS_H - if (remoteaddr.sockaddr.sa_family == AF_VSOCK) - loguser("Connection from %u:%u.\n", - remoteaddr.vm.svm_cid, remoteaddr.vm.svm_port); - else -#endif - loguser("Connection from %s:%hu.\n", inet_socktop(&remoteaddr), inet_port(&remoteaddr)); + loguser("Connection from %s", socktop(&remoteaddr, ss_len)); + if (o.chat) + loguser_noprefix(" on file descriptor %d", s.fd); + loguser_noprefix(".\n"); } /* Check conditions that might cause us to deny the connection. */ @@ -802,7 +777,7 @@ static int chat_announce_connect(int fd, const union sockaddr_u *su) int i, count, ret; strbuf_sprintf(&buf, &size, &offset, - " %s is connected as .\n", inet_socktop(su), fd); + " %s is connected as .\n", socktop(su, 0), fd); strbuf_sprintf(&buf, &size, &offset, " already connected: "); count = 0; @@ -819,7 +794,7 @@ static int chat_announce_connect(int fd, const union sockaddr_u *su) if (count > 0) strbuf_sprintf(&buf, &size, &offset, ", "); - strbuf_sprintf(&buf, &size, &offset, "%s as ", inet_socktop(&tsu), i); + strbuf_sprintf(&buf, &size, &offset, "%s as ", socktop(&tsu, len), i); count++; } diff --git a/ncat/ncat_proxy.c b/ncat/ncat_proxy.c index 7f4f477d0..1b3825e96 100644 --- a/ncat/ncat_proxy.c +++ b/ncat/ncat_proxy.c @@ -158,7 +158,7 @@ int ncat_http_server(void) listen_socket[num_sockets] = do_listen(SOCK_STREAM, IPPROTO_TCP, &listenaddrs[i]); if (listen_socket[num_sockets] == -1) { if (o.debug > 0) - logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno())); + logdebug("do_listen(\"%s\"): %s\n", socktop(&listenaddrs[i], 0), socket_strerror(socket_errno())); continue; } @@ -173,7 +173,7 @@ int ncat_http_server(void) } if (num_sockets == 0) { if (num_listenaddrs == 1) - bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno())); + bye("Unable to open listening socket on %s: %s", socktop(&listenaddrs[0], 0), socket_strerror(socket_errno())); else bye("Unable to open any listening sockets."); } @@ -438,7 +438,7 @@ static int handle_connect(struct socket_buffer *client_sock, if (connect(s, &su.sockaddr, sslen) == -1) { if (o.debug) - logdebug("Can't connect to %s.\n", inet_socktop(&su)); + logdebug("Can't connect to %s: %s.\n", socktop(&su, sslen), socket_strerror(socket_errno())); Close(s); return 504; } @@ -555,7 +555,7 @@ static int handle_method(struct socket_buffer *client_sock, if (connect(s, &su.sockaddr, sslen) == -1) { if (o.debug) - logdebug("Can't connect to %s.\n", inet_socktop(&su)); + logdebug("Can't connect to %s: %s.\n", socktop(&su, sslen), socket_strerror(socket_errno())); Close(s); return 504; } diff --git a/ncat/util.c b/ncat/util.c index ac83819bd..1c112315d 100644 --- a/ncat/util.c +++ b/ncat/util.c @@ -316,6 +316,65 @@ int addr_is_local(const union sockaddr_u *su) } } +/* Converts a sockaddr_u to a string representation. Since a static buffer is + * returned, this is not thread-safe and can only be used once in calls like + * printf(). ss_len may be 0 if it is not already known. +*/ +const char *socktop(const union sockaddr_u *su, socklen_t ss_len) +{ + static char buf[INET6_ADDRSTRLEN + sizeof(union sockaddr_u)]; + size_t size = sizeof(buf); + + switch (su->storage.ss_family) { +#if HAVE_SYS_UN_H + case AF_UNIX: + ncat_assert(ss_len <= sizeof(struct sockaddr_un)); + if (ss_len == sizeof(sa_family_t)) { + /* Unnamed socket */ + Strncpy(buf, "(unnamed socket)", sizeof(buf)); + } + else { + if (ss_len < sizeof(sa_family_t)) { + /* socket path not guaranteed to be valid, but we'll try. */ + size = sizeof(su->un.sun_path); + } + else { + /* We will add null terminator at size + 1 in case it was missing. */ + size = MIN(sizeof(buf) - 1, + ss_len - offsetof(struct sockaddr_un, sun_path)); + } + if (su->un.sun_path[0] == '\0') { + /* Abstract socket (Linux extension) */ + memcpy(buf, su->un.sun_path + 1, size - 1); + Strncpy(buf + size, " (abstract socket)", sizeof(buf) - size); + } + else { + memcpy(buf, su->un.sun_path, size); + buf[size+1] = '\0'; + } + /* In case we got junk data, make it safe. */ + replacenonprintable(buf, strlen(buf), '?'); + } + break; +#endif +#ifdef HAVE_LINUX_VM_SOCKETS_H + case AF_VSOCK: + Snprintf(buf, sizeof(buf), "%u:%u", su->vm.svm_cid, su->vm.svm_port); + break; +#endif + case AF_INET: + Snprintf(buf, sizeof(buf), "%s:%hu", inet_socktop(su), inet_port(su)); + break; + case AF_INET6: + Snprintf(buf, sizeof(buf), "[%s]:%hu", inet_socktop(su), inet_port(su)); + break; + default: + return NULL; + break; + } + return buf; +} + /* Converts an IP address given in a sockaddr_u to an IPv4 or IPv6 IP address string. Since a static buffer is returned, this is not thread-safe and can only be used once in calls like printf() @@ -345,14 +404,19 @@ const char *inet_socktop(const union sockaddr_u *su) /* Returns the port number in HOST BYTE ORDER based on the su's family */ unsigned short inet_port(const union sockaddr_u *su) { - if (su->storage.ss_family == AF_INET) - return ntohs(su->in.sin_port); + switch (su->storage.ss_family) { + case AF_INET: + return ntohs(su->in.sin_port); + break; #if HAVE_IPV6 - else if (su->storage.ss_family == AF_INET6) - return ntohs(su->in6.sin6_port); + case AF_INET6: + return ntohs(su->in6.sin6_port); + break; #endif - - bye("Invalid address family passed to inet_port()."); + default: + bye("Invalid address family passed to inet_port()."); + break; + } return 0; } @@ -394,72 +458,18 @@ int do_listen(int type, int proto, const union sockaddr_u *srcaddr_u) #endif #endif - switch(srcaddr_u->storage.ss_family) { -#ifdef HAVE_SYS_UN_H - case AF_UNIX: - sa_len = SUN_LEN(&srcaddr_u->un); - break; -#endif -#ifdef HAVE_LINUX_VM_SOCKETS_H - case AF_VSOCK: - sa_len = sizeof (struct sockaddr_vm); - break; -#endif -#ifdef HAVE_SOCKADDR_SA_LEN - default: - sa_len = srcaddr_u->sockaddr.sa_len; - break; -#else - case AF_INET: - sa_len = sizeof (struct sockaddr_in); - break; -#ifdef AF_INET6 - case AF_INET6: - sa_len = sizeof (struct sockaddr_in6); - break; -#endif - default: - sa_len = sizeof(*srcaddr_u); - break; -#endif - } + sa_len = get_socklen(srcaddr_u); if (bind(sock, &srcaddr_u->sockaddr, sa_len) < 0) { -#ifdef HAVE_SYS_UN_H - if (srcaddr_u->storage.ss_family == AF_UNIX) - bye("bind to %s: %s.", srcaddr_u->un.sun_path, + bye("bind to %s: %s.", socktop(srcaddr_u, sa_len), socket_strerror(socket_errno())); - else -#endif -#ifdef HAVE_LINUX_VM_SOCKETS_H - if (srcaddr_u->storage.ss_family == AF_VSOCK) - bye("bind to %u:%u: %s.", - srcaddr_u->vm.svm_cid, - srcaddr_u->vm.svm_port, - socket_strerror(socket_errno())); - else -#endif - bye("bind to %s:%hu: %s.", inet_socktop(srcaddr_u), - inet_port(srcaddr_u), socket_strerror(socket_errno())); } if (type == SOCK_STREAM) Listen(sock, BACKLOG); if (o.verbose) { -#ifdef HAVE_SYS_UN_H - if (srcaddr_u->storage.ss_family == AF_UNIX) - loguser("Listening on %s\n", srcaddr_u->un.sun_path); - else -#endif -#ifdef HAVE_LINUX_VM_SOCKETS_H - if (srcaddr_u->storage.ss_family == AF_VSOCK) - loguser("Listening on %u:%u\n", - srcaddr_u->vm.svm_cid, - srcaddr_u->vm.svm_port); - else -#endif - loguser("Listening on %s:%hu\n", inet_socktop(srcaddr_u), inet_port(srcaddr_u)); + loguser("Listening on %s\n", socktop(srcaddr_u, sa_len)); } if (o.test) logtest("LISTEN\n"); @@ -482,16 +492,11 @@ int do_connect(int type) sock = inheritable_socket(targetaddrs->addr.storage.ss_family, type, 0); if (srcaddr.storage.ss_family != AF_UNSPEC) { - size_t sa_len; + size_t sa_len = get_socklen(&srcaddr); -#ifdef HAVE_SOCKADDR_SA_LEN - sa_len = srcaddr.sockaddr.sa_len; -#else - sa_len = sizeof(srcaddr); -#endif if (bind(sock, &srcaddr.sockaddr, sa_len) < 0) { - bye("bind to %s:%hu: %s.", inet_socktop(&srcaddr), - inet_port(&srcaddr), socket_strerror(socket_errno())); + bye("bind to %s: %s.", socktop(&srcaddr, sa_len), + socket_strerror(socket_errno())); } } diff --git a/ncat/util.h b/ncat/util.h index c12cecbcb..97bc9a0a8 100644 --- a/ncat/util.h +++ b/ncat/util.h @@ -122,6 +122,7 @@ int strbuf_sprintf(char **buf, size_t *size, size_t *offset, const char *fmt, .. int addr_is_local(const union sockaddr_u *su); +const char *socktop(const union sockaddr_u *su, socklen_t ss_len); const char *inet_socktop(const union sockaddr_u *su); unsigned short inet_port(const union sockaddr_u *su);