Aircoookie / WLED

Control WS2812B and many more types of digital RGB LEDs with an ESP8266 or ESP32 over WiFi!
https://kno.wled.ge
MIT License
15.09k stars 3.27k forks source link

WPA2 Enterprise Support #2749

Open ghost opened 2 years ago

ghost commented 2 years ago

Is your feature request related to a problem? Please describe. I am trying to make WLED work with WPA2 Enterprise, especially Eduroam networks that sometimes requires certificates.

Describe the solution you'd like There are example sketches from Arduino. I was able the use that to connect my ESP32 (NodeMCU) to the network of my organisation. But without WLED.

#include <WiFi.h> //Wifi library
#include "esp_wpa2.h" //wpa2 library for connections to Enterprise networks
#define EAP_IDENTITY "identitiy" //if connecting from another corporation, use identity@organisation.domain in Eduroam 
#define EAP_USERNAME "username" //oftentimes just a repeat of the identity
#define EAP_PASSWORD "password" //your Eduroam password
const char* ssid = "SSID"; // Eduroam SSID
const char* host = "domain"; //external server domain for HTTP connection after authentification
int counter = 0;

// NOTE: For some systems, various certification keys are required to connect to the wifi system.
//       Usually you are provided these by the IT department of your organization when certs are required
//       and you can't connect with just an identity and password.
//       Most eduroam setups we have seen do not require this level of authentication, but you should contact
//       your IT department to verify.
//       You should uncomment these and populate with the contents of the files if this is required for your scenario (See Example 2 and Example 3 below).

//       HERE YOU CAN JUST INSERT THE CERT CERTIFICATE FROM YOUR ORGANISATION. If it's in .pem format you can just copy-paste 
static const char incommon_ca[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
BSeOE6Fuwg==
-----END CERTIFICATE-----
)EOF";
//const char *client_cert = "insert your client cert from your .crt file here";
//const char *client_key = "insert your client key from your .key file here";

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting to network: ");
  Serial.println(ssid);
  WiFi.disconnect(true);  //disconnect form wifi to set new wifi connection
  WiFi.mode(WIFI_STA); //init wifi mode

  // Example1 (most common): a cert-file-free eduroam with PEAP (or TTLS)
  WiFi.begin(ssid, WPA2_AUTH_PEAP, EAP_IDENTITY, EAP_USERNAME, EAP_PASSWORD);

  // Example 2: a cert-file WPA2 Enterprise with PEAP
  //WiFi.begin(ssid, WPA2_AUTH_PEAP, EAP_IDENTITY, EAP_USERNAME, EAP_PASSWORD, ca_pem, client_cert, client_key);

  // Example 3: TLS with cert-files and no password
  //WiFi.begin(ssid, WPA2_AUTH_TLS, EAP_IDENTITY, NULL, NULL, ca_pem, client_cert, client_key);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    counter++;
    if(counter>=60){ //after 30 seconds timeout - reset board
      ESP.restart();
    }
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address set: "); 
  Serial.println(WiFi.localIP()); //print LAN IP
}
void loop() {
  if (WiFi.status() == WL_CONNECTED) { //if we are connected to Eduroam network
    counter = 0; //reset counter
    Serial.println("Wifi is still connected with IP: "); 
    Serial.println(WiFi.localIP());   //inform user about his IP address
  }else if (WiFi.status() != WL_CONNECTED) { //if we lost connection, retry
    WiFi.begin(ssid);      
  }
  while (WiFi.status() != WL_CONNECTED) { //during lost connection, print dots
    delay(500);
    Serial.print(".");
    counter++;
    if(counter>=60){ //30 seconds timeout - reset board
    ESP.restart();
    }
  }
  Serial.print("Connecting to website: ");
  Serial.println(host);
  WiFiClient client;
 if (client.connect(host, 80)) {
    String url = "/rele/rele1.txt";
    client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: ESP32\r\n" + "Connection: close\r\n\r\n");

    while (client.connected()) {
      String line = client.readStringUntil('\n');
      if (line == "\r") {
        break;
      }
    }
    String line = client.readStringUntil('\n');
   Serial.println(line);
  }else{
      Serial.println("Connection unsucessful");
    }  
}

Describe alternatives you've considered I tried this solution by @garyd9. But I was not able to implement that.

Comment by @garyd9 :

I'll just leave this little block of code I inserted in initConnection() here (mostly taken from various google search results)... Oh, and it does work. On my particular network, my username must be "domain\user" instead of just "user", but it does work fine on PEAP/MSCHAPv2 (coming from an ESP32 device)

(requires "esp_wpa2.h" to be included to get at the WPA2 type and macro)

  const char *username = "MYDOMAIN\\username";
  const char *password = "mypassword";

  WiFi.disconnect(true);
  WiFi.mode(WIFI_STA);  // didn't work without this.  odd.
  esp_wifi_sta_wpa2_ent_set_username((uint8_t *)username, strlen(username));
  esp_wifi_sta_wpa2_ent_set_password((uint8_t *)password, strlen(password));
  esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT();
  esp_err_t code = esp_wifi_sta_wpa2_ent_enable(&config);
  Serial.print ("enable response code: ");
  Serial.println(code);
  const char *ssid = clientSSID;
  Serial.print("wifi Begin connection to: "); Serial.println(ssid);
  WiFi.begin(ssid);

To use this properly, the HTTP UI would need to prompt for an additional piece of info: a username. I just hard-coded everything to try it out. (I'm still exploring this esp32 dev board. it's fun.)

Originally posted by @garyd9 in https://github.com/Aircoookie/WLED/issues/1001#issuecomment-656989199

Additional context I am new to coding and I am just starting to learn through the internet. I asked for help and @blazoncek told me to insert the code in wled.cpp under initConnection()

wled.cpp -> initConnection()

Originally posted by @blazoncek in https://github.com/Aircoookie/WLED/issues/2747#issuecomment-1211998587

But as you can see I was not able to do that.

I think this feature would make WLED even better for students and other people that use WPA2-Enterprise.

Thanks

blazoncek commented 2 years ago

Why open a new issue? What was wrong with the old one?

ghost commented 2 years ago

Oh, sorry for opening another issue. I tought this was different because I clicked on feature request.

I get these error messages

I don't know where the mistake is

spdustin commented 1 year ago

I’m about to deliver a project that will need to access a WPA2 Enterprise network, so I may be able to take this on in the next few days

softhack007 commented 1 year ago

similar to issue 3133 and 2747

Andoramb commented 1 year ago

So does anyone have an update on this? :)