Skip to content

Commit

Permalink
fix: SOCKS5 기능 복구
Browse files Browse the repository at this point in the history
  • Loading branch information
potados99 committed Oct 6, 2023
1 parent 37e0101 commit 3b786e2
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 46 deletions.
4 changes: 2 additions & 2 deletions opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* Proxy server settings
**********************************************************************************************************************/

#define PROXY_SERVER_LISTENING_INTERFACE INTERFACE_LWIP // change this: INTERFACE_NATIVE or INTERFACE_LWIP
#define PROXY_SERVER_LISTENING_INTERFACE INTERFACE_NATIVE // change this: INTERFACE_NATIVE or INTERFACE_LWIP

// When you use INTERFACE_NATIVE, you use the following settings.
#define PROXY_SERVER_NATIVE_LISTENING_ADDRESS "127.0.0.1"
Expand Down Expand Up @@ -51,7 +51,7 @@
* Proxy client settings
**********************************************************************************************************************/

#define PROXY_CLIENT_REMOTE_INTERFACE INTERFACE_LWIP // change this: INTERFACE_NATIVE or INTERFACE_LWIP
#define PROXY_CLIENT_REMOTE_INTERFACE INTERFACE_NATIVE // change this: INTERFACE_NATIVE or INTERFACE_LWIP

// Listening side settings.
#define PROXY_CLIENT_LISTENING_ADDRESS "127.0.0.1"
Expand Down
11 changes: 6 additions & 5 deletions proxy_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ void app_loop(crossbar *client_crossbar, crossbar *remote_crossbar) {
switch (version) {
case SOCKS_VERSION5: {
if (socks5_auth(conn_fd, methods) < 0) {
socks5_auth_not_supported(conn_fd);
log_message("app_loop() Socks auth failed.");
lwip_close(conn_fd);
continue;
Expand Down Expand Up @@ -201,8 +202,8 @@ void app_loop(crossbar *client_crossbar, crossbar *remote_crossbar) {
case SOCKS_VERSION4: {
switch (methods) {
case 1: {
unsigned short int p;
if (socks_read_port(conn_fd, &p) < 0) {
unsigned short int port;
if (socks_read_port(conn_fd, &port) < 0) {
log_message("app_loop() Socks read port failed.");
lwip_close(conn_fd);
continue;
Expand Down Expand Up @@ -231,17 +232,17 @@ void app_loop(crossbar *client_crossbar, crossbar *remote_crossbar) {
}
log_message("Socks4A: ident:%s; domain:%s;", ident, domain);

if ((remote_fd = request_connect(SOCKS_ADDR_DOMAINNAME, domain, p)) < 0) {
if ((remote_fd = request_connect(SOCKS_ADDR_DOMAINNAME, domain, port)) < 0) {
socks4_send_response(conn_fd, 0x5a);
lwip_close(conn_fd);
log_message("app_loop() socks request failed.");
free(ip);
continue;
}
} else {
log_message("Socks4: connect by ip & port", ip, p);
log_message("Socks4: connect by ip & port", ip, port);

if ((remote_fd = request_connect(SOCKS_ADDR_IPV4, ip, p)) < 0) {
if ((remote_fd = request_connect(SOCKS_ADDR_IPV4, ip, port)) < 0) {
socks4_send_response(conn_fd, 0x5b);
lwip_close(conn_fd);
log_message("app_loop() socks request failed.");
Expand Down
57 changes: 35 additions & 22 deletions socks.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#include <quiet-lwip/lwip-socket.h>

#if PROXY_SERVER_LISTENING_INTERFACE == INTERFACE_NATIVE

#include "lwip_mock.h"

#endif

int socks_invitation(int socket_fd, int *version, int *methods) {
Expand Down Expand Up @@ -154,31 +156,36 @@ int request_connect(int type, void *buf, unsigned short int port) {
}

int readn(int fd, void *buf, int n) {
int nread, left = n;
int nread;
int left = n;

while (left > 0) {
if ((nread = lwip_read(fd, buf, left)) == -1) {
nread = lwip_read(fd, buf, left);

if (nread == -1) {
if (errno == EINTR || errno == EAGAIN) {
errno = 0; // ignore
errno = 0; // just ignore the error.
continue;
}
} else {
if (nread == 0) {
return 0;
} else {
left -= nread;
buf += nread;
return -1;
}
} else if (nread == 0) {
return 0;
}

left -= nread;
buf += nread;
}

return n;
}

int readnull(int fd, char *buf, int size) {
char sym = 0;
int nread = 0;
int readnull(int fd, char *buf, int max) {
int nread;
int i = 0;
char sym = 0;

while (i < size) {
while (i < max) {
nread = lwip_recv(fd, &sym, sizeof(char), 0);

if (nread <= 0) {
Expand All @@ -197,20 +204,26 @@ int readnull(int fd, char *buf, int size) {
}

int writen(int fd, void *buf, int n) {
int nwrite, left = n;
int nwrite;
int left = n;

while (left > 0) {
if ((nwrite = lwip_write(fd, buf, left)) == -1) {
nwrite = lwip_write(fd, buf, left);

if (nwrite == -1) {
if (errno == EINTR || errno == EAGAIN) {
errno = 0; // just ignore the error.
continue;
}
} else {
if (nwrite == n) {
return 0;
} else {
left -= nwrite;
buf += nwrite;
return -1;
}
} else if (nwrite == n) {
return 0;
}

left -= nwrite;
buf += nwrite;
}
return n;

return 0;
}
58 changes: 56 additions & 2 deletions socks.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ enum socks_version {
};

enum socks_auth {
SOCKS_AUTH_NOAUTH = 0
SOCKS_AUTH_NOAUTH = 0,
SOCKS_AUTH_NOMETHOD = 255
};

enum socks_command {
Expand All @@ -38,10 +39,63 @@ int socks_read_port(int socket_fd, unsigned short int *port);

int request_connect(int type, void *buf, unsigned short int port);

/**
* Read n bytes from fd and put them into buf.
*
* This function consists of subsequent read() calls.
* Calls will be repeated until n bytes are read or an error occurs.
* Note: EINTER and EAGAIN are not considered as errors. They will be ignored.
*
* It will not return on partial reads. It waits until n bytes are read, and then this function returns.
*
* It is convenient to use this function when you want to grab n bytes without regards to partial reads.
*
* @param fd file descriptor of socket from where to read.
* @param buf a buffer where the bytes read will be stored.
* @param n read how many?
* @return n if success, 0 if connection closed, -1 if error.
*/
int readn(int fd, void *buf, int n);

int readnull(int fd, char *buf, int size);
/**
* Read maximum size bytes from fd until null character comes, and put them into buf.
*
* This function consists of subsequent read() calls.
* Calls will be repeated until one of the following conditions occurs:
* - null character comes
* - size bytes are read
* - an error occurs(including EINTER and EAGAIN).
*
* Any of the above conditions will immediately stop the read loop and make it return the number of bytes read so far.
* Note that the null character *is* included in the bytes count and the buffer.
*
* Beware that this functions lacks a error check functionality. :-)
*
* It is convenient to use this function, because it is good at reading a null terminated strings.
*
* @param fd file descriptor of socket from where to read.
* @param buf a buffer where the bytes read will be stored.
* @param max maximum size to read.
* @return number of bytes read so far.
*/
int readnull(int fd, char *buf, int max);

/**
* Write n bytes from buf into fd.
*
* This function consists of subsequent write() calls.
* Calls will be repeated until n bytes are written or an error occurs.
* Note: EINTER and EAGAIN are not considered as errors. They will be ignored.
*
* It will not return on partial writes. It waits until n bytes are written, and then this function returns.
*
* It is convenient to use this function when you want to put n bytes without regards to partial writes.
*
* @param fd file descriptor of socket to where to write.
* @param buf the source buffer
* @param n write how many?
* @return 0 if success, -1 if error.
*/
int writen(int fd, void *buf, int n);

#endif //QUIET_PRACTICE_SOCKS_H
2 changes: 1 addition & 1 deletion socks4.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int socks4_is_4a(const char *ip) {
int socks4_send_response(int fd, int status) {
char response[8] = {0x00, (char) status, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

if (writen(fd, response, ARRAY_SIZE(response)) < (int)ARRAY_SIZE(response)) {
if (writen(fd, response, ARRAY_SIZE(response)) != 0) {
return -1;
}

Expand Down
42 changes: 28 additions & 14 deletions socks5.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "relay.h"

int socks5_auth(int socket_fd, int methods) {
int supported = -1;

for (int i = 0; i < methods; i++) {
char method;
int n = readn(socket_fd, &method, 1);
Expand All @@ -19,19 +21,29 @@ int socks5_auth(int socket_fd, int methods) {

if (method == SOCKS_AUTH_NOAUTH) {
// support only SOCKS_AUTH_NOAUTH
return 0;
supported = 0;
}
}

return -1;
return supported;
}

int socks5_auth_reply(int socket_fd) {
int answer[] = {SOCKS_VERSION5, SOCKS_AUTH_NOAUTH};
int socks5_auth_not_supported(int socket_fd) {
char answer[2] = {SOCKS_VERSION5, SOCKS_AUTH_NOMETHOD};
if (writen(socket_fd, (void *) answer, ARRAY_SIZE(answer)) != 0) {
return -1;
}

return 0;
}

int written = writen(socket_fd, answer, ARRAY_SIZE(answer));
int socks5_auth_reply(int socket_fd) {
char answer[] = {SOCKS_VERSION5, SOCKS_AUTH_NOAUTH};
if (writen(socket_fd, answer, ARRAY_SIZE(answer)) != 0) {
return -1;
}

return (written == 2) ? 0 : -1;
return 0;
}

int socks5_command(int socket_fd, int *command) {
Expand All @@ -43,6 +55,8 @@ int socks5_command(int socket_fd, int *command) {
return -1;
}

log_message("Command %hhX %hhX %hhX %hhX", cmd[0], cmd[1],cmd[2], cmd[3]);

if (cmd[0] != SOCKS_VERSION5) {
log_message("socks5_command() invalid version: %d.", cmd[0]);
return -1;
Expand All @@ -60,7 +74,7 @@ int socks5_command(int socket_fd, int *command) {
return -1;
}

*command = (int) cmd[1];
*command = (int) cmd[3];

return 0;
}
Expand Down Expand Up @@ -92,19 +106,19 @@ int socks5_read_domain(int socket_fd, char **domain, int *domain_len) {
int socks5_domain_send_response(int socket_fd, char *domain, int domain_len, unsigned short int port) {
char response[] = {SOCKS_VERSION5, SOCKS_CONN_SUCCEEDED, 0, SOCKS_ADDR_DOMAINNAME};

if (writen(socket_fd, response, ARRAY_SIZE(response)) < (int)ARRAY_SIZE(response)) {
if (writen(socket_fd, response, ARRAY_SIZE(response)) != 0) {
return -1;
}

if (writen(socket_fd, &domain_len, sizeof(char)) < (int)sizeof(char)) {
if (writen(socket_fd, &domain_len, sizeof(char)) != 0) {
return -1;
}

if (writen(socket_fd, domain, domain_len * sizeof(char)) < domain_len * (int)sizeof(char)) {
if (writen(socket_fd, domain, domain_len * sizeof(char)) != 0) {
return -1;
}

if (writen(socket_fd, &port, sizeof(port)) < (int)sizeof(port)) {
if (writen(socket_fd, &port, sizeof(port)) != 0) {
return -1;
}

Expand All @@ -114,15 +128,15 @@ int socks5_domain_send_response(int socket_fd, char *domain, int domain_len, uns
int socks5_ip_send_response(int socket_fd, char *ip, unsigned short int port) {
char response[] = {SOCKS_VERSION5, SOCKS_CONN_SUCCEEDED, 0, SOCKS_ADDR_IPV4};

if (writen(socket_fd, response, ARRAY_SIZE(response)) < (int)ARRAY_SIZE(response)) {
if (writen(socket_fd, response, ARRAY_SIZE(response)) != 0) {
return -1;
}

if (writen(socket_fd, ip, IPSIZE * sizeof(char)) < IPSIZE * (int)sizeof(char)) {
if (writen(socket_fd, ip, IPSIZE * sizeof(char)) != 0) {
return -1;
}

if (writen(socket_fd, &port, sizeof(port)) < 2) {
if (writen(socket_fd, &port, sizeof(port)) != 0) {
return -1;
}

Expand Down
2 changes: 2 additions & 0 deletions socks5.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

int socks5_auth(int socket_fd, int methods);

int socks5_auth_not_supported(int socket_fd);

int socks5_auth_reply(int socket_fd);

int socks5_command(int socket_fd, int *command);
Expand Down

0 comments on commit 3b786e2

Please sign in to comment.