summaryrefslogtreecommitdiff
path: root/src/usr.bin/nc/socks.c
diff options
context:
space:
mode:
authordjm <>2025-05-21 08:41:35 +0000
committerdjm <>2025-05-21 08:41:35 +0000
commitc6ea37f37e2639ae1be03aff7c79a5962ee70a62 (patch)
treefd82dbfdcc3f7656a8be12d00e46cfac88c898d3 /src/usr.bin/nc/socks.c
parent80cafa36f69e0e544fce4f1ced15c277adaba45c (diff)
downloadopenbsd-c6ea37f37e2639ae1be03aff7c79a5962ee70a62.tar.gz
openbsd-c6ea37f37e2639ae1be03aff7c79a5962ee70a62.tar.bz2
openbsd-c6ea37f37e2639ae1be03aff7c79a5962ee70a62.zip
add SOCKS4A support to nc(1)'s proxy (-X) mode
SOCKS4A is a fairly obscure extension to the olde SOCKS4 protocol that allows passing the destination as a string rather than a literal IPv4 address, which is the only thing that vanilla SOCKS4 supports. The motivation for adding something so niche is to test the SOCKS4A server code in ssh(1)'s dynamic forwarding (-D) support. ok tb@
Diffstat (limited to 'src/usr.bin/nc/socks.c')
-rw-r--r--src/usr.bin/nc/socks.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/usr.bin/nc/socks.c b/src/usr.bin/nc/socks.c
index 7c7448c9c5..4c5ff90135 100644
--- a/src/usr.bin/nc/socks.c
+++ b/src/usr.bin/nc/socks.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: socks.c,v 1.31 2022/06/08 20:20:26 djm Exp $ */ 1/* $OpenBSD: socks.c,v 1.32 2025/05/21 08:41:35 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. 4 * Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -293,7 +293,7 @@ socks_connect(const char *host, const char *port,
293 default: 293 default:
294 errx(1, "connection failed, unsupported address type"); 294 errx(1, "connection failed, unsupported address type");
295 } 295 }
296 } else if (socksv == 4) { 296 } else if (socksv == 4 || socksv == 44) {
297 /* This will exit on lookup failure */ 297 /* This will exit on lookup failure */
298 decode_addrport(host, port, (struct sockaddr *)&addr, 298 decode_addrport(host, port, (struct sockaddr *)&addr,
299 sizeof(addr), 1, 0); 299 sizeof(addr), 1, 0);
@@ -302,10 +302,22 @@ socks_connect(const char *host, const char *port,
302 buf[0] = SOCKS_V4; 302 buf[0] = SOCKS_V4;
303 buf[1] = SOCKS_CONNECT; /* connect */ 303 buf[1] = SOCKS_CONNECT; /* connect */
304 memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); 304 memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port);
305 memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); 305 if (socksv == 4) {
306 memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr);
307 } else {
308 /* SOCKS4A uses addr of 0.0.0.x, and hostname later */
309 buf[4] = buf[5] = buf[6] = 0;
310 buf[7] = 1;
311 }
306 buf[8] = 0; /* empty username */ 312 buf[8] = 0; /* empty username */
307 wlen = 9; 313 wlen = 9;
308 314 if (socksv == 44) {
315 /* SOCKS4A has nul-terminated hostname after user */
316 if (strlcpy(buf + 9, host,
317 sizeof(buf) - 9) >= sizeof(buf) - 9)
318 errx(1, "hostname too big");
319 wlen = 9 + strlen(host) + 1;
320 }
309 cnt = atomicio(vwrite, proxyfd, buf, wlen); 321 cnt = atomicio(vwrite, proxyfd, buf, wlen);
310 if (cnt != wlen) 322 if (cnt != wlen)
311 err(1, "write failed (%zu/%zu)", cnt, wlen); 323 err(1, "write failed (%zu/%zu)", cnt, wlen);