From 74c5c70ea3056c39c92263b9570da059e416f7f2 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Sun, 18 Mar 2018 11:05:00 +0100 Subject: [PATCH] Stripped unused ACL functionality --- firmware/0x00000.bin | Bin 37696 -> 35360 bytes firmware/0x10000.bin | Bin 232548 -> 229988 bytes user/acl.c | 310 ------------------------------------------- user/acl.h | 51 ------- user/config_flash.c | 100 +------------- user/config_flash.h | 5 - user/user_config.h | 5 - user/user_main.c | 273 ------------------------------------- 8 files changed, 1 insertion(+), 743 deletions(-) delete mode 100644 user/acl.c delete mode 100644 user/acl.h diff --git a/firmware/0x00000.bin b/firmware/0x00000.bin index 7f4a3e9aa2abcd25c870e01c38e5cb70010f3b8a..d8ca52edab94e5aafc835fba11da54e06f81014c 100644 GIT binary patch delta 4680 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 YLJ}ale87L_yZDcbUgvpxI`7~97iKMLjQ{`u delta 7029 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 diff --git a/firmware/0x10000.bin b/firmware/0x10000.bin index 7532e7a70f6958909a12099eb36a4dc3c9bb6cf5..b8fa86632360489e7eb491c7a10dd8755c5a5de6 100644 GIT binary patch delta 25736 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 a6HhMT4Nj8vCz+9EN@V?sdsp#e^8WxSNSe$5 delta 28349 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 MAX_NO_ACLS) - { - return true; - } - return acl_freep[acl_no] == 0; -} - -void ICACHE_FLASH_ATTR -acl_clear(uint8_t acl_no) -{ - if (acl_no >= MAX_NO_ACLS) - { - return; - } - acl_freep[acl_no] = 0; - acl_clear_stats(acl_no); -} - -void ICACHE_FLASH_ATTR -acl_clear_stats(uint8_t acl_no) -{ - int i; - - if (acl_no >= MAX_NO_ACLS) - { - return; - } - my_deny_cb = NULL; - for(i=0; i< MAX_ACL_ENTRIES; i++) - acl[acl_no][i].hit_count = 0; -} - -bool ICACHE_FLASH_ATTR -acl_add(uint8_t acl_no, - uint32_t src, - uint32_t s_mask, - uint32_t dest, - uint32_t d_mask, - uint8_t proto, - uint16_t s_port, - uint16_t d_port, - uint8_t allow) -{ - acl_entry *my_entry; - - if (acl_no >= MAX_NO_ACLS || acl_freep[acl_no] >= MAX_ACL_ENTRIES) - { - return false; - } - - my_entry = &acl[acl_no][acl_freep[acl_no]]; - my_entry->src = src & s_mask; - my_entry->s_mask = s_mask; - my_entry->dest = dest & d_mask; - my_entry->d_mask = d_mask; - my_entry->proto = proto; - my_entry->s_port = s_port; - my_entry->d_port = d_port; - my_entry->allow = allow; - my_entry->hit_count = 0; - - acl_freep[acl_no]++; - return true; -} - -uint8_t ICACHE_FLASH_ATTR -acl_check_packet(uint8_t acl_no, struct pbuf *p) -{ - struct eth_hdr *mac_h; - struct ip_hdr *ip_h; - uint8_t proto; - struct udp_hdr *udp_h; - struct tcp_hdr *tcp_h; - uint16_t src_port, dest_port; - uint8_t *packet; - int i; - acl_entry *my_entry; - uint8_t allow; - - if (acl_no >= MAX_NO_ACLS) - { - return ACL_DENY; - } - - if (p->len < sizeof(struct eth_hdr)) - { - return ACL_DENY; - } - - mac_h = (struct eth_hdr *)p->payload; - - // Allow ARP - if (ntohs(mac_h->type) == ETHTYPE_ARP) - { - acl_allow_count++; - return ACL_ALLOW; - } - - // Drop anything else if not IPv4 - if (ntohs(mac_h->type) != ETHTYPE_IP) - { - acl_deny_count++; - return ACL_DENY; - } - - if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)) - { - acl_deny_count++; - return ACL_DENY; - } - - allow = ACL_DENY; - packet = (uint8_t*)p->payload; - ip_h = (struct ip_hdr *)&packet[sizeof(struct eth_hdr)]; - proto = IPH_PROTO(ip_h); - - switch (proto) { - case IP_PROTO_UDP: - { - if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct udp_hdr)) - { - return; - } - udp_h = (struct udp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)]; - src_port = ntohs(udp_h->src); - dest_port = ntohs(udp_h->dest); - } break; - - case IP_PROTO_TCP: - { - if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct tcp_hdr)) - { - return; - } - tcp_h = (struct tcp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)]; - src_port = ntohs(tcp_h->src); - dest_port = ntohs(tcp_h->dest); - } break; - - case IP_PROTO_ICMP: - { - src_port = dest_port = 0; - } break; - - // Drop anything that is not UDP, TCP, or ICMP - default: - { - acl_deny_count++; - return ACL_DENY; - } break; - } - - // os_printf("Src: %d.%d.%d.%d Dst: %d.%d.%d.%d Proto: %s SP:%d DP:%d\n", - // IP2STR(&ip_h->src), IP2STR(&ip_h->dest), - // proto==IP_PROTO_TCP?"TCP":proto==IP_PROTO_UDP?"UDP":"IP4", src_port, dest_port); - - for(i=0; iproto == 0 || proto == my_entry->proto) && - (my_entry->src == 0 || my_entry->src == (ip_h->src.addr&my_entry->s_mask)) && - (my_entry->dest == 0 || my_entry->dest == (ip_h->dest.addr&my_entry->d_mask)) && - (my_entry->s_port == 0 || my_entry->s_port == src_port) && - (my_entry->d_port == 0 || my_entry->d_port == dest_port)) - { - allow = my_entry->allow; - my_entry->hit_count++; - goto done; - } - } - -done: - if (!(allow & ACL_ALLOW) && my_deny_cb != NULL) - { - allow = my_deny_cb(proto, ip_h->src.addr, src_port, - ip_h->dest.addr, dest_port, allow); - } - if (allow & ACL_ALLOW) - { - acl_allow_count++; - } - else - { - acl_deny_count++; - } - - // os_printf(" allow: %d\r\n", allow); - return allow; -} - -void -acl_set_deny_cb(packet_deny_cb cb) -{ - my_deny_cb = cb; -} - -void ICACHE_FLASH_ATTR -addr2str(uint8_t *buf, uint32_t addr, uint32_t mask) -{ - uint8_t clidr; - - if (addr == 0) - { - os_sprintf(buf, "any"); - return; - } - - mask = ntohl(mask); - for (clidr = 0; mask; mask <<= 1,clidr++); - if (clidr < 32) - { - os_sprintf(buf, "%d.%d.%d.%d/%d", IP2STR((ip_addr_t*)&addr), clidr); - } - else - { - os_sprintf(buf, "%d.%d.%d.%d", IP2STR((ip_addr_t*)&addr)); - } -} - -void ICACHE_FLASH_ATTR -port2str(uint8_t *buf, uint16_t port) -{ - if (port == 0) - { - os_sprintf(buf, "any"); - } - else - { - os_sprintf(buf, "%d", port); - } -} - -void ICACHE_FLASH_ATTR -acl_show(uint8_t acl_no, uint8_t *buf) -{ - int i; - acl_entry *my_entry; - uint8_t line[80], addr1[21], addr2[21], port1[6], port2[6]; - - buf[0] = 0; - - if (acl_no >= MAX_NO_ACLS) - { - return; - } - - for(i = 0; i < acl_freep[acl_no]; i++) - { - my_entry = &acl[acl_no][i]; - addr2str(addr1, my_entry->src, my_entry->s_mask); - port2str(port1, my_entry->s_port); - addr2str(addr2, my_entry->dest, my_entry->d_mask); - port2str(port2, my_entry->d_port); - if (my_entry->proto != 0) - { - os_sprintf(line, "%s %s:%s %s:%s %s%s (%d hits)\r\n", - my_entry->proto==IP_PROTO_TCP?"TCP":"UDP", - addr1, port1, addr2, port2, - (my_entry->allow & ACL_ALLOW)?"allow":"deny", - (my_entry->allow & ACL_MONITOR)?"_monitor":"", - my_entry->hit_count); - } - else - { - os_sprintf(line, "IP %s %s %s%s (%d hits)\r\n", - addr1, addr2, - (my_entry->allow & ACL_ALLOW)?"allow":"deny", - (my_entry->allow & ACL_MONITOR)?"_monitor":"", - my_entry->hit_count); - } - os_memcpy(&buf[os_strlen(buf)], line, os_strlen(line)+1); - } -} diff --git a/user/acl.h b/user/acl.h deleted file mode 100644 index 59f8859..0000000 --- a/user/acl.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _ACL_H_ -#define _ACL_H_ - -#include "lwip/ip.h" -#include "lwip/pbuf.h" - -#define MAX_NO_ACLS 4 -#define MAX_ACL_ENTRIES 30 - -#define ACL_DENY 0x0 -#define ACL_ALLOW 0x1 -#define ACL_MONITOR 0x2 - -typedef struct _acl_entry -{ - uint32_t src; - uint32_t s_mask; - uint32_t dest; - uint32_t d_mask; - uint16_t s_port; - uint16_t d_port; - uint8_t proto; - uint8_t allow; - uint32_t hit_count; -} acl_entry; - -extern acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES]; -extern uint8_t acl_freep[MAX_NO_ACLS]; -extern uint32_t acl_allow_count; -extern uint32_t acl_deny_count; - -typedef uint8_t (*packet_deny_cb)(uint8_t proto, uint32_t saddr, uint16_t s_port, uint32_t daddr, uint16_t d_port, uint8_t allow); - -void acl_init(); -bool acl_is_empty(uint8_t acl_no); -void acl_clear(uint8_t acl_no); -void acl_clear_stats(uint8_t acl_no); -bool acl_add(uint8_t acl_no, - uint32_t src, - uint32_t s_mask, - uint32_t dest, - uint32_t d_mask, - uint8_t proto, - uint16_t s_port, - uint16_t d_port, - uint8_t allow); -uint8_t acl_check_packet(uint8_t acl_no, struct pbuf *p); -void acl_set_deny_cb(packet_deny_cb cb); -void acl_show(uint8_t acl_no, uint8_t *buf); - -#endif /* _ACL_H_ */ diff --git a/user/config_flash.c b/user/config_flash.c index 96152d4..0af7b51 100644 --- a/user/config_flash.c +++ b/user/config_flash.c @@ -45,9 +45,6 @@ config_load_default(sysconfig_p config) wifi_get_macaddr(STATION_IF, config->STA_MAC_address); config->dhcps_entries = 0; -#ifdef ACLS - acl_init(); // initializes the ACLs, written in config during save -#endif config->current_mac_address = 0; // Interval to change mac address in seconds @@ -73,94 +70,6 @@ config_load_default(sysconfig_p config) ets_str2macaddr(config->mac_list[13], "4E:53:50:4F:4F:4D"); ets_str2macaddr(config->mac_list[14], "4E:53:50:4F:4F:4E"); ets_str2macaddr(config->mac_list[15], "4E:53:50:4F:4F:4F"); - - // Streetpass relay whitelist - uint32_t daddr; - uint32_t dmask; - - // Clear all acl rules - acl_clear(0); - acl_clear(1); - acl_clear(2); - acl_clear(3); - - // Whitelist broadcast to enable DHCP - parse_IP_addr("255.255.255.255", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - // Whitelist DNS - acl_add(0, 0, 0, 0, 0, IP_PROTO_UDP, 0, 53, ACL_ALLOW); - - // Whitelist Streetpass relays - // acl from_sta IP any 52.43.174.40 allow - parse_IP_addr("52.43.174.40", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("104.70.153.178", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("104.74.48.110", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("23.7.18.146", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("23.7.24.35", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("52.11.210.152", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("52.25.179.65", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("52.89.56.205", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("54.148.137.96", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("54.218.98.74", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("54.218.99.79", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("54.244.22.201", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("69.25.139.140", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("192.195.204.216", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("52.10.249.207", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - // NOTE(m): New IP addresses found by Dal78 - // NOTE(m): The list of Streetpass IP addresses may be dynamic :-/ - parse_IP_addr("52.24.183.161", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("52.39.19.157", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("34.208.213.200", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("104.103.189.191", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("23.2.226.76", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - parse_IP_addr("35.167.248.201", &daddr, &dmask); - acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW); - - // Default implementation denies everything not matched above. - // This last rule is not necessary and commented out to save memory space: - // acl_add(0, 0, 0, 0, 0, 0, 0, 0, ACL_DENY); } int @@ -193,10 +102,7 @@ config_load(sysconfig_p config) config_save(config); return -1; } -#ifdef ACLS - os_memcpy(&acl, &(config->acl), sizeof(acl)); - os_memcpy(&acl_freep, &(config->acl_freep), sizeof(acl_freep)); -#endif + return 0; } @@ -204,10 +110,6 @@ void config_save(sysconfig_p config) { uint16_t base_address = FLASH_BLOCK_NO; -#ifdef ACLS - os_memcpy(&(config->acl), &acl, sizeof(acl)); - os_memcpy(&(config->acl_freep), &acl_freep, sizeof(acl_freep)); -#endif os_printf("Saving configuration\r\n"); spi_flash_erase_sector(base_address); spi_flash_write(base_address * SPI_FLASH_SEC_SIZE, diff --git a/user/config_flash.h b/user/config_flash.h index bd920aa..7e31b55 100644 --- a/user/config_flash.h +++ b/user/config_flash.h @@ -11,7 +11,6 @@ #include "lwip/app/dhcpserver.h" #include "user_config.h" -#include "acl.h" #define FLASH_BLOCK_NO 0xc @@ -60,10 +59,6 @@ typedef struct uint16_t dhcps_entries; // number of allocated entries in the following table struct dhcps_pool dhcps_p[MAX_DHCP]; // DHCP entries -#ifdef ACLS - acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES]; // ACL entries - uint8_t acl_freep[MAX_NO_ACLS]; // ACL free pointers -#endif // HomePass mac list // Allow 20 slots diff --git a/user/user_config.h b/user/user_config.h index 19287e3..d58f160 100644 --- a/user/user_config.h +++ b/user/user_config.h @@ -27,11 +27,6 @@ // #define PHY_MODE 1 -// -// Define this if you want to have ACLs for the SoftAP. -// -#define ACLS 1 - // Internal typedef enum {SIG_DO_NOTHING=0, SIG_START_SERVER=1, SIG_SEND_DATA, SIG_UART0, SIG_CONSOLE_RX, SIG_CONSOLE_TX, SIG_CONSOLE_TX_RAW, SIG_GPIO_INT} USER_SIGNALS; diff --git a/user/user_main.c b/user/user_main.c index 89b5b09..ac563ce 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -23,10 +23,6 @@ #include "easygpio.h" -#ifdef ACLS -#include "acl.h" -#endif - /* System Task, for signals refer to user_config.h */ #define user_procTaskPrio 0 #define user_procTaskQueueLen 1 @@ -83,24 +79,6 @@ my_input_ap(struct pbuf *p, struct netif *inp) client_watchdog_cnt = config.client_watchdog; -#ifdef ACLS - // Check ACLs - store result - uint8_t acl_check = ACL_ALLOW; - if (!acl_is_empty(0)) - { - acl_check = acl_check_packet(0, p); - } -#endif - -#ifdef ACLS - // If not allowed, drop packet - if (!(acl_check&ACL_ALLOW)) - { - pbuf_free(p); - return; - } -#endif - Bytes_in += p->tot_len; Packets_in++; @@ -117,24 +95,6 @@ my_output_ap(struct netif *outp, struct pbuf *p) easygpio_outputSet (config.status_led, 0); } -#ifdef ACLS - // Check ACLs - store result - uint8_t acl_check = ACL_ALLOW; - if (!acl_is_empty(1)) - { - acl_check = acl_check_packet(1, p); - } -#endif - -#ifdef ACLS - // If not allowed, drop packet - if (!(acl_check&ACL_ALLOW)) - { - pbuf_free(p); - return; - } -#endif - Bytes_out += p->tot_len; Packets_out++; @@ -145,26 +105,12 @@ err_t ICACHE_FLASH_ATTR my_input_sta(struct pbuf *p, struct netif *inp) { ap_watchdog_cnt = config.ap_watchdog; -#ifdef ACLS - if (!acl_is_empty(2) && !(acl_check_packet(2, p) & ACL_ALLOW)) - { - pbuf_free(p); - return; - } -#endif orig_input_sta (p, inp); } err_t ICACHE_FLASH_ATTR my_output_sta(struct netif *outp, struct pbuf *p) { -#ifdef ACLS - if (!acl_is_empty(3) && !(acl_check_packet(3, p) & ACL_ALLOW)) - { - pbuf_free(p); - return; - } -#endif orig_output_sta (outp, p); } @@ -304,67 +250,6 @@ console_send_response(struct espconn *pespconn, uint8_t do_cmd) } } - -#ifdef ACLS -void ICACHE_FLASH_ATTR -parse_IP_addr(uint8_t *str, uint32_t *addr, uint32_t *mask) -{ - int i; - uint32_t net; - if (strcmp(str, "any") == 0) - { - *addr = 0; - *mask = 0; - return; - } - - for(i=0; str[i]!=0 && str[i]!='/'; i++); - - *mask = 0xffffffff; - if (str[i]!=0) - { - str[i]=0; - *mask <<= (32 - atoi(&str[i+1])); - } - *mask = htonl(*mask); - *addr = ipaddr_addr(str); -} - -struct espconn *deny_cb_conn = 0; -uint8_t acl_debug = 0; - -uint8_t -acl_deny_cb(uint8_t proto, - uint32_t saddr, - uint16_t s_port, - uint32_t daddr, - uint16_t d_port, - uint8_t allow) -{ - char response[128]; - - if (!acl_debug) - { - return allow; - } - - os_sprintf(response, - "\rdeny: %s Src: %d.%d.%d.%d:%d Dst: %d.%d.%d.%d:%d\r\n", - proto==IP_PROTO_TCP?"TCP":proto==IP_PROTO_UDP?"UDP":"IP4", - IP2STR((ip_addr_t *)&saddr), - s_port, - IP2STR((ip_addr_t *)&daddr), - d_port); - - if (acl_debug) - { - to_console(response); - system_os_post(0, SIG_CONSOLE_TX, (ETSParam) deny_cb_conn); - } - return allow; -} -#endif /* ACLS */ - // Use this from ROM instead int ets_str2macaddr(uint8 *mac, char *str_mac); #define parse_mac ets_str2macaddr @@ -431,10 +316,6 @@ console_handle_command(struct espconn *pespconn) to_console(response); #endif -#ifdef ACLS - os_sprintf(response, "acl [from_sta|to_sta|from_ap|to_ap] clear\r\nacl [from_sta|to_sta|from_ap|to_ap] [IP|TCP|UDP] [] [] [allow|deny|allow_monitor|deny_monitor]\r\n"); - to_console(response); -#endif goto command_handled_2; } @@ -579,144 +460,8 @@ console_handle_command(struct espconn *pespconn) } goto command_handled_2; } -#ifdef ACLS - if (nTokens == 2 && strcmp(tokens[1], "acl") == 0) - { - char *txt[] = {"From STA:\r\n", - "To STA:\r\n", "From AP:\r\n", "To AP:\r\n"}; - for (i = 0; i 1) @@ -947,15 +692,6 @@ console_handle_command(struct espconn *pespconn) goto command_handled; } -#ifdef ACLS - if (strcmp(tokens[1], "acl_debug") == 0) - { - acl_debug = atoi(tokens[2]); - os_sprintf(response, "ACL debug set\r\n"); - goto command_handled; - } -#endif - if (strcmp(tokens[1], "speed") == 0) { uint16_t speed = atoi(tokens[2]); @@ -1478,15 +1214,6 @@ user_init() // Load config config_load(&config); -#ifdef ACLS - acl_debug = 0; - int i; - for(i=0; i< MAX_NO_ACLS; i++) - { - acl_clear_stats(i); - } - acl_set_deny_cb(acl_deny_cb); -#endif // Config GPIO pin as output if (config.status_led == 1) {