ESP8266-based WiFi serial modem emulator ROM
0
fork

Configure Feed

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

Socks: Initial work on SOCKS5 proxy support

This will eventually be a port of most of my sockhole Ruby code

+262
+138
SocksClient.cpp
··· 1 + /* 2 + * WiFiPPP 3 + * Copyright (c) 2021 joshua stein <jcs@jcs.org> 4 + * 5 + * Permission to use, copy, modify, and distribute this software for any 6 + * purpose with or without fee is hereby granted, provided that the above 7 + * copyright notice and this permission notice appear in all copies. 8 + * 9 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 + */ 17 + 18 + #include "SocksClient.h" 19 + #include "wifippp.h" 20 + 21 + enum { 22 + STATE_DEAD = 0, 23 + STATE_INIT, 24 + STATE_METHOD, 25 + STATE_REQUEST, 26 + STATE_PROXY, 27 + }; 28 + 29 + #define VERSION_SOCKS5 0x05 30 + 31 + #define METHOD_MIN_LENGTH 3 32 + #define METHOD_AUTH_NONE 0x0 33 + 34 + #define REQUEST_MIN_LENGTH 9 35 + #define REQUEST_COMMAND_CONNECT 0x1 36 + #define REQUEST_ATYP_IP 0x1 37 + #define REQUEST_ATYP_HOSTNAME 0x3 38 + #define REQUEST_ATYP_IP6 0x4 39 + 40 + #define REPLY_SUCCESS 0x0 41 + #define REPLY_FAIL 0x1 42 + #define REPLY_EPERM 0x02 43 + #define REPLY_NET_UNREACHABLE 0x03 44 + #define REPLY_HOST_UNREACHABLE 0x04 45 + #define REPLY_CONN_REFUSED 0x05 46 + #define REPLY_TTL_EXPIRED 0x06 47 + #define REPLY_BAD_COMMAND 0x07 48 + #define REPLY_BAD_ADDRESS 0x08 49 + 50 + SocksClient::~SocksClient() 51 + { 52 + } 53 + 54 + SocksClient::SocksClient(int _slot, WiFiClient _client) 55 + : slot(_slot), client(_client) 56 + { 57 + state = STATE_INIT; 58 + 59 + memset(buf, 0, sizeof(buf)); 60 + buflen = 0; 61 + 62 + syslog.logf(LOG_DEBUG, "[%d] in socks client init with ip %s", slot, 63 + client.remoteIP().toString().c_str()); 64 + } 65 + 66 + bool 67 + SocksClient::done() 68 + { 69 + if (state == STATE_DEAD) 70 + return true; 71 + 72 + if (!client.connected()) 73 + return true; 74 + 75 + return false; 76 + } 77 + 78 + void 79 + SocksClient::process() 80 + { 81 + if (state == STATE_DEAD) 82 + return; 83 + 84 + if (client.available() && sizeof(buf) - buflen > 0) 85 + buflen += client.read(buf + buflen, sizeof(buf) - buflen); 86 + 87 + switch (state) { 88 + case STATE_INIT: 89 + if (buflen >= METHOD_MIN_LENGTH) { 90 + state = STATE_METHOD; 91 + break; 92 + } 93 + break; 94 + case STATE_METHOD: 95 + verify_method(); 96 + break; 97 + } 98 + } 99 + 100 + void 101 + SocksClient::verify_method() 102 + { 103 + if (state != STATE_METHOD) { 104 + syslog.logf(LOG_ERR, "[%d] %s but state %d", slot, __func__, 105 + state); 106 + state = STATE_DEAD; 107 + return; 108 + } 109 + 110 + if (buflen < METHOD_MIN_LENGTH) 111 + return; 112 + 113 + if (buf[0] != VERSION_SOCKS5) { 114 + syslog.logf(LOG_ERR, "[%d] unsupported version 0x%x", slot, 115 + buf[0]); 116 + fail_close(REPLY_FAIL); 117 + return; 118 + } 119 + } 120 + 121 + void 122 + SocksClient::fail_close(char code) 123 + { 124 + unsigned char msg[] = { 125 + VERSION_SOCKS5, 126 + code, 127 + 0, 128 + REQUEST_ATYP_IP, 129 + 0, 0, 0, 0, 130 + 0, 0, 131 + }; 132 + 133 + client.write(msg, sizeof(msg)); 134 + 135 + state = STATE_DEAD; 136 + client.stop(); 137 + server.stop(); 138 + }
+40
SocksClient.h
··· 1 + /* 2 + * WiFiPPP 3 + * Copyright (c) 2021 joshua stein <jcs@jcs.org> 4 + * 5 + * Permission to use, copy, modify, and distribute this software for any 6 + * purpose with or without fee is hereby granted, provided that the above 7 + * copyright notice and this permission notice appear in all copies. 8 + * 9 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 + */ 17 + 18 + #pragma once 19 + 20 + #include <WiFiClient.h> 21 + 22 + class SocksClient : public WiFiClient { 23 + public: 24 + virtual ~SocksClient(); 25 + SocksClient(int _slot, WiFiClient _client); 26 + 27 + bool done(); 28 + void process(); 29 + void verify_method(); 30 + void fail_close(char code); 31 + 32 + int state; 33 + int slot; 34 + WiFiClient client; 35 + WiFiClient server; 36 + 37 + private: 38 + unsigned char buf[64]; 39 + size_t buflen; 40 + };
+76
socks.cpp
··· 1 + /* 2 + * WiFiPPP 3 + * Copyright (c) 2021 joshua stein <jcs@jcs.org> 4 + * 5 + * Permission to use, copy, modify, and distribute this software for any 6 + * purpose with or without fee is hereby granted, provided that the above 7 + * copyright notice and this permission notice appear in all copies. 8 + * 9 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 + */ 17 + 18 + #include "wifippp.h" 19 + #include <WiFiClient.h> 20 + #include <WiFiServer.h> 21 + #include "SocksClient.h" 22 + 23 + WiFiServer socks_server(1080); 24 + 25 + #define MAX_SOCKS_CLIENTS 5 26 + SocksClient *socks_clients[MAX_SOCKS_CLIENTS] = { nullptr }; 27 + 28 + void 29 + socks_setup(void) 30 + { 31 + socks_server.begin(); 32 + } 33 + 34 + void 35 + socks_process(void) 36 + { 37 + int i; 38 + 39 + if (socks_server.hasClient()) { 40 + int slot = -1; 41 + 42 + for (i = 0; i < MAX_SOCKS_CLIENTS; i++) { 43 + if (!socks_clients[i] || socks_clients[i]->done()) { 44 + if (socks_clients[i]) 45 + delete socks_clients[i]; 46 + slot = i; 47 + break; 48 + } 49 + } 50 + 51 + syslog.logf(LOG_DEBUG, "new SOCKS client, slot %d", slot); 52 + 53 + if (slot > -1) { 54 + WiFiClient client = socks_server.available(); 55 + if (client.connected()) 56 + socks_clients[slot] = new SocksClient(slot, 57 + client); 58 + else 59 + syslog.logf(LOG_ERR, "found slot %d for new " 60 + "connection but not connected", slot); 61 + } 62 + } 63 + 64 + for (i = 0; i < MAX_SOCKS_CLIENTS; i++) { 65 + if (!socks_clients[i]) 66 + continue; 67 + 68 + if (socks_clients[i]->done()) { 69 + delete socks_clients[i]; 70 + socks_clients[i] = nullptr; 71 + continue; 72 + } 73 + 74 + socks_clients[i]->process(); 75 + } 76 + }
+2
util.cpp
··· 80 80 WiFi.disconnect(); 81 81 else 82 82 WiFi.begin(settings->wifi_ssid, settings->wifi_pass); 83 + 84 + socks_setup(); 83 85 } 84 86 85 87 void
+4
wifippp.h
··· 66 66 bool ppp_start(void); 67 67 void ppp_process(void); 68 68 69 + /* socks.cpp */ 70 + void socks_setup(void); 71 + void socks_process(void); 72 + 69 73 /* telnet.cpp */ 70 74 int telnet_connect(char *host, uint16_t port); 71 75 bool telnet_connected(void);
+2
wifippp.ino
··· 32 32 int b = -1, i; 33 33 long now = millis(); 34 34 35 + socks_process(); 36 + 35 37 switch (state) { 36 38 case STATE_AT: 37 39 if (Serial.available() && (b = Serial.read()))