Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPA2 enterprise with credentials auth ok with radius but still get STATION_WRONG_PASSWORD after 30s #6803

Closed
6 tasks done
simkard69 opened this issue Nov 18, 2019 · 9 comments

Comments

@simkard69
Copy link

simkard69 commented Nov 18, 2019

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12E / NodeMCU v3]
  • Core Version: [2.6.1] (esp8266 by ESP8266 Community)
  • Development Env: [Arduino IDE 1.8.10]
  • Operating System: [Windows 10 x64]

Settings in IDE

  • Module: [NodeMCU 1.0 (ESP-12E Module)]
  • Flash Mode: [???]
  • Flash Size: [4MB]
  • lwip Variant: [v2 Lower Memory]
  • Reset Method: [??? (probably NodeMCU)]
  • Flash Frequency: [???]
  • CPU Frequency: [80Mhz]
  • Upload Using: [USB/SERIAL]
  • Upload Speed: [115200 and/or 256000] (serial upload only)

Problem Description

Wifi router is a Synology RT1900ac with WPA2 Enterprise authentication enabled.
RADIUS server is a NPS running on Windows Server 2019.
Policies are configured with :
- Conditions > NAS Port Type > Wireless - Other OR Wireless - IEEE 802.11
- Conditions > NAS Identifier >
- Conditions > Calling Station ID > <MAC ADDRESS FROM NodeMCU/ESP8266>
- Conditions > Windows Groups >
- Constraints > Authentication Methods > Microsoft Secure Password (EAP-MSCHAP v2)

Behavior of code (chronologically) :
- [ESP8266] boots up then tries to associate/authenticate
- [RADIUS/NPS] receives AUTH and grant access
- [ESP8266] On the first 30 seconds, "wifi_station_get_connect_status" == 1 ()
- [ESP8266] Then after 2nd AUTH which takes place at 30s after 1st one : "wifi_station_get_connect_status" switch to == 2 (STATION_WRONG_PASSWORD)
- [RADIUS/NPS] Everytime ESP8266 tries to AUTH it gets access granted anyway
- [ESP8266] Never gets DHCP lease / IP address (even trying to assign it manually // code is available inside the given example)

Seems like a lot of people have problems trying to use WPA2 Enterprise with credentials.
NB : I did not tried to use certificates at all as I do not want to.

Thanks for ideas/suggestions/anything of value will be greatly appreciated.

Sample message from NPS server on Windows Server 2019 (acting as RADIUS server here)
Network Policy Server granted access to a user.

User:
	Security ID:			<DOMAIN\username>
	Account Name:			<username>
	Account Domain:			<DOMAIN>
	Fully Qualified Account Name:	<DOMAIN\username>

Client Machine:
	Security ID:			NULL SID
	Account Name:			-
	Fully Qualified Account Name:	-
	Called Station Identifier:	<MAC ADDRESS FROM ROUTER WIFI INTERFACE>
	Calling Station Identifier:	<MAC ADDRESS FROM NodeMCU/ESP8266>

NAS:
	NAS IPv4 Address:		<IP ADDRESS FROM AP WIFI INTERFACE>
	NAS IPv6 Address:		-
	NAS Identifier:			<MAC ADDRESS FROM WIFI AP INTERFACE>
	NAS Port-Type:			Wireless - IEEE 802.11
	NAS Port:			4

RADIUS Client:
	Client Friendly Name:		<FQDN FROM AP WIFI INTERFACE>
	Client IP Address:		<IP ADDRESS FROM AP WIFI INTERFACE>

Authentication Details:
	Connection Request Policy Name:	Connexions sans fil sécurisées (SimKard)
	Network Policy Name:		<NETWORK POLICY NAMED AS DEFINED IN NPS/RADIUS SERVER>
	Authentication Provider:	Windows
	Authentication Server:		<ACTIVE DIRECTORY DOMAIN CONTROLLER FQDN>
	Authentication Type:		EAP
	EAP Type:			Microsoft: Secured password (EAP-MSCHAP v2)
	Account Session Identifier:	-
	Logging Results:		Accounting information was written to the local log file.

MCVE Sketch

#include <ESP8266WiFi.h>
extern "C" {
  #include "user_interface.h"
  #include "wpa2_enterprise.h"
}

// WPA2 Enterprise informations
// 
// Security Mode              : WAP2-Enterprise / PEAP (Protected Extensible Authentication Protocol)
// Tunnel authentication type : MS CHAP v2 (Challenge Handshake Authentication Protocol)
// Encryption type            : AES


// SSID informations + credentials (username/password for WPA2-Enterprise)
static const char* ssid = "<AP SSID GOES THERE>";
// Pre-Shared Key for authentication (if not using WPA2 EAP-MSCHAP-v2)
//static const char* PreSharedKey = "<WEP/WPA/WPA2 PRESHARED KEY IF USED>";
// Username for authentification
static const char* username = "<USERNAME>";
// Password for authentication
static const char* password = "<PASSWORD>";


// Device hostname and static IP address configuration
const char* deviceName = "<HOSTNAME GOES THERE>";
//IPAddress staticIP(192, 168, 0, 123); // IP address
//IPAddress subnet(255, 255, 255, 0);  // Subnet mask
//IPAddress gateway(192, 168, 0, 254);  // Gateway
//IPAddress dns(192, 168, 0, 254);      // DNS


// WiFi variables
int WiFi_status; // WiFi connection status
unsigned long millis_WiFi_association_start;
int millis_WiFi_association_reset = 35000;


void setup() {
  // INIT Serial communication
  Serial.begin(115200);
  
  delay(500); // Waits for systems to become ready
  
  WiFi.disconnect(); // Disconnect WiFi to flush out configuration
  WiFi.hostname(deviceName); // Set hostname
  //WiFi.config(staticIP, subnet, gateway, dns); // Set manual IP address configuration (If disabled, DHCP will be enforced)


  // =============================================================================================
  // ===== Variables configuration for WPA2 EAP-MSCHAP-v2 with username/password credentials =====
  // =============================================================================================
  // Setting ESP into STATION mode only (no AP mode or dual mode)
  wifi_set_opmode(STATION_MODE); // 0x01 = Station mode ; 0x02 = SoftAP mode ; 0x03 = Station + SoftAP
  
  // Creating the struct to handle parameters/variables
  struct station_config wifi_config;
  
  memset(&wifi_config, 0, sizeof(wifi_config));
  strcpy((char*)wifi_config.ssid, ssid);
  
  wifi_station_set_config(&wifi_config);

  // Flushing stored configuration from FLASH
  wifi_station_clear_cert_key();
  wifi_station_clear_enterprise_ca_cert();
  wifi_station_clear_enterprise_identity();
  wifi_station_clear_enterprise_username();
  wifi_station_clear_enterprise_password();
  wifi_station_clear_enterprise_new_password();
  
  // Configuring authentication with AP
  wifi_station_set_wpa2_enterprise_auth(1);
  wifi_station_set_enterprise_identity((uint8*)username, strlen(username));
  //wifi_station_set_enterprise_ca_cert(ca_cert, sizeof(ca_cert));
  wifi_station_set_enterprise_username((uint8*)username, strlen(username));
  wifi_station_set_enterprise_password((uint8*)password, strlen(password));

  // Starting association with AP
  wifi_station_connect();
  // =============================================================================================


/*
  // =============================================================================================
  // =====         Variables configuration for standard Pre-Shared Key configuration         =====
  // =============================================================================================
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, PreSharedKey);
  // Normal Connection ends here
  // =============================================================================================
*/

  Serial.println();
  Serial.print("Connecting to SSID [");
  Serial.print(ssid);
  Serial.print("] : ");

  // Wait for WiFi connection to be authenticated and IP address obtained from DHCP (if not disabled)
  // At that stage, values in parenthesis can be : 0 = STATION_IDLE ; 1 = STATION_CONNECTING ; 2 = STATION_WRONG_PASSWORD ; 3 = STATION_NO_AP_FOUND ; 4 = STATION_CONNECT_FAIL
  millis_WiFi_association_start = millis();
  while (WiFi.status() != WL_CONNECTED) {
    WiFi_status = wifi_station_get_connect_status();
    Serial.print("");
    if (WiFi_status != 1){
      Serial.print(WiFi_status, DEC);
    } else {
      Serial.print(".");
    }

    // Restart ESP8266 if no WiFi association has been successful
    if (millis() - millis_WiFi_association_start >= millis_WiFi_association_reset){
      ESP.restart();
    }
    
    delay(500);
  }
  
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  IPAddress myAddr = WiFi.localIP();
}

void loop() {

}
@d-a-v
Copy link
Collaborator

d-a-v commented Nov 18, 2019

We have no control on this API.
Just to be sure, you may try again with lwip1 and also with this call anywhere in setup():

disable_extra4k_at_link_time();

If it still does not work, what you would have to do is to make a native nonos-sdk test (branch 2.2.x - the one we use) and check if this issue is still there. And if it is, try with their branch 3.x. And if it is still there, then open an issue on their repository.
You can also ask for support and examples in their rtos-sdk.

@devyte
Copy link
Collaborator

devyte commented Nov 19, 2019

WPA2 isn't fully supported by the sdk (we're still waiting for a working example of the limited use case), and we don't have core code on our side to wrap it. The one thing to try is what @d-a-v says above, which disables an optimization that returns the stacks to their normal places. That allows more stack space for SYS, just in case the optimized reduced stack being blown up is what you're running into.
Closing due to feature not supported by core.

@devyte devyte closed this as completed Nov 19, 2019
@simkard69
Copy link
Author

simkard69 commented Nov 19, 2019

We have no control on this API.
Just to be sure, you may try again with lwip1 and also with this call anywhere in setup():

disable_extra4k_at_link_time();

If it still does not work, what you would have to do is to make a native nonos-sdk test (branch 2.2.x - the one we use) and check if this issue is still there. And if it is, try with their branch 3.x. And if it is still there, then open an issue on their repository.
You can also ask for support and examples in their rtos-sdk.

Just for me to understand what I should be doing regarding the nonos-sdk versions.
Can you point me to some tutorial regarding that part ?

Thanks

NB : seems like the option "disable_extra4k_at_link_time()" you gave me is not found in my environment, any advice ?

\\<PATH TO INO FILE>\ESP8266_WPA2Ent_WebServer.ino: In function 'void setup()':

ESP8266_WPA2Ent_WebServer:45:32: error: 'disable_extra4k_at_link_time' was not declared in this scope

   disable_extra4k_at_link_time(); // lwip1 for WPA2 Enterprise purposes

                                ^

Multiple libraries were found for "ESP8266WiFi.h"
 Used: C:\Users\<USERNAME>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\libraries\ESP8266WiFi
exit status 1
'disable_extra4k_at_link_time' was not declared in this scope

@simkard69
Copy link
Author

I had to include this code in order for the Arduino IDE to find the function "disable_extra4k_at_link_time()"
#include <coredecls.h>

... But unfortunately, no change to be reported on the wifi association/authentication behavior.

@d-a-v
Copy link
Collaborator

d-a-v commented Nov 19, 2019

This is not lwip1, lwip1 is selectable in arduino IDE menus or environment variables in PIO

disable_extra4k_at_link_time(); // use official/legacy ram location for user stack

nonos-sdk example: https://github.com/espressif/ESP8266_NONOS_SDK/tree/master/examples/wpa2_enterprise

maybe it can help (maybe not): https://github.com/d-a-v/esp8266-nonos-easy-sdk (unmaintained)

@simkard69
Copy link
Author

simkard69 commented Nov 19, 2019

I tried to enable "debug level" on "Wifi" to check for any further/complementary messages, and I got these :

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v482516e3
~ld
⸮#d`�;⸮o�lph
SDK:2.2.2-dev(5ab15d1)/Core:2.6.1=20601000/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-16-ge23a07e/BearSSL:89454af
wifi evt: 2
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 4
cnt 
state: 5 -> 0 (0)
rm 0
WPA2 ENTERPRISE VERSION: [v2.0] enable

Connecting to SSID [<AP SSID GOES HERE>] : .wifi evt: 1
STA disconnect: 8
wifi evt: 8
.....scandone
state: 0 -> 2 (b0)
.state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 4
cnt 
EAP-MSCHAPV2: RX identifier 1 mschapv2_id 1
EAP-MSCHAPV2: Generate Challenge Response
EAP-MSCHAPV2: RX identifier 2 mschapv2_id 1
....................pm open,type:2 0
.......................................state: 5 -> 0 (2)
rm 0
pm close 7
reconnect
wifi evt: 1
STA disconnect: 204
2scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 4
cnt 
EAP-MSCHAPV2: RX identifier 1 mschapv2_id 1
EAP-MSCHAPV2: Generate Challenge Response
EAP-MSCHAPV2: RX identifier 2 mschapv2_id 1
222 (These "2" are here to indicate the value of "wifi_station_get_connect_status" which corresponds to "STATION_WRONG_PASSWORD")

Seems like EAP-MSCHAPV2 is taking place correctly, but then, nothing happens.

I have some doubts about the fact that "wifi_station_get_connect_status" updates correctly its status value once associated.
Can this be possible ?

Or maybe I'm wrong and the following sequency just means that there is some problem with the authentication on RADIUS side (which on RADIUS event log doesn't seem to be ...) :

EAP-MSCHAPV2: RX identifier 1 mschapv2_id 1
EAP-MSCHAPV2: Generate Challenge Response
EAP-MSCHAPV2: RX identifier 2 mschapv2_id 1

NB : I tried to change lwIP to something else, for now I just tried :

  • "v2 Lower Memory" : Not changing the association behavior
  • "v2 Higher Bandwidth" : Not changing the association behavior
  • "v1.4 Higher Bandwidth" : Not changing the association behavior

Makes me think about this post :
wpa2 enterprise PEAP-MSChapv2 don't NAK the EAP authentification #263

@d-a-v
Copy link
Collaborator

d-a-v commented Nov 19, 2019

I personally never observed WPA2 working.
This code is FW-closed-source so

  • we cannot do anything
  • the best move is to show them a pure non-working nonos-sdk program like in OP+1, with maximum informations. In some places they propose the linux-hostapd configuration they use to test with their WPA2 FW. I think one should try with it and report with the same configuration (one of the places).

@simkard69
Copy link
Author

There is some interesting information on this link
joostd/esp8266-eduroam

Seems like it is stated that :

Notes:
use version 1.5.2 or later of the espressif sdk for EAP-TLS support.
use version 2.0.0 or later of the espressif sdk for PEAP or EAP-TTLS support.

PEAP still has issues that need to be resolved:
the EAP outer identity seems fixed to anonymous@espressif.com.
MS-Chapv2 authentication fails for some reason.

Something is strange by the way because it seems that I can't change the authentication protocol used from EAP-MSCHAPV2 to something else.

Actually my wifi clients authenticates fine with "Microsoft : Protected EAP (PEAP)".
On NPS, when I disable the "Microsoft: Secured password (EAP-MSCHAP v2), I get access denied for the ESP8266 trying to authenticates with the following reason :
Reason: The client and server cannot communicate, because they do not possess a common algorithm.

@simkard69
Copy link
Author

Seems like the only to get past this problem is to upgrade to NONOS SDK v3 / v3.0.0
I know that there might be some paths to go there, but just wondering when should we expect this SDK release coming to this esp8266 arduino package ?

Thanks for your hard work guys !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants