mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
socks5: style and exit handling
This commit is contained in:
parent
df5c143b89
commit
32eaf83f24
2 changed files with 102 additions and 197 deletions
|
@ -87,8 +87,7 @@ lws_client_connect_2(struct lws *wsi)
|
|||
|
||||
} else if (wsi->vhost->socks_proxy_port) {
|
||||
socks_generate_msg(wsi, SOCKS_MSG_GREETING, &plen);
|
||||
lwsl_client("%s\n", "Sending SOCKS Greeting.");
|
||||
|
||||
lwsl_client("Sending SOCKS Greeting\n");
|
||||
ads = wsi->vhost->socks_proxy_address;
|
||||
port = wsi->vhost->socks_proxy_port;
|
||||
#endif
|
||||
|
@ -366,8 +365,7 @@ lws_client_connect_2(struct lws *wsi)
|
|||
n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
|
||||
MSG_NOSIGNAL);
|
||||
if (n < 0) {
|
||||
lwsl_debug("ERROR writing greeting to socks proxy"
|
||||
"socket.\n");
|
||||
lwsl_debug("ERROR writing socks greeting\n");
|
||||
cce = "socks write failed";
|
||||
goto failed;
|
||||
}
|
||||
|
@ -980,9 +978,12 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
|
|||
{
|
||||
struct lws_context *context = wsi->context;
|
||||
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
|
||||
ssize_t len = 0;
|
||||
ssize_t len = 0, n, passwd_len;
|
||||
short net_num;
|
||||
char *p;
|
||||
|
||||
if (type == SOCKS_MSG_GREETING) {
|
||||
switch (type) {
|
||||
case SOCKS_MSG_GREETING:
|
||||
/* socks version, version 5 only */
|
||||
pt->serv_buf[len++] = SOCKS_VERSION_5;
|
||||
/* number of methods */
|
||||
|
@ -991,33 +992,30 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
|
|||
pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD;
|
||||
/* no authentication method */
|
||||
pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH;
|
||||
}
|
||||
else if (type == SOCKS_MSG_USERNAME_PASSWORD) {
|
||||
ssize_t user_len = 0;
|
||||
ssize_t passwd_len = 0;
|
||||
break;
|
||||
|
||||
user_len = strlen(wsi->vhost->socks_user);
|
||||
case SOCKS_MSG_USERNAME_PASSWORD:
|
||||
n = strlen(wsi->vhost->socks_user);
|
||||
passwd_len = strlen(wsi->vhost->socks_password);
|
||||
|
||||
/* the subnegotiation version */
|
||||
pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1;
|
||||
/* length of the user name */
|
||||
pt->serv_buf[len++] = user_len;
|
||||
pt->serv_buf[len++] = n;
|
||||
/* user name */
|
||||
strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user,
|
||||
context->pt_serv_buf_size - len);
|
||||
len += user_len;
|
||||
len += n;
|
||||
/* length of the password */
|
||||
pt->serv_buf[len++] = passwd_len;
|
||||
/* password */
|
||||
strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_password,
|
||||
context->pt_serv_buf_size - len);
|
||||
len += passwd_len;
|
||||
}
|
||||
else if (type == SOCKS_MSG_CONNECT) {
|
||||
ssize_t len_index = 0;
|
||||
short net_num = 0;
|
||||
char *net_buf = (char*)&net_num;
|
||||
break;
|
||||
|
||||
case SOCKS_MSG_CONNECT:
|
||||
p = (char*)&net_num;
|
||||
|
||||
/* socks version */
|
||||
pt->serv_buf[len++] = SOCKS_VERSION_5;
|
||||
|
@ -1027,20 +1025,25 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
|
|||
pt->serv_buf[len++] = 0;
|
||||
/* address type */
|
||||
pt->serv_buf[len++] = SOCKS_ATYP_DOMAINNAME;
|
||||
len_index = len++;
|
||||
/* skip length, we fill it in at the end */
|
||||
n = len++;
|
||||
|
||||
/* the address we tell SOCKS proxy to connect to */
|
||||
strncpy((char *)&(pt->serv_buf[len]), wsi->u.hdr.stash->address,
|
||||
context->pt_serv_buf_size - len);
|
||||
len += strlen(wsi->u.hdr.stash->address);
|
||||
net_num = htons((short)wsi->c_port);
|
||||
net_num = htons(wsi->c_port);
|
||||
|
||||
/* the port we tell SOCKS proxy to connect to */
|
||||
pt->serv_buf[len++] = net_buf[0];
|
||||
pt->serv_buf[len++] = net_buf[1];
|
||||
pt->serv_buf[len++] = p[0];
|
||||
pt->serv_buf[len++] = p[1];
|
||||
|
||||
/* the length of the address, excluding port */
|
||||
pt->serv_buf[len_index] = strlen(wsi->u.hdr.stash->address);
|
||||
pt->serv_buf[n] = strlen(wsi->u.hdr.stash->address);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
*msg_len = len;
|
||||
|
|
250
lib/client.c
250
lib/client.c
|
@ -113,192 +113,98 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
#if defined(LWS_WITH_SOCKS5)
|
||||
/* SOCKS Greeting Reply */
|
||||
case LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY:
|
||||
|
||||
/* handle proxy hung up on us */
|
||||
|
||||
if (pollfd->revents & LWS_POLLHUP) {
|
||||
|
||||
lwsl_warn("SOCKS connection %p (fd=%d) dead\n",
|
||||
(void *)wsi, pollfd->fd);
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
|
||||
if (n < 0) {
|
||||
if (LWS_ERRNO == LWS_EAGAIN) {
|
||||
lwsl_debug("SOCKS read returned EAGAIN..."
|
||||
"retrying\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR reading from SOCKS socket\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* processing greeting reply */
|
||||
if (pt->serv_buf[0] == SOCKS_VERSION_5
|
||||
&& pt->serv_buf[1] == SOCKS_AUTH_NO_AUTH)
|
||||
{
|
||||
lwsl_client("%s\n", "SOCKS greeting reply received "
|
||||
"- No Authentication Method");
|
||||
socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len);
|
||||
|
||||
conn_mode = LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY;
|
||||
pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY;
|
||||
lwsl_client("%s\n", "Sending SOCKS connect command");
|
||||
}
|
||||
else if (pt->serv_buf[0] == SOCKS_VERSION_5
|
||||
&& pt->serv_buf[1] == SOCKS_AUTH_USERNAME_PASSWORD)
|
||||
{
|
||||
lwsl_client("%s\n", "SOCKS greeting reply received "
|
||||
"- User Name Password Method");
|
||||
socks_generate_msg(wsi, SOCKS_MSG_USERNAME_PASSWORD,
|
||||
&len);
|
||||
|
||||
conn_mode = LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY;
|
||||
pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY;
|
||||
lwsl_client("%s\n", "Sending SOCKS user/password");
|
||||
}
|
||||
else
|
||||
{
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR SOCKS greeting reply failed, method "
|
||||
"code: %d\n", pt->serv_buf[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = send(wsi->desc.sockfd, (char *)pt->serv_buf, len,
|
||||
MSG_NOSIGNAL);
|
||||
if (n < 0) {
|
||||
lwsl_debug("ERROR writing socks command to socks proxy "
|
||||
"socket\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lws_set_timeout(wsi, pending_timeout, AWAITING_TIMEOUT);
|
||||
wsi->mode = conn_mode;
|
||||
|
||||
break;
|
||||
/* SOCKS auth Reply */
|
||||
case LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY:
|
||||
|
||||
/* handle proxy hung up on us */
|
||||
|
||||
if (pollfd->revents & LWS_POLLHUP) {
|
||||
|
||||
lwsl_warn("SOCKS connection %p (fd=%d) dead\n",
|
||||
(void *)wsi, pollfd->fd);
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
|
||||
if (n < 0) {
|
||||
if (LWS_ERRNO == LWS_EAGAIN) {
|
||||
lwsl_debug("SOCKS read returned EAGAIN... "
|
||||
"retrying\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR reading from socks socket\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* processing auth reply */
|
||||
if (pt->serv_buf[0] == SOCKS_SUBNEGOTIATION_VERSION_1
|
||||
&& pt->serv_buf[1] == SOCKS_SUBNEGOTIATION_STATUS_SUCCESS)
|
||||
{
|
||||
lwsl_client("%s\n", "SOCKS password reply recieved - "
|
||||
"successful");
|
||||
socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len);
|
||||
|
||||
conn_mode = LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY;
|
||||
pending_timeout =
|
||||
PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY;
|
||||
lwsl_client("%s\n", "Sending SOCKS connect command");
|
||||
}
|
||||
else
|
||||
{
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR : SOCKS user/password reply failed, "
|
||||
"error code: %d\n", pt->serv_buf[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = send(wsi->desc.sockfd, (char *)pt->serv_buf, len,
|
||||
MSG_NOSIGNAL);
|
||||
if (n < 0) {
|
||||
lwsl_debug("ERROR writing connect command to SOCKS "
|
||||
"socket\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lws_set_timeout(wsi, pending_timeout, AWAITING_TIMEOUT);
|
||||
wsi->mode = conn_mode;
|
||||
|
||||
break;
|
||||
|
||||
/* SOCKS connect command Reply */
|
||||
case LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY:
|
||||
|
||||
/* handle proxy hung up on us */
|
||||
|
||||
if (pollfd->revents & LWS_POLLHUP) {
|
||||
|
||||
lwsl_warn("SOCKS connection %p (fd=%d) dead\n",
|
||||
(void *)wsi, pollfd->fd);
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 0;
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
|
||||
if (n < 0) {
|
||||
if (LWS_ERRNO == LWS_EAGAIN) {
|
||||
lwsl_debug("SOCKS read returned EAGAIN... "
|
||||
"retrying\n");
|
||||
lwsl_debug("SOCKS read EAGAIN, retrying\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR reading from socks socket\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* processing connect reply */
|
||||
if (pt->serv_buf[0] == SOCKS_VERSION_5
|
||||
&& pt->serv_buf[1] == SOCKS_REQUEST_REPLY_SUCCESS)
|
||||
{
|
||||
lwsl_client("%s\n", "SOCKS connect reply recieved - "
|
||||
"successful");
|
||||
}
|
||||
else
|
||||
{
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR SOCKS connect reply failed, error "
|
||||
"code: %d\n", pt->serv_buf[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* free stash since we are done with it */
|
||||
lws_free_set_NULL(wsi->u.hdr.stash);
|
||||
|
||||
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
|
||||
wsi->vhost->socks_proxy_address))
|
||||
lwsl_err("ERROR reading from SOCKS socket\n");
|
||||
goto bail3;
|
||||
wsi->c_port = wsi->vhost->socks_proxy_port;
|
||||
}
|
||||
|
||||
/* clear his proxy connection timeout */
|
||||
switch (wsi->mode) {
|
||||
|
||||
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
|
||||
case LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY:
|
||||
if (pt->serv_buf[0] != SOCKS_VERSION_5)
|
||||
goto socks_reply_fail;
|
||||
|
||||
goto start_ws_hanshake;
|
||||
if (pt->serv_buf[1] == SOCKS_AUTH_NO_AUTH) {
|
||||
lwsl_client("SOCKS greeting reply: No Auth Method\n");
|
||||
socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len);
|
||||
conn_mode = LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY;
|
||||
pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY;
|
||||
goto socks_send;
|
||||
}
|
||||
|
||||
if (pt->serv_buf[1] == SOCKS_AUTH_USERNAME_PASSWORD) {
|
||||
lwsl_client("SOCKS greeting reply: User/Pw Method\n");
|
||||
socks_generate_msg(wsi, SOCKS_MSG_USERNAME_PASSWORD, &len);
|
||||
conn_mode = LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY;
|
||||
pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY;
|
||||
goto socks_send;
|
||||
}
|
||||
goto socks_reply_fail;
|
||||
|
||||
case LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY:
|
||||
if (pt->serv_buf[0] != SOCKS_SUBNEGOTIATION_VERSION_1 ||
|
||||
pt->serv_buf[1] != SOCKS_SUBNEGOTIATION_STATUS_SUCCESS)
|
||||
goto socks_reply_fail;
|
||||
|
||||
lwsl_client("SOCKS password OK, sending connect\n");
|
||||
socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len);
|
||||
conn_mode = LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY;
|
||||
pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY;
|
||||
socks_send:
|
||||
n = send(wsi->desc.sockfd, (char *)pt->serv_buf, len,
|
||||
MSG_NOSIGNAL);
|
||||
if (n < 0) {
|
||||
lwsl_debug("ERROR writing to socks proxy\n");
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
lws_set_timeout(wsi, pending_timeout, AWAITING_TIMEOUT);
|
||||
wsi->mode = conn_mode;
|
||||
break;
|
||||
|
||||
socks_reply_fail:
|
||||
lwsl_notice("socks reply: v%d, err %d\n",
|
||||
pt->serv_buf[0], pt->serv_buf[1]);
|
||||
goto bail3;
|
||||
|
||||
case LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY:
|
||||
if (pt->serv_buf[0] != SOCKS_VERSION_5 ||
|
||||
pt->serv_buf[1] != SOCKS_REQUEST_REPLY_SUCCESS)
|
||||
goto socks_reply_fail;
|
||||
|
||||
lwsl_client("socks connect OK\n");
|
||||
|
||||
/* free stash since we are done with it */
|
||||
lws_free_set_NULL(wsi->u.hdr.stash);
|
||||
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
|
||||
wsi->vhost->socks_proxy_address))
|
||||
goto bail3;
|
||||
|
||||
wsi->c_port = wsi->vhost->socks_proxy_port;
|
||||
|
||||
/* clear his proxy connection timeout */
|
||||
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
|
||||
goto start_ws_handshake;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case LWSCM_WSCL_WAITING_PROXY_REPLY:
|
||||
|
||||
/* handle proxy hung up on us */
|
||||
|
@ -308,8 +214,7 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
lwsl_warn("Proxy connection %p (fd=%d) dead\n",
|
||||
(void *)wsi, pollfd->fd);
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 0;
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
|
||||
|
@ -318,18 +223,15 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
lwsl_debug("Proxy read returned EAGAIN... retrying\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR reading from proxy socket\n");
|
||||
return 0;
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
pt->serv_buf[13] = '\0';
|
||||
if (strcmp(sb, "HTTP/1.0 200 ") &&
|
||||
strcmp(sb, "HTTP/1.1 200 ")) {
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
lwsl_err("ERROR proxy: %s\n", sb);
|
||||
return 0;
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
/* clear his proxy connection timeout */
|
||||
|
@ -348,7 +250,7 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
* happening at a time when there's no real connection yet
|
||||
*/
|
||||
#if defined(LWS_WITH_SOCKS5)
|
||||
start_ws_hanshake:
|
||||
start_ws_handshake:
|
||||
#endif
|
||||
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Reference in a new issue