mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	This reverts commit c693c219f4.
			
			
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							0e5e559283
						
					
				
				
					commit
					ec026ab3a8
				
			| @@ -1,6 +1,3 @@ | ||||
| import logging | ||||
| from cryptography.hazmat.primitives.asymmetric import rsa, ec, ed448, ed25519 | ||||
|  | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome import automation | ||||
| @@ -8,15 +5,12 @@ from esphome.automation import Condition | ||||
| from esphome.const import CONF_AP, CONF_BSSID, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \ | ||||
|     CONF_FAST_CONNECT, CONF_GATEWAY, CONF_HIDDEN, CONF_ID, CONF_MANUAL_IP, CONF_NETWORKS, \ | ||||
|     CONF_PASSWORD, CONF_POWER_SAVE_MODE, CONF_REBOOT_TIMEOUT, CONF_SSID, CONF_STATIC_IP, \ | ||||
|     CONF_SUBNET, CONF_USE_ADDRESS, CONF_PRIORITY, CONF_IDENTITY, CONF_CERTIFICATE_AUTHORITY, \ | ||||
|     CONF_CERTIFICATE, CONF_KEY, CONF_USERNAME, CONF_EAP | ||||
|     CONF_SUBNET, CONF_USE_ADDRESS, CONF_PRIORITY | ||||
| from esphome.core import CORE, HexInt, coroutine_with_priority | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| AUTO_LOAD = ['network'] | ||||
|  | ||||
| wifi_ns = cg.esphome_ns.namespace('wifi') | ||||
| EAPAuth = wifi_ns.struct('EAPAuth') | ||||
| IPAddress = cg.global_ns.class_('IPAddress') | ||||
| ManualIP = wifi_ns.struct('ManualIP') | ||||
| WiFiComponent = wifi_ns.class_('WiFiComponent', cg.Component) | ||||
| @@ -42,55 +36,6 @@ def validate_password(value): | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def validate_eap(value): | ||||
|     if CONF_USERNAME in value: | ||||
|         if CONF_IDENTITY not in value: | ||||
|             _LOGGER.info("EAP 'identity:' is not set, assuming username.") | ||||
|             value[CONF_IDENTITY] = value[CONF_USERNAME] | ||||
|         if CONF_PASSWORD not in value: | ||||
|             raise cv.Invalid("You cannot use the EAP 'username:' option without a 'password:'. " | ||||
|                              "Please provide the 'password:' key") | ||||
|     if CONF_CERTIFICATE in value or CONF_KEY in value: | ||||
|         if CONF_CERTIFICATE not in value and CONF_KEY not in value: | ||||
|             raise cv.Invalid("You have provided an EAP 'certificate:' or 'key:' without providing " | ||||
|                              "the other. Please check you have provided both.") | ||||
|         # Check the key is valid and for this certificate, just to check the user hasn't pasted | ||||
|         # the wrong thing. I write this after I spent a while debugging that exact issue. | ||||
|         # This may require a password to decrypt to key, so we should verify that at the same time. | ||||
|         certPw = None | ||||
|         if CONF_PASSWORD in value: | ||||
|             certPw = value[CONF_PASSWORD] | ||||
|  | ||||
|         cert = cv.load_certificate(value[CONF_CERTIFICATE]) | ||||
|         try: | ||||
|             key = cv.load_key(value[CONF_KEY], certPw) | ||||
|         except ValueError as e: | ||||
|             raise cv.Invalid( | ||||
|                 "There was an error with the EAP 'password:' provided for 'key:' :%s" % e | ||||
|             ) | ||||
|         except TypeError as e: | ||||
|             raise cv.Invalid("There was an error with the EAP 'key:' provided :%s" % e) | ||||
|  | ||||
|         if isinstance(key, rsa.RSAPrivateKey): | ||||
|             if key.public_key().public_numbers() != cert.public_key().public_numbers(): | ||||
|                 raise cv.Invalid("The provided EAP 'key:' does not match the 'certificate:'") | ||||
|         elif isinstance(key, ec.EllipticCurvePrivateKey): | ||||
|             if key.public_key().public_numbers() != cert.public_key().public_numbers(): | ||||
|                 raise cv.Invalid("The provided EAP 'key:' does not match the 'certificate:'") | ||||
|         elif isinstance(key, ed448.Ed448PrivateKey): | ||||
|             if key.public_key() != cert: | ||||
|                 raise cv.Invalid("The provided EAP 'key:' does not match the 'certificate:'") | ||||
|         elif isinstance(key, ed25519.Ed25519PrivateKey): | ||||
|             if key.public_key() != cert: | ||||
|                 raise cv.Invalid("The provided EAP 'key:' does not match the 'certificate:'") | ||||
|         else: | ||||
|             _LOGGER.warning( | ||||
|                 "Unrecognised EAP 'certificate:' 'key:' pair format: %s. Proceed with caution!", | ||||
|                 type(key) | ||||
|             ) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def validate_channel(value): | ||||
|     value = cv.positive_int(value) | ||||
|     if value < 1: | ||||
| @@ -111,15 +56,6 @@ STA_MANUAL_IP_SCHEMA = AP_MANUAL_IP_SCHEMA.extend({ | ||||
|     cv.Optional(CONF_DNS2, default="0.0.0.0"): cv.ipv4, | ||||
| }) | ||||
|  | ||||
| EAP_AUTH_SCHEMA = cv.Schema({ | ||||
|     cv.Optional(CONF_IDENTITY): cv.string_strict, | ||||
|     cv.Optional(CONF_USERNAME): cv.string_strict, | ||||
|     cv.Optional(CONF_PASSWORD): cv.string_strict, | ||||
|     cv.Optional(CONF_CERTIFICATE_AUTHORITY): cv.certificate, | ||||
|     cv.Optional(CONF_CERTIFICATE): cv.certificate, | ||||
|     cv.Optional(CONF_KEY): cv.string_strict, | ||||
| }) | ||||
|  | ||||
| WIFI_NETWORK_BASE = cv.Schema({ | ||||
|     cv.GenerateID(): cv.declare_id(WiFiAP), | ||||
|     cv.Optional(CONF_SSID): cv.ssid, | ||||
| @@ -137,7 +73,6 @@ WIFI_NETWORK_STA = WIFI_NETWORK_BASE.extend({ | ||||
|     cv.Optional(CONF_BSSID): cv.mac_address, | ||||
|     cv.Optional(CONF_HIDDEN): cv.boolean, | ||||
|     cv.Optional(CONF_PRIORITY, default=0.0): cv.float_, | ||||
|     cv.Optional(CONF_EAP): EAP_AUTH_SCHEMA, | ||||
| }) | ||||
|  | ||||
|  | ||||
| @@ -158,10 +93,6 @@ def validate(config): | ||||
|         raise cv.Invalid("Please specify at least an SSID or an Access Point " | ||||
|                          "to create.") | ||||
|  | ||||
|     for network in config[CONF_NETWORKS]: | ||||
|         if CONF_EAP in network: | ||||
|             network[CONF_EAP] = validate_eap(network[CONF_EAP]) | ||||
|  | ||||
|     if config.get(CONF_FAST_CONNECT, False): | ||||
|         networks = config.get(CONF_NETWORKS, []) | ||||
|         if not networks: | ||||
| @@ -187,7 +118,6 @@ CONFIG_SCHEMA = cv.All(cv.Schema({ | ||||
|     cv.Optional(CONF_SSID): cv.ssid, | ||||
|     cv.Optional(CONF_PASSWORD): validate_password, | ||||
|     cv.Optional(CONF_MANUAL_IP): STA_MANUAL_IP_SCHEMA, | ||||
|     cv.Optional(CONF_EAP): EAP_AUTH_SCHEMA, | ||||
|  | ||||
|     cv.Optional(CONF_AP): WIFI_NETWORK_AP, | ||||
|     cv.Optional(CONF_DOMAIN, default='.local'): cv.domain_name, | ||||
| @@ -203,20 +133,6 @@ CONFIG_SCHEMA = cv.All(cv.Schema({ | ||||
| }), validate) | ||||
|  | ||||
|  | ||||
| def eap_auth(config): | ||||
|     if config is None: | ||||
|         return None | ||||
|     return cg.StructInitializer( | ||||
|         EAPAuth, | ||||
|         ('identity', config.get(CONF_IDENTITY, "")), | ||||
|         ('username', config.get(CONF_USERNAME, "")), | ||||
|         ('password', config.get(CONF_PASSWORD, "")), | ||||
|         ('ca_cert', config.get(CONF_CERTIFICATE_AUTHORITY, "")), | ||||
|         ('client_cert', config.get(CONF_CERTIFICATE, "")), | ||||
|         ('client_key', config.get(CONF_KEY, "")), | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def safe_ip(ip): | ||||
|     if ip is None: | ||||
|         return IPAddress(0, 0, 0, 0) | ||||
| @@ -242,8 +158,6 @@ def wifi_network(config, static_ip): | ||||
|         cg.add(ap.set_ssid(config[CONF_SSID])) | ||||
|     if CONF_PASSWORD in config: | ||||
|         cg.add(ap.set_password(config[CONF_PASSWORD])) | ||||
|     if CONF_EAP in config: | ||||
|         cg.add(ap.set_eap(eap_auth(config[CONF_EAP]))) | ||||
|     if CONF_BSSID in config: | ||||
|         cg.add(ap.set_bssid([HexInt(i) for i in config[CONF_BSSID].parts])) | ||||
|     if CONF_HIDDEN in config: | ||||
|   | ||||
| @@ -541,14 +541,12 @@ void WiFiAP::set_ssid(const std::string &ssid) { this->ssid_ = ssid; } | ||||
| void WiFiAP::set_bssid(bssid_t bssid) { this->bssid_ = bssid; } | ||||
| void WiFiAP::set_bssid(optional<bssid_t> bssid) { this->bssid_ = bssid; } | ||||
| void WiFiAP::set_password(const std::string &password) { this->password_ = password; } | ||||
| void WiFiAP::set_eap(optional<EAPAuth> eap_auth) { this->eap_ = eap_auth; } | ||||
| void WiFiAP::set_channel(optional<uint8_t> channel) { this->channel_ = channel; } | ||||
| void WiFiAP::set_manual_ip(optional<ManualIP> manual_ip) { this->manual_ip_ = manual_ip; } | ||||
| void WiFiAP::set_hidden(bool hidden) { this->hidden_ = hidden; } | ||||
| const std::string &WiFiAP::get_ssid() const { return this->ssid_; } | ||||
| const optional<bssid_t> &WiFiAP::get_bssid() const { return this->bssid_; } | ||||
| const std::string &WiFiAP::get_password() const { return this->password_; } | ||||
| const optional<EAPAuth> &WiFiAP::get_eap() const { return this->eap_; } | ||||
| const optional<uint8_t> &WiFiAP::get_channel() const { return this->channel_; } | ||||
| const optional<ManualIP> &WiFiAP::get_manual_ip() const { return this->manual_ip_; } | ||||
| bool WiFiAP::get_hidden() const { return this->hidden_; } | ||||
|   | ||||
| @@ -57,16 +57,6 @@ struct ManualIP { | ||||
|   IPAddress dns2;  ///< The second DNS server. 0.0.0.0 for default. | ||||
| }; | ||||
|  | ||||
| struct EAPAuth { | ||||
|   std::string identity;  // required for all auth types | ||||
|   std::string username; | ||||
|   std::string password; | ||||
|   char *ca_cert;  // optionally verify authentication server | ||||
|   // used for EAP-TLS | ||||
|   char *client_cert; | ||||
|   char *client_key; | ||||
| }; | ||||
|  | ||||
| using bssid_t = std::array<uint8_t, 6>; | ||||
|  | ||||
| class WiFiAP { | ||||
| @@ -75,7 +65,6 @@ class WiFiAP { | ||||
|   void set_bssid(bssid_t bssid); | ||||
|   void set_bssid(optional<bssid_t> bssid); | ||||
|   void set_password(const std::string &password); | ||||
|   void set_eap(optional<EAPAuth> eap_auth); | ||||
|   void set_channel(optional<uint8_t> channel); | ||||
|   void set_priority(float priority) { priority_ = priority; } | ||||
|   void set_manual_ip(optional<ManualIP> manual_ip); | ||||
| @@ -83,7 +72,6 @@ class WiFiAP { | ||||
|   const std::string &get_ssid() const; | ||||
|   const optional<bssid_t> &get_bssid() const; | ||||
|   const std::string &get_password() const; | ||||
|   const optional<EAPAuth> &get_eap() const; | ||||
|   const optional<uint8_t> &get_channel() const; | ||||
|   float get_priority() const { return priority_; } | ||||
|   const optional<ManualIP> &get_manual_ip() const; | ||||
| @@ -93,7 +81,6 @@ class WiFiAP { | ||||
|   std::string ssid_; | ||||
|   optional<bssid_t> bssid_; | ||||
|   std::string password_; | ||||
|   optional<EAPAuth> eap_; | ||||
|   optional<uint8_t> channel_; | ||||
|   float priority_{0}; | ||||
|   optional<ManualIP> manual_ip_; | ||||
|   | ||||
| @@ -6,7 +6,6 @@ | ||||
|  | ||||
| #include <utility> | ||||
| #include <algorithm> | ||||
| #include <esp_wpa2.h> | ||||
| #include "lwip/err.h" | ||||
| #include "lwip/dns.h" | ||||
|  | ||||
| @@ -188,51 +187,6 @@ bool WiFiComponent::wifi_sta_connect_(WiFiAP ap) { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // setup enterprise authentication if required | ||||
|   if (ap.get_eap().has_value()) { | ||||
|     // note: all certificates and keys have to be null terminated. Lengths are appended by +1 to include \0. | ||||
|     EAPAuth eap = ap.get_eap().value(); | ||||
|     err = esp_wifi_sta_wpa2_ent_set_identity((uint8_t *) eap.identity.c_str(), eap.identity.length()); | ||||
|     if (err != ESP_OK) { | ||||
|       ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_identity failed! %d", err); | ||||
|     } | ||||
|     int ca_cert_len = strlen(eap.ca_cert); | ||||
|     int client_cert_len = strlen(eap.client_cert); | ||||
|     int client_key_len = strlen(eap.client_key); | ||||
|     if (ca_cert_len) { | ||||
|       err = esp_wifi_sta_wpa2_ent_set_ca_cert((uint8_t *) eap.ca_cert, ca_cert_len + 1); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_ca_cert failed! %d", err); | ||||
|       } | ||||
|     } | ||||
|     // workout what type of EAP this is | ||||
|     // validation is not required as the config tool has already validated it | ||||
|     if (client_cert_len && client_key_len) { | ||||
|       // if we have certs, this must be EAP-TLS | ||||
|       err = esp_wifi_sta_wpa2_ent_set_cert_key((uint8_t *) eap.client_cert, client_cert_len + 1, | ||||
|                                                (uint8_t *) eap.client_key, client_key_len + 1, | ||||
|                                                (uint8_t *) eap.password.c_str(), strlen(eap.password.c_str())); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_cert_key failed! %d", err); | ||||
|       } | ||||
|     } else { | ||||
|       // in the absence of certs, assume this is username/password based | ||||
|       err = esp_wifi_sta_wpa2_ent_set_username((uint8_t *) eap.username.c_str(), eap.username.length()); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_username failed! %d", err); | ||||
|       } | ||||
|       err = esp_wifi_sta_wpa2_ent_set_password((uint8_t *) eap.password.c_str(), eap.password.length()); | ||||
|       if (err != ESP_OK) { | ||||
|         ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_password failed! %d", err); | ||||
|       } | ||||
|     } | ||||
|     esp_wpa2_config_t wpa2Config = WPA2_CONFIG_INIT_DEFAULT(); | ||||
|     err = esp_wifi_sta_wpa2_ent_enable(&wpa2Config); | ||||
|     if (err != ESP_OK) { | ||||
|       ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_enable failed! %d", err); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this->wifi_apply_hostname_(); | ||||
|  | ||||
|   err = esp_wifi_connect(); | ||||
|   | ||||
| @@ -10,10 +10,6 @@ from string import ascii_letters, digits | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| from cryptography import x509 | ||||
| from cryptography.hazmat.backends import default_backend | ||||
| from cryptography.hazmat.primitives.serialization import load_pem_private_key | ||||
|  | ||||
| from esphome import core | ||||
| from esphome.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_ID, \ | ||||
|     CONF_INTERNAL, CONF_NAME, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, \ | ||||
| @@ -721,25 +717,6 @@ def domain_name(value): | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def load_certificate(value): | ||||
|     return x509.load_pem_x509_certificate(value.encode('UTF-8'), default_backend()) | ||||
|  | ||||
|  | ||||
| def load_key(value, password): | ||||
|     if password: | ||||
|         password = password.encode("UTF-8") | ||||
|     return load_pem_private_key(value.encode('UTF-8'), password, default_backend()) | ||||
|  | ||||
|  | ||||
| def certificate(value): | ||||
|     value = string_strict(value) | ||||
|     try: | ||||
|         load_certificate(value)  # raises ValueError | ||||
|         return value | ||||
|     except ValueError: | ||||
|         return Invalid("Invalid certificate") | ||||
|  | ||||
|  | ||||
| def ssid(value): | ||||
|     value = string_strict(value) | ||||
|     if not value: | ||||
|   | ||||
| @@ -76,8 +76,6 @@ CONF_CALIBRATION = 'calibration' | ||||
| CONF_CAPACITANCE = 'capacitance' | ||||
| CONF_CARRIER_DUTY_PERCENT = 'carrier_duty_percent' | ||||
| CONF_CARRIER_FREQUENCY = 'carrier_frequency' | ||||
| CONF_CERTIFICATE = "certificate" | ||||
| CONF_CERTIFICATE_AUTHORITY = "certificate_authority" | ||||
| CONF_CHANGE_MODE_EVERY = 'change_mode_every' | ||||
| CONF_CHANNEL = 'channel' | ||||
| CONF_CHANNELS = 'channels' | ||||
| @@ -148,7 +146,6 @@ CONF_DRY_ACTION = 'dry_action' | ||||
| CONF_DRY_MODE = 'dry_mode' | ||||
| CONF_DUMP = 'dump' | ||||
| CONF_DURATION = 'duration' | ||||
| CONF_EAP = 'eap' | ||||
| CONF_ECHO_PIN = 'echo_pin' | ||||
| CONF_EFFECT = 'effect' | ||||
| CONF_EFFECTS = 'effects' | ||||
| @@ -214,7 +211,6 @@ CONF_I2C = 'i2c' | ||||
| CONF_I2C_ID = 'i2c_id' | ||||
| CONF_ICON = 'icon' | ||||
| CONF_ID = 'id' | ||||
| CONF_IDENTITY = 'identity' | ||||
| CONF_IDLE = 'idle' | ||||
| CONF_IDLE_ACTION = 'idle_action' | ||||
| CONF_IDLE_LEVEL = 'idle_level' | ||||
| @@ -242,7 +238,6 @@ CONF_JS_URL = 'js_url' | ||||
| CONF_JVC = 'jvc' | ||||
| CONF_KEEP_ON_TIME = 'keep_on_time' | ||||
| CONF_KEEPALIVE = 'keepalive' | ||||
| CONF_KEY = 'key' | ||||
| CONF_LAMBDA = 'lambda' | ||||
| CONF_LEVEL = 'level' | ||||
| CONF_LG = 'lg' | ||||
|   | ||||
| @@ -10,5 +10,4 @@ pyserial==3.4 | ||||
| ifaddr==0.1.6 | ||||
| platformio==4.3.3 | ||||
| esptool==2.8 | ||||
| cryptography==2.9.2 | ||||
| click==7.1.2 | ||||
|   | ||||
| @@ -10,7 +10,6 @@ pyserial==3.4 | ||||
| ifaddr==0.1.6 | ||||
| platformio==4.3.3 | ||||
| esptool==2.8 | ||||
| cryptography==2.9.2 | ||||
|  | ||||
| pylint==2.5.0 | ||||
| flake8==3.7.9 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user