Compare commits

...

4 Commits

Author SHA1 Message Date
jendis
b85a6b3862
Merge 983df6f7ae into 12c9039ea4 2026-02-11 02:54:29 +03:00
Vladimir Dubrovin
12c9039ea4 Fixed: crash on invalid configuration file
Some checks failed
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
2026-01-28 19:40:58 +03:00
Vladimir Dubrovin
1a970c5c98 Fixed: memory corruptions on config parsing 2026-01-28 19:13:41 +03:00
Jan Smutny
983df6f7ae Extend SOCKS for AnyIP utilization
Introduce '-k' parameter that overwrites the -e parameter (if given) and
uses the IP for the external connection that corresponds to the current client
connection. The benefit arises when the parameter '-i0.0.0.0' or '-i::' in case
of IPv6 is set. This allows the entire range configured as local on the system
to receive connections and establish connections to the target server using the
IP address to which the client connected.
Note: This feature is not applicable for Windows.
2025-02-06 13:23:03 +01:00
6 changed files with 74 additions and 13 deletions

View File

@ -42,6 +42,16 @@ of IP-IP NAT (will not work for PAT)
Internal address. IP address proxy accepts connections to. Internal address. IP address proxy accepts connections to.
By default connection to any interface is accepted. It\'s usually unsafe. By default connection to any interface is accepted. It\'s usually unsafe.
.TP .TP
.B -k
External address given by
.B -e
is ignored and the internal address or generally the address client conected to is used instead.
This allows to utilize AnyIP Linux feature when
.B -i0.0.0.0
or in case of IPv6
.B -i::
is set. Not available for Windows platform.
.TP
.B -p .B -p
Port. Port proxy listens for incoming connections. Default is 1080. Port. Port proxy listens for incoming connections. Default is 1080.
.TP .TP

View File

@ -526,16 +526,48 @@ int doconnect(struct clientparam * param){
if(!*SAPORT(&param->sinsr))*SAPORT(&param->sinsr) = *SAPORT(&param->req); if(!*SAPORT(&param->sinsr))*SAPORT(&param->sinsr) = *SAPORT(&param->req);
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);} if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
if(SAISNULL(&param->sinsl)){ if(SAISNULL(&param->sinsl)){
if (param->srv->keepip) {
#ifndef NOIPV6
struct sockaddr_in6 local_addr;
socklen_t local_addr_len = sizeof(local_addr);
getsockname(param->clisock, (struct sockaddr *)&local_addr, &local_addr_len);
if(*SAFAMILY(&local_addr) == AF_INET6) {
if (IN6_IS_ADDR_V4MAPPED(&local_addr.sin6_addr)) {
struct sockaddr_in6 local_addr2;
memset(&local_addr2, 0, sizeof(local_addr2));
local_addr2.sin6_family = AF_INET;
local_addr2.sin6_port = local_addr.sin6_port;
param->sinsl = local_addr2;
} else {
param->sinsl = local_addr;
}
} else {
param->sinsl = local_addr;
}
#else
struct sockaddr_in local_addr;
socklen_t local_addr_len = sizeof(local_addr);
getsockname(new_sock, (struct sockaddr *)&local_addr, &local_addr_len);
param->sinsl = local_addr;
#endif
} else {
#ifndef NOIPV6 #ifndef NOIPV6
if(*SAFAMILY(&param->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6; if(*SAFAMILY(&param->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6;
else else
#endif #endif
param->sinsl = param->srv->extsa; param->sinsl = param->srv->extsa;
} }
}
*SAPORT(&param->sinsl) = 0; *SAPORT(&param->sinsl) = 0;
setopts(param->remsock, param->srv->srvsockopts); setopts(param->remsock, param->srv->srvsockopts);
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg)); param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
if (param->srv->keepip) {
int opt = 1;
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_IP, IP_FREEBIND, (char *)&opt, sizeof(int));
}
#ifdef REUSE #ifdef REUSE
{ {
int opt; int opt;

View File

@ -105,6 +105,10 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign
struct tm *ts; struct tm *ts;
ts = localtime(&t); ts = localtime(&t);
if(strlen((char *)name) >= 4096){
*buf = 0;
return buf;
}
if(strchr((char *)name, '%')){ if(strchr((char *)name, '%')){
struct clientparam fakecli; struct clientparam fakecli;
@ -905,7 +909,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
if(argc > 0 && strcmp("*", (char *)argv[0])) { if(argc > 0 && strcmp("*", (char *)argv[0])) {
arg = argv[0]; arg = argv[0];
arg = (unsigned char *)strtok((char *)arg, ","); arg = (unsigned char *)strtok((char *)arg, ",");
do { if(arg) do {
if(!acl->users) { if(!acl->users) {
acl->users = userl = myalloc(sizeof(struct userlist)); acl->users = userl = myalloc(sizeof(struct userlist));
} }
@ -924,7 +928,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(argc > 1 && strcmp("*", (char *)argv[1])) { if(argc > 1 && strcmp("*", (char *)argv[1])) {
arg = (unsigned char *)strtok((char *)argv[1], ","); arg = (unsigned char *)strtok((char *)argv[1], ",");
do { if(arg) do {
if(!acl->src) { if(!acl->src) {
acl->src = ipl = myalloc(sizeof(struct iplist)); acl->src = ipl = myalloc(sizeof(struct iplist));
} }
@ -945,7 +949,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(argc > 2 && strcmp("*", (char *)argv[2])) { if(argc > 2 && strcmp("*", (char *)argv[2])) {
arg = (unsigned char *)strtok((char *)argv[2], ","); arg = (unsigned char *)strtok((char *)argv[2], ",");
do { if(arg) do {
int arglen; int arglen;
unsigned char *pattern; unsigned char *pattern;
struct iplist tmpip={NULL}; struct iplist tmpip={NULL};
@ -1002,7 +1006,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(argc > 3 && strcmp("*", (char *)argv[3])) { if(argc > 3 && strcmp("*", (char *)argv[3])) {
arg = (unsigned char *)strtok((char *)argv[3], ","); arg = (unsigned char *)strtok((char *)argv[3], ",");
do { if(arg) do {
if(!acl->ports) { if(!acl->ports) {
acl->ports = portl = myalloc(sizeof(struct portlist)); acl->ports = portl = myalloc(sizeof(struct portlist));
} }
@ -1025,7 +1029,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(argc > 4 && strcmp("*", (char *)argv[4])) { if(argc > 4 && strcmp("*", (char *)argv[4])) {
arg = (unsigned char *)strtok((char *)argv[4], ","); arg = (unsigned char *)strtok((char *)argv[4], ",");
do { if(arg) do {
if(!strcmp((char *)arg, "CONNECT")){ if(!strcmp((char *)arg, "CONNECT")){
acl->operation |= CONNECT; acl->operation |= CONNECT;
} }
@ -1682,7 +1686,7 @@ int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned cha
} }
switch(*str){ switch(*str){
case '\0': case '\0':
if(comment) return -1; if(comment || incbegin) return -1;
argm[argc] = 0; argm[argc] = 0;
return argc; return argc;
case '$': case '$':
@ -1709,14 +1713,14 @@ int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned cha
argc--; argc--;
if((fd = open((char *)incbegin+1, O_RDONLY)) <= 0){ if((fd = open((char *)incbegin+1, O_RDONLY)) <= 0){
fprintf(stderr, "Failed to open %s\n", incbegin+1); fprintf(stderr, "Failed to open %s\n", incbegin+1);
break; return -1;
} }
if((*bufsize - *inbuf) <STRINGBUF){ if((*bufsize - *inbuf) <STRINGBUF){
*bufsize += STRINGBUF; *bufsize += STRINGBUF;
if(!(buf = myrealloc(buf, *bufsize))){ if(!(buf = myrealloc(buf, *bufsize))){
fprintf(stderr, "Failed to allocate memory for %s\n", incbegin+1); fprintf(stderr, "Failed to allocate memory for %s\n", incbegin+1);
close(fd); close(fd);
break; return -1;
} }
} }
len = 0; len = 0;
@ -1727,7 +1731,7 @@ int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned cha
if((res = read(fd, buf+*inbuf+len, STRINGBUF-(1+len))) <= 0) { if((res = read(fd, buf+*inbuf+len, STRINGBUF-(1+len))) <= 0) {
perror((char *)incbegin+1); perror((char *)incbegin+1);
close(fd); close(fd);
break; return -1;
} }
close(fd); close(fd);
buf[*inbuf+res+len] = 0; buf[*inbuf+res+len] = 0;

View File

@ -300,6 +300,8 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break; break;
} }
case 0:
j--;
default: default:
buf[i++] = format[j]; buf[i++] = format[j];
} }

View File

@ -288,6 +288,9 @@ int MODULEMAINFUNC (int argc, char** argv){
"\n" "\n"
" -iIP ip address or internal interface (clients are expected to connect)\n" " -iIP ip address or internal interface (clients are expected to connect)\n"
" -eIP ip address or external interface (outgoing connection will have this)\n" " -eIP ip address or external interface (outgoing connection will have this)\n"
#ifndef _WIN32
" -k outgoing connection will have local IP where client connected, thus ignores -e (useful in AnyIP case)\n"
#endif
" -rHOST:PORT Use IP:port for connect back proxy instead of listen port\n" " -rHOST:PORT Use IP:port for connect back proxy instead of listen port\n"
" -RHOST:PORT Use PORT to listen connect back proxy connection to pass data to\n" " -RHOST:PORT Use PORT to listen connect back proxy connection to pass data to\n"
" -4 Use IPv4 for outgoing connections\n" " -4 Use IPv4 for outgoing connections\n"
@ -426,6 +429,13 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif #endif
} }
break; break;
#ifndef _WIN32
case 'k':
{
srv.keepip = 1;
}
break;
#endif
case 'N': case 'N':
getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat); getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
break; break;
@ -815,6 +825,7 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
else { else {
new_sock = srv.so._accept(srv.so.state, sock, (struct sockaddr*)&defparam.sincr, &size); new_sock = srv.so._accept(srv.so.state, sock, (struct sockaddr*)&defparam.sincr, &size);
if(new_sock == INVALID_SOCKET){ if(new_sock == INVALID_SOCKET){
#ifdef _WIN32 #ifdef _WIN32
switch(WSAGetLastError()){ switch(WSAGetLastError()){
@ -990,6 +1001,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
srv->logdumpcli = conf.logdumpcli; srv->logdumpcli = conf.logdumpcli;
srv->cbsock = INVALID_SOCKET; srv->cbsock = INVALID_SOCKET;
srv->needuser = 1; srv->needuser = 1;
srv->keepip = 0;
#ifdef WITHSPLICE #ifdef WITHSPLICE
srv->usesplice = 1; srv->usesplice = 1;
#endif #endif

View File

@ -493,6 +493,7 @@ struct srvparam {
int paused, version; int paused, version;
int singlepacket; int singlepacket;
int usentlm; int usentlm;
int keepip;
int needuser; int needuser;
int silent; int silent;
int transparent; int transparent;