diff options
Diffstat (limited to 'src/usr.bin/nc/socks.c')
-rw-r--r-- | src/usr.bin/nc/socks.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/src/usr.bin/nc/socks.c b/src/usr.bin/nc/socks.c index 7c7448c9c5..1f1fb96e2a 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.34 2025/05/22 06:40:26 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,19 +293,33 @@ 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 | if (socksv == 4) { |
298 | decode_addrport(host, port, (struct sockaddr *)&addr, | 298 | /* This will exit on lookup failure */ |
299 | sizeof(addr), 1, 0); | 299 | decode_addrport(host, port, (struct sockaddr *)&addr, |
300 | sizeof(addr), 1, 0); | ||
301 | } | ||
300 | 302 | ||
301 | /* Version 4 */ | 303 | /* Version 4 */ |
302 | buf[0] = SOCKS_V4; | 304 | buf[0] = SOCKS_V4; |
303 | buf[1] = SOCKS_CONNECT; /* connect */ | 305 | buf[1] = SOCKS_CONNECT; /* connect */ |
304 | memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); | 306 | memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); |
305 | memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); | 307 | if (socksv == 4) { |
308 | memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); | ||
309 | } else { | ||
310 | /* SOCKS4A uses addr of 0.0.0.x, and hostname later */ | ||
311 | buf[4] = buf[5] = buf[6] = 0; | ||
312 | buf[7] = 1; | ||
313 | } | ||
306 | buf[8] = 0; /* empty username */ | 314 | buf[8] = 0; /* empty username */ |
307 | wlen = 9; | 315 | wlen = 9; |
308 | 316 | if (socksv == 44) { | |
317 | /* SOCKS4A has nul-terminated hostname after user */ | ||
318 | if (strlcpy(buf + 9, host, | ||
319 | sizeof(buf) - 9) >= sizeof(buf) - 9) | ||
320 | errx(1, "hostname too big"); | ||
321 | wlen = 9 + strlen(host) + 1; | ||
322 | } | ||
309 | cnt = atomicio(vwrite, proxyfd, buf, wlen); | 323 | cnt = atomicio(vwrite, proxyfd, buf, wlen); |
310 | if (cnt != wlen) | 324 | if (cnt != wlen) |
311 | err(1, "write failed (%zu/%zu)", cnt, wlen); | 325 | err(1, "write failed (%zu/%zu)", cnt, wlen); |
@@ -373,16 +387,16 @@ socks_connect(const char *host, const char *port, | |||
373 | /* Read status reply */ | 387 | /* Read status reply */ |
374 | proxy_read_line(proxyfd, buf, sizeof(buf)); | 388 | proxy_read_line(proxyfd, buf, sizeof(buf)); |
375 | if (proxyuser != NULL && | 389 | if (proxyuser != NULL && |
376 | (strncmp(buf, "HTTP/1.0 407 ", 12) == 0 || | 390 | (strncmp(buf, "HTTP/1.0 407 ", 13) == 0 || |
377 | strncmp(buf, "HTTP/1.1 407 ", 12) == 0)) { | 391 | strncmp(buf, "HTTP/1.1 407 ", 13) == 0)) { |
378 | if (authretry > 1) { | 392 | if (authretry > 1) { |
379 | fprintf(stderr, "Proxy authentication " | 393 | fprintf(stderr, "Proxy authentication " |
380 | "failed\n"); | 394 | "failed\n"); |
381 | } | 395 | } |
382 | close(proxyfd); | 396 | close(proxyfd); |
383 | goto again; | 397 | goto again; |
384 | } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 && | 398 | } else if (strncmp(buf, "HTTP/1.0 200 ", 13) != 0 && |
385 | strncmp(buf, "HTTP/1.1 200 ", 12) != 0) | 399 | strncmp(buf, "HTTP/1.1 200 ", 13) != 0) |
386 | errx(1, "Proxy error: \"%s\"", buf); | 400 | errx(1, "Proxy error: \"%s\"", buf); |
387 | 401 | ||
388 | /* Headers continue until we hit an empty line */ | 402 | /* Headers continue until we hit an empty line */ |