ESP8266-based WiFi serial modem emulator ROM
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Socks: Finish proxying implementation

+216 -26
+197 -23
SocksClient.cpp
··· 27 27 STATE_PROXY, 28 28 }; 29 29 30 + unsigned int tls_ports[] = { 31 + 443, /* https */ 32 + 993, /* imaps */ 33 + 995, /* pop3s */ 34 + }; 35 + 30 36 /* https://datatracker.ietf.org/doc/html/rfc1928 */ 31 37 32 38 #define VERSION_SOCKS5 0x05 ··· 53 59 54 60 SocksClient::~SocksClient() 55 61 { 62 + client_in.stop(); 63 + if (tls()) 64 + client_out_tls.stop(); 65 + else 66 + client_out.stop(); 56 67 } 57 68 58 69 SocksClient::SocksClient(int _slot, WiFiClient _client) 59 - : slot(_slot), client(_client) 70 + : slot(_slot), client_in(_client) 60 71 { 61 72 state = STATE_INIT; 62 73 63 74 memset(buf, 0, sizeof(buf)); 64 75 buflen = 0; 76 + remote_port = 0; 77 + ip4_addr_set_zero(&remote_ip); 78 + _tls = false; 65 79 80 + #ifdef SOCKS_TRACE 66 81 syslog.logf(LOG_DEBUG, "[%d] in socks client init with ip %s", slot, 67 - client.remoteIP().toString().c_str()); 82 + client_in.remoteIP().toString().c_str()); 83 + #endif 68 84 } 69 85 70 86 bool 71 87 SocksClient::done() 72 88 { 73 - if (state == STATE_DEAD) 74 - return true; 89 + return (state == STATE_DEAD); 90 + } 75 91 76 - if (!client.connected()) 77 - return true; 78 - 79 - return false; 92 + void 93 + SocksClient::finish() 94 + { 95 + state = STATE_DEAD; 80 96 } 81 97 82 98 void 83 99 SocksClient::process() 84 100 { 85 - if (state == STATE_DEAD) 101 + switch (state) { 102 + case STATE_DEAD: 86 103 return; 87 - 88 - if (client.available() && sizeof(buf) - buflen > 0) 89 - buflen += client.read(buf + buflen, sizeof(buf) - buflen); 104 + case STATE_INIT: 105 + case STATE_METHOD: 106 + case STATE_REQUEST: 107 + if (client_in.available() && sizeof(buf) - buflen > 0) 108 + buflen += client_in.read(buf + buflen, 109 + sizeof(buf) - buflen); 110 + break; 111 + default: 112 + /* proxy() will do its own buffering */ 113 + break; 114 + } 90 115 91 116 switch (state) { 92 117 case STATE_INIT: ··· 100 125 break; 101 126 case STATE_REQUEST: 102 127 handle_request(); 128 + break; 129 + case STATE_CONNECT: 130 + connect(); 131 + break; 132 + case STATE_PROXY: 133 + proxy(); 103 134 break; 104 135 } 105 136 } ··· 116 147 0, 0, 117 148 }; 118 149 119 - client.write(msg, sizeof(msg)); 150 + client_in.write(msg, sizeof(msg)); 120 151 121 - state = STATE_DEAD; 122 - client.stop(); 123 - server.stop(); 152 + finish(); 124 153 } 125 154 126 155 bool ··· 172 201 METHOD_AUTH_NONE, 173 202 }; 174 203 175 - client.write(msg, sizeof(msg)); 204 + client_in.write(msg, sizeof(msg)); 176 205 state = STATE_REQUEST; 177 206 buflen = 0; 178 207 return; ··· 185 214 VERSION_SOCKS5, 186 215 METHOD_AUTH_BAD, 187 216 }; 188 - client.write(msg, sizeof(msg)); 217 + client_in.write(msg, sizeof(msg)); 189 218 fail_close(REPLY_FAIL); 190 219 } 191 220 ··· 219 248 remote_port = (uint16_t)((buf[8] & 0xff) << 8) | 220 249 (buf[9] & 0xff); 221 250 251 + #ifdef SOCKS_TRACE 222 252 syslog.logf(LOG_DEBUG, "[%d] CONNECT request to IP %s:%d", 223 253 slot, ipaddr_ntoa(&remote_ip), remote_port); 254 + #endif 224 255 225 256 break; 226 257 case REQUEST_ATYP_HOSTNAME: { ··· 258 289 return; 259 290 } 260 291 292 + ip4_addr_set_u32(&remote_ip, resip.v4()); 293 + 294 + #ifdef SOCKS_TRACE 261 295 syslog.logf(LOG_DEBUG, "[%d] CONNECT request to hostname " 262 296 "%s:%d, resolved to IP %s", slot, remote_hostname, 263 - remote_port, ipaddr_ntoa(resip)); 264 - 265 - // e.g., curl --preproxy socks5h://1.2.3.4 ... 297 + remote_port, ipaddr_ntoa(&remote_ip)); 298 + #endif 266 299 break; 267 300 } 268 301 case REQUEST_ATYP_IP6: ··· 278 311 279 312 switch (buf[1]) { 280 313 case REQUEST_COMMAND_CONNECT: 281 - // do_connect 282 314 state = STATE_CONNECT; 283 - break; 315 + return; 284 316 default: 285 317 syslog.logf(LOG_ERR, "[%d] unsupported command 0x%x", 286 318 slot, buf[1]); ··· 288 320 return; 289 321 } 290 322 } 323 + 324 + void 325 + SocksClient::connect() 326 + { 327 + bool ret; 328 + 329 + _tls = false; 330 + 331 + if (!verify_state(STATE_CONNECT)) 332 + return; 333 + 334 + if (remote_port == 0 || ip4_addr_isany_val(remote_ip)) { 335 + syslog.logf(LOG_ERR, "[%d] bogus ip/port %s:%d", 336 + slot, ipaddr_ntoa(&remote_ip), remote_port); 337 + fail_close(REPLY_BAD_ADDRESS); 338 + return; 339 + } 340 + 341 + for (size_t i = 0; i < sizeof(tls_ports) / sizeof(tls_ports[0]); i++) { 342 + if (remote_port == tls_ports[i]) { 343 + _tls = true; 344 + break; 345 + } 346 + } 347 + 348 + if (tls()) { 349 + client_out_tls.setInsecure(); 350 + ret = client_out_tls.connect(remote_ip, remote_port); 351 + } else 352 + ret = client_out.connect(remote_ip, remote_port); 353 + 354 + if (!ret) { 355 + syslog.logf(LOG_WARNING, "[%d] connection to %s:%d%s failed", 356 + slot, ipaddr_ntoa(&remote_ip), remote_port, 357 + (tls() ? " (TLS decrypt)" : "")); 358 + fail_close(REPLY_CONN_REFUSED); 359 + return; 360 + } 361 + 362 + unsigned char msg[] = { 363 + VERSION_SOCKS5, REPLY_SUCCESS, 0, REQUEST_ATYP_IP, 364 + ip4_addr1(&remote_ip), ip4_addr2(&remote_ip), 365 + ip4_addr3(&remote_ip), ip4_addr4(&remote_ip), 366 + (unsigned char)((remote_port >> 8) & 0xff), 367 + (unsigned char)(remote_port & 0xff) 368 + }; 369 + 370 + buflen = 0; 371 + client_in.write(msg, sizeof(msg)); 372 + state = STATE_PROXY; 373 + } 374 + 375 + #ifdef SOCKS_TRACE 376 + void 377 + SocksClient::dump_buf(size_t len) 378 + { 379 + char tbuf[(64 * 3) + 1]; 380 + size_t tbufl = 0; 381 + 382 + if (len > 64) 383 + len = 64; 384 + 385 + for (size_t i = 0; i < len; i++) { 386 + sprintf(tbuf + tbufl, " %02x", buf[i]); 387 + tbufl += 3; 388 + } 389 + 390 + syslog.logf(LOG_DEBUG, "[%d] %s", slot, tbuf); 391 + } 392 + #endif 393 + 394 + void 395 + SocksClient::proxy() 396 + { 397 + size_t len; 398 + 399 + if (!verify_state(STATE_PROXY)) 400 + return; 401 + 402 + /* 403 + * Process buffers before checking connection, we may have read some 404 + * before the client closed. 405 + */ 406 + while (client_in.available()) { 407 + len = client_in.read(buf, sizeof(buf)); 408 + #ifdef SOCKS_TRACE 409 + syslog.logf(LOG_DEBUG, "[%d] read %d bytes from client in, " 410 + "sending to client out %s", slot, len, 411 + (tls() ? "tls" : "")); 412 + dump_buf(len); 413 + #endif 414 + if (tls()) 415 + client_out_tls.write(buf, len); 416 + else 417 + client_out.write(buf, len); 418 + } 419 + 420 + if (tls()) { 421 + while (client_out_tls.available()) { 422 + len = client_out_tls.read(buf, sizeof(buf)); 423 + #ifdef SOCKS_TRACE 424 + syslog.logf(LOG_DEBUG, "[%d] read %d bytes from " 425 + "client out tls, sending to client in", 426 + slot, len); 427 + dump_buf(len); 428 + #endif 429 + client_in.write(buf, len); 430 + } 431 + } else { 432 + while (client_out.available()) { 433 + len = client_out.read(buf, sizeof(buf)); 434 + #ifdef SOCKS_TRACE 435 + syslog.logf(LOG_DEBUG, "[%d] read %d bytes from " 436 + "client out, sending to client in", slot, len); 437 + dump_buf(len); 438 + #endif 439 + client_in.write(buf, len); 440 + } 441 + } 442 + 443 + if (!client_in.connected()) { 444 + #ifdef SOCKS_TRACE 445 + syslog.logf(LOG_DEBUG, "[%d] client in closed", slot); 446 + #endif 447 + finish(); 448 + return; 449 + } 450 + 451 + if (tls() && !client_out_tls.connected()) { 452 + #ifdef SOCKS_TRACE 453 + syslog.logf(LOG_DEBUG, "[%d] client out tls closed", slot); 454 + #endif 455 + finish(); 456 + return; 457 + } else if (!tls() && !client_out.connected()) { 458 + #ifdef SOCKS_TRACE 459 + syslog.logf(LOG_DEBUG, "[%d] client out closed", slot); 460 + #endif 461 + finish(); 462 + return; 463 + } 464 + }
+13 -2
SocksClient.h
··· 18 18 #pragma once 19 19 20 20 #include <WiFiClient.h> 21 + #include <WiFiClientSecure.h> 22 + 23 + // #define SOCKS_TRACE 21 24 22 25 class SocksClient : public WiFiClient { 23 26 public: ··· 27 30 bool done(); 28 31 void process(); 29 32 33 + bool tls() { return _tls; }; 30 34 int state; 31 35 int slot; 32 - WiFiClient client; 33 - WiFiClient server; 36 + WiFiClient client_in; 37 + WiFiClient client_out; 38 + WiFiClientSecure client_out_tls; 34 39 35 40 private: 36 41 void verify_method(); ··· 38 43 bool verify_version(); 39 44 void handle_request(); 40 45 void fail_close(char code); 46 + void connect(); 47 + void proxy(); 48 + void finish(); 49 + 50 + void dump_buf(size_t len); 41 51 42 52 unsigned char buf[64]; 43 53 unsigned char *remote_hostname; 44 54 ip4_addr_t remote_ip; 45 55 uint16_t remote_port; 56 + bool _tls; 46 57 47 58 size_t buflen; 48 59 };
+4 -1
socks.cpp
··· 20 20 #include <WiFiServer.h> 21 21 #include "SocksClient.h" 22 22 23 - WiFiServer socks_server(1080); 23 + #define SOCKS_PORT 1080 24 + 25 + WiFiServer socks_server(SOCKS_PORT); 24 26 25 27 #define MAX_SOCKS_CLIENTS 5 26 28 SocksClient *socks_clients[MAX_SOCKS_CLIENTS] = { nullptr }; ··· 28 30 void 29 31 socks_setup(void) 30 32 { 33 + socks_server = WiFiServer(settings->ppp_server_ip, SOCKS_PORT); 31 34 socks_server.begin(); 32 35 } 33 36
+2
wifippp.ino
··· 438 438 439 439 ip_addr_copy(settings->ppp_server_ip, t_addr); 440 440 output("OK\r\n"); 441 + /* re-bind to the new ip */ 442 + socks_setup(); 441 443 } else if (strcmp(lcmd, "at$ppps?") == 0) { 442 444 /* AT$PPPS?: print PPP server IP */ 443 445 ip4_addr_t t_addr;