Skip to content

Commit 3ab5182

Browse files
committed
Allow connect_port 0 as wildcard to permit all CONNECT ports
Setting connect_port to 0 acts as a wildcard that allows connections to any port. Specific port entries are checked first; the wildcard is used as a fallback. Wildcard matches are logged at LOG_WARNING level to help identify which non-standard ports are in use.
1 parent 83eef4e commit 3ab5182

5 files changed

Lines changed: 45 additions & 17 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ See `thinproxy.conf.example` for a full example.
112112
| Directive | Description | Default |
113113
|-----------|-------------|---------|
114114
| `deny_private` | Block private/reserved destinations (`yes`/`no`) | `yes` |
115-
| `connect_port` | Allowed CONNECT port (repeatable) | `443` |
115+
| `connect_port` | Allowed CONNECT port (repeatable, `0` = wildcard) | `443` |
116116
| `allow` | Allow source address/CIDR (whitelist mode) | |
117117
| `deny` | Deny source address/CIDR (blacklist mode) | |
118118

fuzz/fuzz_config.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
2828
acl_mode = ACL_NONE;
2929
nacl = 0;
3030
nconnect_ports = 0;
31+
connect_port_wildcard = 0;
3132
cfg_maxconns = MAX_CONNS;
3233
cfg_timeout = 300;
3334
cfg_maxconns_per_ip = 0;

thinproxy.8

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ The default is
136136
Restrict the CONNECT method to the specified
137137
.Ar port .
138138
May be specified multiple times to allow several ports.
139+
A
140+
.Ar port
141+
of
142+
.Cm 0
143+
acts as a wildcard, allowing all ports.
144+
When combined with explicit port entries, specific ports are checked
145+
first; the wildcard is used as a fallback.
146+
Connections allowed by the wildcard are logged at
147+
.Dv LOG_WARNING
148+
level to help identify which ports are actually needed.
139149
When any
140150
.Cm connect_port
141151
directive is present, CONNECT requests to unlisted ports are denied

thinproxy.c

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ static int nacl;
231231
#define MAX_CONNECT_PORTS 64
232232
static int connect_ports[MAX_CONNECT_PORTS] = { 443 };
233233
static int nconnect_ports = 1;
234+
static int connect_port_wildcard;
234235

235236
/* forward declarations */
236237
static void conn_close(struct conn *);
@@ -533,22 +534,24 @@ acl_check(struct sockaddr *sa)
533534
}
534535

535536
/*
536-
* Check if a CONNECT port is allowed.
537-
* Returns 1 if allowed, 0 if denied.
537+
* Check whether a CONNECT port is allowed.
538+
* Returns 0 if denied, 1 if explicitly listed, 2 if wildcard.
538539
*/
539540
static int
540541
connect_port_allowed(const char *port)
541542
{
542543
int p, i;
543544

544-
if (nconnect_ports == 0)
545+
if (nconnect_ports == 0 && !connect_port_wildcard)
545546
return 1;
546547

547548
p = (int)strtoll(port, NULL, 10);
548549
for (i = 0; i < nconnect_ports; i++) {
549550
if (connect_ports[i] == p)
550551
return 1;
551552
}
553+
if (connect_port_wildcard)
554+
return 2;
552555
return 0;
553556
}
554557

@@ -710,6 +713,7 @@ config_reset(void)
710713
nacl = 0;
711714
connect_ports[0] = 443;
712715
nconnect_ports = 1;
716+
connect_port_wildcard = 0;
713717
}
714718

715719
static int
@@ -863,7 +867,7 @@ parse_config(const char *path, int must_exist)
863867
cfg_deny_private = b;
864868
} else if (strcasecmp(key, "connect_port") == 0) {
865869
const char *errstr;
866-
int n = (int)strtonum(val, 1, 65535, &errstr);
870+
int n = (int)strtonum(val, 0, 65535, &errstr);
867871
if (errstr != NULL) {
868872
logmsg(LOG_ERR,
869873
"%s:%d: connect_port: %s",
@@ -873,16 +877,21 @@ parse_config(const char *path, int must_exist)
873877
}
874878
if (!connect_port_seen) {
875879
nconnect_ports = 0;
880+
connect_port_wildcard = 0;
876881
connect_port_seen = 1;
877882
}
878-
if (nconnect_ports >= MAX_CONNECT_PORTS) {
879-
logmsg(LOG_ERR,
880-
"%s:%d: too many connect_port entries",
881-
path, lineno);
882-
fclose(fp);
883-
return -1;
883+
if (n == 0) {
884+
connect_port_wildcard = 1;
885+
} else {
886+
if (nconnect_ports >= MAX_CONNECT_PORTS) {
887+
logmsg(LOG_ERR,
888+
"%s:%d: too many connect_port "
889+
"entries", path, lineno);
890+
fclose(fp);
891+
return -1;
892+
}
893+
connect_ports[nconnect_ports++] = n;
884894
}
885-
connect_ports[nconnect_ports++] = n;
886895
} else {
887896
logmsg(LOG_ERR, "%s:%d: unknown directive: %s",
888897
path, lineno, key);
@@ -1323,11 +1332,17 @@ handle_request(struct conn *c)
13231332
logmsg(LOG_INFO, "%s", logbuf);
13241333
}
13251334

1326-
if (is_connect && !connect_port_allowed(port)) {
1327-
logmsg(LOG_WARNING, "CONNECT port %s denied", port);
1328-
ign_write(c->cfd, ERR_403, sizeof(ERR_403) - 1);
1329-
conn_close(c);
1330-
return;
1335+
if (is_connect) {
1336+
int prc = connect_port_allowed(port);
1337+
if (prc == 0) {
1338+
logmsg(LOG_WARNING, "CONNECT port %s denied", port);
1339+
ign_write(c->cfd, ERR_403, sizeof(ERR_403) - 1);
1340+
conn_close(c);
1341+
return;
1342+
}
1343+
if (prc == 2)
1344+
logmsg(LOG_WARNING,
1345+
"CONNECT port %s allowed (wildcard)", port);
13311346
}
13321347

13331348
if (!is_connect) {

thinproxy.conf.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ port 8080
3333
# Restrict CONNECT method to specific ports (default: 443)
3434
# When set, CONNECT to unlisted ports is denied with 403.
3535
# Config entries replace the defaults.
36+
# Use 0 as a wildcard to allow all ports (logged at WARNING level).
3637
#connect_port 443
3738
#connect_port 8443
39+
#connect_port 0
3840

3941
# Access control lists
4042
# Use either "allow" or "deny" directives, not both.

0 commit comments

Comments
 (0)