esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
16.07k stars 13.33k forks source link

WPA2 Enterprise authorization fail #2595

Closed Gidrix closed 6 years ago

Gidrix commented 8 years ago

Basic Infos

Hardware

Hardware: ESP-12 Core Version: using git branch update_sdk_2.0.0

Description

I have AP with configured PEAP WPA2 Enterprise, it only asks log/pass, certificates not required. Authorization work properly, I can connect with my android phone. When esp tries to connect to AP, in AP log esp status is only "associated", which means esp actually connected to AP. BUT esp never get an ip (status will be "authorized"). Basically wpa2 enterprise part of code dont do anything. Same code in NONOS SDK 2.0.0 works fine, but I already have pretty big project on arduino, so it would be hard to transfer to sdk.

Settings in IDE

Module: Generic ESP8266 Module Flash Size: 4MB CPU Frequency: 80Mhz Flash Mode: qio Flash Frequency: 40Mhz Upload Using: SERIAL Reset Method: ck

Sketch


#include <Arduino.h>
#include <ESP8266WiFi.h>
#ifdef ESP8266
extern "C" {
#include "user_interface.h"
#include "wpa2_enterprise.h"
}
#endif

static u8 ent_username[] = "test";
static u8 ent_password[] = "test";

void setup(){
  char a[100];
  ip_info info;
  wifi_get_ip_info(0, &info);

  Serial.begin(115200);

  wifi_station_disconnect();
  wifi_set_opmode(STATION_MODE);

  char ssid[32] = "my_enterprise_ap";
  char password[64] = {0x00};
  struct station_config stationConf;
  stationConf.bssid_set = 0;  //need not check MAC address of AP
  memcpy(&stationConf.ssid, ssid, 32);
  memcpy(&stationConf.password, password, 64);

  if(!wifi_station_set_config(&stationConf)){
    Serial.print("\r\nset config fail\r\n");
  }

  // switch to WPA2 Enterprise 
  wifi_station_set_wpa2_enterprise_auth(1); 

  if(wifi_station_set_enterprise_username (ent_username, sizeof(ent_username))){
    Serial.print("\r\nusername set fail\r\n");
  }
  if(wifi_station_set_enterprise_password (ent_password, sizeof(ent_password))){
    Serial.print("\r\npassword set fail\r\n");
  }

  if(!wifi_station_connect()){
    Serial.print("\r\nconnect fail\r\n");
  }

  Serial.print("\r\ntrying to connect...");

  while(info.ip.addr == 0){
    ESP.wdtFeed();
    Serial.print(".");
    delay(1000);
    wifi_get_ip_info(0, &info);
  }

  sprintf(a, "%"PRIu32,info.ip.addr);
  Serial.print("\r\nip addr: ");
  Serial.print(a);
  Serial.print("\r\n");
}

void loop()
{ 
}
gorghino commented 8 years ago

I confirm it with a ESP8266-07. I uploaded the last firmware + patch and I'm using 2.0.0 branch. The log is:

load 0x4010f000, len 1384, room trying to connect.....................................wifi evt: 1 STA disconnect: 204 ..............................wifi evt: 1 STA disconnect: 204 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 ..wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 ..wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 .wifi evt: 1 STA disconnect: 4 ..............................wifi evt: 1 STA disconnect: 204 .....................

gorghino commented 8 years ago

@Gidrix Could you please share your working user_main.c? I tried to code something with the SDK2 but eduroam doesn't work and I can't figure out If I'm putting functions in wrong place.

rbmb commented 7 years ago

HI, I tried your code and found that the esp8266 always send the same default identifier instead of the one specified by wifi_station_set_enterprise_username https://github.com/esp8266/Arduino/issues/1032#issuecomment-261636614

The default identifier is anonymous@espressif.com , but I don't know the password. you can find it in libwpa2.a file, generated by the eap.c file.

rbmb commented 7 years ago

The file libwpa2.a is exactly the same, the header file wpa2_entreprise.h is also the same except the comments at the beginning between Arduino and NONOS SDK.

How can we progress in this issue ? Where should we look ? Can it be the linking order in platform.txt (compiler.c.elf.libs)?

joostd commented 7 years ago

The linking order doesn't matter. @gorghino's code above should work just fine, but it depends on the particular wifi setup. Note that the default identifier "anonymous@espressif.com" is not used for authentication but for routing. /There is no password./

There is currently no API for changing this, but unless you are trying to connect to a roaming network (such as eduroam) you probably don't need to. Check the radius logs if you can to see why you cannot connect.

My experiences in a lab setup are:

However, outside the lab authentication often fails, for various reasons. The radius logs will tell you why.

marcelkottmann commented 7 years ago

@Gidrix said, that the same code works in NONOS SDK 2.0.0. I assume this was the same AP, correct?

My Radius Log unfortunately does not show any useful information for me, besides that my request was Rejected (user/password were marric/marric):

[RADIUS-Server] 2016/12/15 11:49:44,810  Devicetime: 2016/12/15 11:49:44,587
Received RADIUS authentication request 18 from client 127.0.0.1:3072:
-->known attributes of request:
   User-Name           : marric
   Service-Type        : Framed
   MS-CHAP-Challenge:
   0000: 66 ec 0d 0f 5a f5 01 84 56 db 6c 33 a6 4d 9c 9e  f...Z...V.l3.M..
   MS-CHAP2-Response:
   0000: 07 00 ca 16 97 58 41 49 59 82 33 49 2b 40 76 ad  .....XAIY.3I+@v.
   0010: fd 91 00 00 00 00 00 00 00 00 7b b5 86 b1 f3 cd  ..........{.....
   0020: b7 93 71 57 0c 39 16 eb 9b 76 bd 7d 54 1a e3 49  ..qW.9...v.}T..I
   0030: 09 19                                            ..
   NAS-Identifier      : skynet-mock
   NAS-IP-Address      : 127.0.0.1
   Called-Station-Id   : 00-80-48-54-83-3B:LANCOMEAP
   Calling-Station-Id  : 5C-CF-7F-10-B0-E6
   Connect-Info        : CONNECT 54 Mbps 802.11g
-->user name contains no realm, using empty realm
-->realm of user is ''
-->authenticating locally
-->found user 'marric' in database(s)
-->authenticating via MS-CHAPv2
-->response type is Reject, response attributes:
-->sending response

Full log of one authentication attempt: https://gist.github.com/pepe79/fa753973e7d932bfa16ddde6b5b476eb

marcelkottmann commented 7 years ago

Finally I got an IP!

The problem is in your code: Instead of using sizeof(ent_username) and sizeof(ent_password) you have to get the string lengthes. So I replaced this code with strlen((char)ent_username)) and strlen((char)ent_password)). After this change I could authorize with my WPA2 PEAP AP and got an IP.

joostd commented 7 years ago

When debugging, it may also help to use the sdk directly and monitor the debug messages on the serial console.

Example code: https://github.com/joostd/esp8266-eduroam/blob/master/wpa2e-v20/user/user_main.c

bospre commented 7 years ago

Hi, that sounds good. Can you please share your working code?

bospre commented 7 years ago

OK, I found out, that you just modified the sketch above. I tried that too, but it doesn't compile because I only have the Library 2.3.0 installed which is based on SDK 1.5x. Unfortunatly I did not understand how to upgrade. Is it possible to download the files manually?

marcelkottmann commented 7 years ago

Follow these instructions to use the sdk 2.0.0 in Arduino IDE: https://github.com/esp8266/Arduino/issues/2304#issuecomment-245849344

joostd commented 7 years ago

Beware though, that at the moment both EAP-TTLS and EAP-PEAP only work with MS-CHAPv2 user authentication. PAP is not supported yet.

So YMMV: it all depends on the configuration of the RADIUS backend.

bospre commented 7 years ago

I finally managed the download. The sketch now compiles. But in my logfile I see: Sun Dec 18 21:14:55 2016 : Auth: Login incorrect: [anonymous@espressif.com/] (from client WLAN ... Usually it looks like this: Sun Dec 18 21:06:03 2016 : Auth: Login OK: [Handy_xxxxx/] (from client WLAN ...

But "anonymous@espressif.com" was not the user I put into the variable. Has this to do with MS-CHAPv2 versus PAP? Can you explain the difference? I tried to google that, but could not find something I could understand.

What can I do? The RADIUS-server accepts login by name and password. But there is the wrong name submitted? I just checked my mobile phone (which connexcts perfect), for EAP there is PEAP chosen and for Phase2-Authentification: MSCHAPV2.

joostd commented 7 years ago

anonymous@espressif.com is the outer identity that is hardcoded in libwpa2. It is different from the "inner identity" used in MSCHAPv2 and which is set using wifi_station_set_enterprise_username.

You can try editing the binary libwpa2 to make the outer identity equal to the inner identity. For instance using a tool like bbe. See http://bbe-.sourceforge.net

bospre commented 7 years ago

Thank you for your fast reply. I had a look into libwpa2.h, but could not find the string. If it is a binary format, is there a way to change under windwows? bbs is not executable...

joostd commented 7 years ago

Just Google for "binary editor windows" or use this port (binary download at the bottom)

alviso commented 7 years ago

@joostd I'm trying to connect to UPC Wi-Free with esp8266-eduroam/wpa2e-v20/ This is the output I'm getting, any suggestions? Thanks, Peter

WPA2 ENTERPRISE VERSION: [v2.0] enable mode : sta(5c:cf:7f:88:1e:b2) add if0 scandone state: 0 -> 2 (b0) state: 2 -> 3 (0) state: 3 -> 5 (10) add 0 aid 1 cnt state: 5 -> 2 (17a0) rm 0 [disconnect from ssid UPC Wi-Free, reason 23]

At one point I got 2 additonal messages (pm open, pm close)

state: 0 -> 2 (b0) state: 2 -> 3 (0) state: 3 -> 5 (10) add 0 aid 1 cnt pm open,type:2 0 state: 5 -> 0 (2) rm 0 pm close 7 reconnect [disconnect from ssid UPC Wi-Free, reason 204]

joostd commented 7 years ago

See the SDK API reference section 7.2.4:

REASON_802_1X_AUTH_FAILED = 23, /* 11i */

This means authentication fails. UPC Wi_Free probably uses PEAP by default, which should be supported. Not having access to the RADIUS logs will make this very difficult to debug.

I don't know UPC Wi_Free, but I can imagine they make use of the outer identity. You may need to edit libwpa2.a to make the outer identity ("anonymous@expressif.com") identical to your username.

alviso commented 7 years ago

@joostd Thanks a lot for your answer. I tried to edit the outer identity as well but same result for now.

dfries commented 7 years ago

I'm using esp-open-sdk rather than the Arduino base. I added some of the enterprise functions to the basic_example and linked with wpa2, but I'm getting what sounds like an out of memory error "Method private structure allocated failure" even with this minimal program that claims 45KB free. This is with ESP8266_NONOS_SDK_V2.0.0_16_08_10, any ideas? I have the same error if I try a PEM client certificate and private key.

Added functions:

wifi_set_opmode(STATION_MODE);
wifi_station_set_wpa2_enterprise_auth(true);
wifi_station_set_reconnect_policy(false);
wifi_station_set_enterprise_username((u8*)EAP_USER, os_strlen(EAP_USER));
wifi_station_set_enterprise_password((u8*)EAP_PASSWORD, os_strlen(EAP_PASSWORD));
wifi_station_connect();

output:

heap 46040 wifi status 1 state: 2 -> 0 (0) scandone state: 0 -> 2 (b0) state: 2 -> 3 (0) state: 3 -> 5 (10) add 0 aid 1 cnt Method private structure allocated failure state: 5 -> 2 (17c0) rm 0

Full program here. https://github.com/dfries/source-code-examples/blob/wpa2-eap/basic_example/user/user_main.c

phizz166 commented 7 years ago

I am having similar problems connecting to WPA2-PEAP networks with MSCHAPv2 authentication. I'm using SDK 2.0 and Gidrix's code from above as modified by pepe79. I am not getting any explicit error messages, just this from the Serial debug output:

scandone
WPA2 ENTERPRISE VERSION: [v2.0] enable

trying to connect......scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
.state: 3 -> 0 (4)
reconnect
..scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 
..........pm open,type:2 0
....................state: 5 -> 0 (2)
rm 0
pm close 7
reconnect
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 
..........pm open,type:2 0
....................state: 5 -> 0 (2)
rm 0
pm close 7
reconnect
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
.state: 3 -> 0 (4)
reconnect
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 
..........pm open,type:2 0
.....

I have tried this both with the unmodified version of libwpa2.a, and a version that I attempted to edit to swap the anonymous@espressif.com outer identity for my own. It doesn't seem to make a difference (If anyone has a good explanation of exactly how to edit the file without corrupting it -- e.g. should I pad the email address with 0x00s before or after the data? -- that would be a big help). I have tried this on two different PEAP networks (eduroam and my institution's own network) and neither one works.

Does anyone have any suggestions? I feel like this shouldn't be as hard as it is...

joostd commented 7 years ago

It seems like development of the esp8266 SDK has stalled. Similar problems with esp32 have been resolved with improvements of its version of libwpa2, where you call the library to set the outer identity.

For the esp8266, it is still needed to binary edit the file libwpa2.a. This is what I do:

Change your working directory to where your version of libwpa2.a is located, for instance

cd esp8266/Arduino/tools/sdk/lib

The v2.0.0 version of the SDK will contain the hardcoded string anonymous@espressif.com

$ grep -z espressif.com libwpa2.a 
anonymous@espressif.com

Make a backup of this file

$ cp libwpa2.a libwpa2.a.original

Use a binary editor like bbe (osx brew users can install with brew install bbe) to overwrite the outer identity with your own, for instance anonymous12@example.edu. Note that the value before the @-sign probably doesn't matter for roaming networks like eduroam, as the outer identity is typically used for routing. Here we make sure the complete string has the same length by right-padding with arbitrary characters.

$ bbe -e "s/anonymous@espressif.com/anonymous12@example.edu/" -o libwpa2.a libwpa2.a.original

Verify that the only bytes that were updated are in the outer identity string

$ diff <(xxd libwpa2.a.original) <(xxd libwpa2.a)
4398c4398
< 000112d0: 7340 6573 7072 6573 7369 662e 636f 6d00  s@espressif.com.
---
> 000112d0: 7331 3240 6578 616d 706c 652e 6564 7500  s12@example.edu.
sanchosk commented 7 years ago

@alviso Did you manage to get it working? I also try to connect to UPC Wi-Free, I edited the libwpa2.a binary file, but I still fail to connect...

alviso commented 7 years ago

No. I did the same but no luck.

On May 19, 2017 12:59, "Robert Klauco" notifications@github.com wrote:

@alviso https://github.com/alviso Did you manage to get it working? I also try to connect to UPC Wi-Free, I edited the libwpa2.a binary file, but I still fail to connect...

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/esp8266/Arduino/issues/2595#issuecomment-302673725, or mute the thread https://github.com/notifications/unsubscribe-auth/ALQrahCR2tHQROhaFxcyKCLkqeO4YRx1ks5r7XYZgaJpZM4KTlgZ .

sanchosk commented 7 years ago

For me it acts a bit strange. It starts to connect, but when the IP address should be assigned, the device freezes and in few seconds watchdog kicks in :( No idea how can I debug it when I do not have access to the UPC router.

sanchosk commented 7 years ago

Does anybody have an idea how to proceed here? I used the sdk 2.1.0 with arduino ide and so far I have no luck. The problem here is I do not control the radius server, so I can't debug the login messages. But it would be nice to get some help on how to debug the behavior and get some more info from esp if possible. What's strange is the fact it always freezes when the actual IP should have been assigned...

neel0003 commented 7 years ago

I tried following the instructions in the link https://www.hallgeirholien.no/post/esp8266-eap/

to connect to a WPA2-Enterprise network with PEAP and MSCHAPV2 for authorization. I am unable to get an IP. I do not have access to my server, can someone point out how to print some helpful debugmessages in the serial output. Do I need to add a ce-cert for getting an IP?

devyte commented 7 years ago

I believe that PR #3215 introduces an api to change the outer identity. Please test with that and report back here.

devyte commented 6 years ago

Closing in favor of #3842 .

PrateekGoyal18 commented 4 years ago

@marcelkottmann, can you share your code snippet. I have connected esp8266 to wpa2 at my university but after some random time (around 10-15 mins, sometimes earlier and sometimes 30 mins also), the esp crashes and restarts itself.