Skip to content
Snippets Groups Projects
Commit 32eaf83f authored by Andy Green's avatar Andy Green
Browse files

socks5: style and exit handling

parent df5c143b
Branches
Tags
No related merge requests found
...@@ -87,8 +87,7 @@ lws_client_connect_2(struct lws *wsi) ...@@ -87,8 +87,7 @@ lws_client_connect_2(struct lws *wsi)
} else if (wsi->vhost->socks_proxy_port) { } else if (wsi->vhost->socks_proxy_port) {
socks_generate_msg(wsi, SOCKS_MSG_GREETING, &plen); 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; ads = wsi->vhost->socks_proxy_address;
port = wsi->vhost->socks_proxy_port; port = wsi->vhost->socks_proxy_port;
#endif #endif
...@@ -366,8 +365,7 @@ lws_client_connect_2(struct lws *wsi) ...@@ -366,8 +365,7 @@ lws_client_connect_2(struct lws *wsi)
n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen, n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
MSG_NOSIGNAL); MSG_NOSIGNAL);
if (n < 0) { if (n < 0) {
lwsl_debug("ERROR writing greeting to socks proxy" lwsl_debug("ERROR writing socks greeting\n");
"socket.\n");
cce = "socks write failed"; cce = "socks write failed";
goto failed; goto failed;
} }
...@@ -980,9 +978,12 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type, ...@@ -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 *context = wsi->context;
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; 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 */ /* socks version, version 5 only */
pt->serv_buf[len++] = SOCKS_VERSION_5; pt->serv_buf[len++] = SOCKS_VERSION_5;
/* number of methods */ /* number of methods */
...@@ -991,33 +992,30 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type, ...@@ -991,33 +992,30 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD; pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD;
/* no authentication method */ /* no authentication method */
pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH; pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH;
} break;
else if (type == SOCKS_MSG_USERNAME_PASSWORD) {
ssize_t user_len = 0;
ssize_t passwd_len = 0;
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); passwd_len = strlen(wsi->vhost->socks_password);
/* the subnegotiation version */ /* the subnegotiation version */
pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1; pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1;
/* length of the user name */ /* length of the user name */
pt->serv_buf[len++] = user_len; pt->serv_buf[len++] = n;
/* user name */ /* user name */
strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user, strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user,
context->pt_serv_buf_size - len); context->pt_serv_buf_size - len);
len += user_len; len += n;
/* length of the password */ /* length of the password */
pt->serv_buf[len++] = passwd_len; pt->serv_buf[len++] = passwd_len;
/* password */ /* password */
strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_password, strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_password,
context->pt_serv_buf_size - len); context->pt_serv_buf_size - len);
len += passwd_len; len += passwd_len;
} break;
else if (type == SOCKS_MSG_CONNECT) {
ssize_t len_index = 0; case SOCKS_MSG_CONNECT:
short net_num = 0; p = (char*)&net_num;
char *net_buf = (char*)&net_num;
/* socks version */ /* socks version */
pt->serv_buf[len++] = SOCKS_VERSION_5; pt->serv_buf[len++] = SOCKS_VERSION_5;
...@@ -1027,20 +1025,25 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type, ...@@ -1027,20 +1025,25 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
pt->serv_buf[len++] = 0; pt->serv_buf[len++] = 0;
/* address type */ /* address type */
pt->serv_buf[len++] = SOCKS_ATYP_DOMAINNAME; 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 */ /* the address we tell SOCKS proxy to connect to */
strncpy((char *)&(pt->serv_buf[len]), wsi->u.hdr.stash->address, strncpy((char *)&(pt->serv_buf[len]), wsi->u.hdr.stash->address,
context->pt_serv_buf_size - len); context->pt_serv_buf_size - len);
len += strlen(wsi->u.hdr.stash->address); 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 */ /* the port we tell SOCKS proxy to connect to */
pt->serv_buf[len++] = net_buf[0]; pt->serv_buf[len++] = p[0];
pt->serv_buf[len++] = net_buf[1]; pt->serv_buf[len++] = p[1];
/* the length of the address, excluding port */ /* 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; *msg_len = len;
......
...@@ -113,192 +113,98 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi, ...@@ -113,192 +113,98 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
#if defined(LWS_WITH_SOCKS5) #if defined(LWS_WITH_SOCKS5)
/* SOCKS Greeting Reply */ /* SOCKS Greeting Reply */
case LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY: case LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY:
case LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY:
case LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY:
/* handle proxy hung up on us */ /* handle proxy hung up on us */
if (pollfd->revents & LWS_POLLHUP) { if (pollfd->revents & LWS_POLLHUP) {
lwsl_warn("SOCKS connection %p (fd=%d) dead\n", lwsl_warn("SOCKS connection %p (fd=%d) dead\n",
(void *)wsi, pollfd->fd); (void *)wsi, pollfd->fd);
goto bail3;
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
return 0;
} }
n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0); n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
if (n < 0) { if (n < 0) {
if (LWS_ERRNO == LWS_EAGAIN) { if (LWS_ERRNO == LWS_EAGAIN) {
lwsl_debug("SOCKS read returned EAGAIN..." lwsl_debug("SOCKS read EAGAIN, retrying\n");
"retrying\n");
return 0; return 0;
} }
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
lwsl_err("ERROR reading from SOCKS socket\n"); lwsl_err("ERROR reading from SOCKS socket\n");
return 0; goto bail3;
}
/* 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); switch (wsi->mode) {
wsi->mode = conn_mode;
break; case LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY:
/* SOCKS auth Reply */ if (pt->serv_buf[0] != SOCKS_VERSION_5)
case LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY: goto socks_reply_fail;
/* handle proxy hung up on us */
if (pollfd->revents & LWS_POLLHUP) { if (pt->serv_buf[1] == SOCKS_AUTH_NO_AUTH) {
lwsl_client("SOCKS greeting reply: No Auth Method\n");
lwsl_warn("SOCKS connection %p (fd=%d) dead\n", socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len);
(void *)wsi, pollfd->fd); conn_mode = LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY;
pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY;
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); goto socks_send;
return 0; }
}
n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0); if (pt->serv_buf[1] == SOCKS_AUTH_USERNAME_PASSWORD) {
if (n < 0) { lwsl_client("SOCKS greeting reply: User/Pw Method\n");
if (LWS_ERRNO == LWS_EAGAIN) { socks_generate_msg(wsi, SOCKS_MSG_USERNAME_PASSWORD, &len);
lwsl_debug("SOCKS read returned EAGAIN... " conn_mode = LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY;
"retrying\n"); pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY;
return 0; goto socks_send;
} }
goto socks_reply_fail;
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); case LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY:
lwsl_err("ERROR reading from socks socket\n"); if (pt->serv_buf[0] != SOCKS_SUBNEGOTIATION_VERSION_1 ||
return 0; pt->serv_buf[1] != SOCKS_SUBNEGOTIATION_STATUS_SUCCESS)
} goto socks_reply_fail;
/* processing auth reply */ lwsl_client("SOCKS password OK, sending connect\n");
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); socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len);
conn_mode = LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY; conn_mode = LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY;
pending_timeout = pending_timeout = PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY;
PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY; socks_send:
lwsl_client("%s\n", "Sending SOCKS connect command"); n = send(wsi->desc.sockfd, (char *)pt->serv_buf, len,
} MSG_NOSIGNAL);
else if (n < 0) {
{ lwsl_debug("ERROR writing to socks proxy\n");
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); goto bail3;
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;
}
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); lws_set_timeout(wsi, pending_timeout, AWAITING_TIMEOUT);
lwsl_err("ERROR reading from socks socket\n"); wsi->mode = conn_mode;
return 0; break;
}
/* processing connect reply */ socks_reply_fail:
if (pt->serv_buf[0] == SOCKS_VERSION_5 lwsl_notice("socks reply: v%d, err %d\n",
&& pt->serv_buf[1] == SOCKS_REQUEST_REPLY_SUCCESS) pt->serv_buf[0], pt->serv_buf[1]);
{ goto bail3;
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 */ case LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY:
lws_free_set_NULL(wsi->u.hdr.stash); if (pt->serv_buf[0] != SOCKS_VERSION_5 ||
pt->serv_buf[1] != SOCKS_REQUEST_REPLY_SUCCESS)
goto socks_reply_fail;
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, lwsl_client("socks connect OK\n");
wsi->vhost->socks_proxy_address))
goto bail3;
wsi->c_port = wsi->vhost->socks_proxy_port;
/* clear his proxy connection timeout */ /* 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;
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); wsi->c_port = wsi->vhost->socks_proxy_port;
goto start_ws_hanshake; /* clear his proxy connection timeout */
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
goto start_ws_handshake;
}
break;
#endif #endif
case LWSCM_WSCL_WAITING_PROXY_REPLY: case LWSCM_WSCL_WAITING_PROXY_REPLY:
/* handle proxy hung up on us */ /* handle proxy hung up on us */
...@@ -308,8 +214,7 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi, ...@@ -308,8 +214,7 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
lwsl_warn("Proxy connection %p (fd=%d) dead\n", lwsl_warn("Proxy connection %p (fd=%d) dead\n",
(void *)wsi, pollfd->fd); (void *)wsi, pollfd->fd);
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); goto bail3;
return 0;
} }
n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0); 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, ...@@ -318,18 +223,15 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
lwsl_debug("Proxy read returned EAGAIN... retrying\n"); lwsl_debug("Proxy read returned EAGAIN... retrying\n");
return 0; return 0;
} }
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
lwsl_err("ERROR reading from proxy socket\n"); lwsl_err("ERROR reading from proxy socket\n");
return 0; goto bail3;
} }
pt->serv_buf[13] = '\0'; pt->serv_buf[13] = '\0';
if (strcmp(sb, "HTTP/1.0 200 ") && if (strcmp(sb, "HTTP/1.0 200 ") &&
strcmp(sb, "HTTP/1.1 200 ")) { strcmp(sb, "HTTP/1.1 200 ")) {
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
lwsl_err("ERROR proxy: %s\n", sb); lwsl_err("ERROR proxy: %s\n", sb);
return 0; goto bail3;
} }
/* clear his proxy connection timeout */ /* clear his proxy connection timeout */
...@@ -348,7 +250,7 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi, ...@@ -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 * happening at a time when there's no real connection yet
*/ */
#if defined(LWS_WITH_SOCKS5) #if defined(LWS_WITH_SOCKS5)
start_ws_hanshake: start_ws_handshake:
#endif #endif
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
return -1; return -1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment