Skip to content

WPA2 Enterprise support: PEAP/MSCHAPv2 #97

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

Merged
merged 2 commits into from
Dec 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ script:
- buildExampleSketch ConnectNoEncryption
- buildExampleSketch ConnectWithWEP
- buildExampleSketch ConnectWithWPA
- buildExampleSketch ConnectWithWPA2Enterprise
- buildExampleSketch ScanNetworks
- buildExampleSketch ScanNetworksAdvanced
- buildExampleSketch SimpleWebServerWiFi
Expand Down
111 changes: 111 additions & 0 deletions examples/ConnectWithWPA2Enterprise/ConnectWithWPA2Enterprise.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
This example connects to an WPA2 Enterprise WiFi network.
Then it prints the MAC address of the WiFi module,
the IP address obtained, and other network details.

Based on ConnectWithWPA.ino by dlf (Metodo2 srl) and Tom Igoe
*/
#include <SPI.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your WPA2 enterprise network SSID (name)
char user[] = SECRET_USER; // your WPA2 enterprise username
char pass[] = SECRET_PASS; // your WPA2 enterprise password
int status = WL_IDLE_STATUS; // the Wifi radio's status

void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}

String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}

// attempt to connect to Wifi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA2 enterprise network:
// - You can optionally provide additional identity and CA cert (string) parameters:
// WiFi.beginEnterprise(ssid, user, pass, identity, caCert)
// . if your network requires them.
status = WiFi.beginEnterprise(ssid, user, pass);

// wait 10 seconds for connection:
delay(10000);
}

// you're connected now, so print out the data:
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();

}

void loop() {
// check the network connection once every 10 seconds:
delay(10000);
printCurrentNet();
}

void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}

void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);

// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);

// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}

void printMacAddress(byte mac[]) {
for (int i = 5; i >= 0; i--) {
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
if (i > 0) {
Serial.print(":");
}
}
Serial.println();
}
3 changes: 3 additions & 0 deletions examples/ConnectWithWPA2Enterprise/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#define SECRET_SSID ""
#define SECRET_USER ""
#define SECRET_PASS ""
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ remoteIP KEYWORD2
remotePort KEYWORD2

beginAP KEYWORD2
beginEnterprise KEYWORD2
setHostname KEYWORD2
end KEYWORD2
getTime KEYWORD2
Expand Down
31 changes: 31 additions & 0 deletions src/WiFi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,37 @@ uint8_t WiFiClass::beginAP(const char *ssid, const char* passphrase, uint8_t cha
return status;
}

uint8_t WiFiClass::beginEnterprise(const char* ssid, const char* username, const char* password)
{
return beginEnterprise(ssid, username, password, "");
}

uint8_t WiFiClass::beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity)
{
return beginEnterprise(ssid, username, password, identity, "");
}

uint8_t WiFiClass::beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity, const char* ca)
{
uint8_t status = WL_IDLE_STATUS;

// set passphrase
if (WiFiDrv::wifiSetEnterprise(0 /*PEAP/MSCHAPv2*/, ssid, strlen(ssid), username, strlen(username), password, strlen(password), identity, strlen(identity), ca, strlen(ca) + 1)!= WL_FAILURE)
{
for (unsigned long start = millis(); (millis() - start) < _timeout;)
{
delay(WL_DELAY_START_CONNECTION);
status = WiFiDrv::getConnectionStatus();
if ((status != WL_IDLE_STATUS) && (status != WL_NO_SSID_AVAIL) && (status != WL_SCAN_COMPLETED)) {
break;
}
}
} else {
status = WL_CONNECT_FAILED;
}
return status;
}

void WiFiClass::config(IPAddress local_ip)
{
WiFiDrv::config(1, (uint32_t)local_ip, 0, 0);
Expand Down
4 changes: 4 additions & 0 deletions src/WiFi.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class WiFiClass
uint8_t beginAP(const char *ssid, const char* passphrase);
uint8_t beginAP(const char *ssid, const char* passphrase, uint8_t channel);

uint8_t beginEnterprise(const char* ssid, const char* username, const char* password);
uint8_t beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity);
uint8_t beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity, const char* ca);

/* Change Ip configuration settings disabling the dhcp client
*
* param local_ip: Static ip configuration
Expand Down
36 changes: 36 additions & 0 deletions src/utility/wifi_drv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,42 @@ int8_t WiFiDrv::wifiSetApPassphrase(const char* ssid, uint8_t ssid_len, const ch
return _data;
}

int8_t WiFiDrv::wifiSetEnterprise(uint8_t eapType, const char* ssid, uint8_t ssid_len, const char *username, const uint8_t username_len, const char *password, const uint8_t password_len, const char *identity, const uint8_t identity_len, const char* ca_cert, uint16_t ca_cert_len)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(SET_ENT_CMD, PARAM_NUMS_6);
SpiDrv::sendBuffer(&eapType, sizeof(eapType));
SpiDrv::sendBuffer((uint8_t*)ssid, ssid_len);
SpiDrv::sendBuffer((uint8_t*)username, username_len);
SpiDrv::sendBuffer((uint8_t*)password, password_len);
SpiDrv::sendBuffer((uint8_t*)identity, identity_len);
SpiDrv::sendBuffer((uint8_t*)ca_cert, ca_cert_len, LAST_PARAM);

// pad to multiple of 4
int commandSize = 15 + sizeof(eapType) + ssid_len + username_len + password_len + identity_len + ca_cert_len;
while (commandSize % 4) {
SpiDrv::readChar();
commandSize++;
}

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
SpiDrv::spiSlaveSelect();

// Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
if (!SpiDrv::waitResponseCmd(SET_ENT_CMD, PARAM_NUMS_1, &_data, &_dataLen))
{
WARN("error waitResponse");
_data = WL_FAILURE;
}
SpiDrv::spiSlaveDeselect();
return _data;
}

int16_t WiFiDrv::ping(uint32_t ipAddress, uint8_t ttl)
{
WAIT_FOR_SLAVE_SELECT();
Expand Down
7 changes: 7 additions & 0 deletions src/utility/wifi_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ class WiFiDrv

static int8_t wifiSetApNetwork(const char* ssid, uint8_t ssid_len, uint8_t channel);
static int8_t wifiSetApPassphrase(const char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len, uint8_t channel);
static int8_t wifiSetEnterprise(uint8_t eapType,
const char* ssid, uint8_t ssid_len,
const char *username, const uint8_t username_len,
const char *password, const uint8_t password_len,
const char *identity, const uint8_t identity_len,
const char* ca_cert, uint16_t ca_cert_len);


static int16_t ping(uint32_t ipAddress, uint8_t ttl);

Expand Down
2 changes: 2 additions & 0 deletions src/utility/wifi_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ enum {
GET_SOCKET_CMD = 0x3F,

// All command with DATA_FLAG 0x40 send a 16bit Len
SET_ENT_CMD = 0x40,

SEND_DATA_TCP_CMD = 0x44,
GET_DATABUF_TCP_CMD = 0x45,
Expand Down Expand Up @@ -126,6 +127,7 @@ enum numParams{
PARAM_NUMS_3,
PARAM_NUMS_4,
PARAM_NUMS_5,
PARAM_NUMS_6,
MAX_PARAM_NUMS
};

Expand Down