一、wpa_supplicate介绍
WPA,是Wi-Fi Protected Access,Wi-Fi安全访问的简称。wpa_supplicant是开源项目源码,被谷歌修改后加入android移动平台,它主要是用来支持WEP,WPA/WPA2和WAPI无线协议和加密认证的。
WPA_Supplicant功能:通过socket(不管是wpa_supplicant与上层还是wpa_supplicant与驱动都采用socket通讯)与驱动交互上报数据给用户,而用户可以通过socket发送命令给wpa_supplicant调动驱动来对WiFi芯片操作。简单的说,wpa_supplicant就是wifi驱动和用户(wifi应用程序)的中间件,支持相关协议和加密认证。
wpa_supplicant是一个连接、配置WIFI的工具,它主要包含wpa_supplicant与wpa_cli两个程序。wpa_supplicant是服务端,wap_cli是客户端,一般情况下使用wpa_cli就可以操作WiFi。但是它不支持所有的驱动,可以浏览wpa_supplicant网站获得它所支持的驱动列表。另外,wpa_supplicant目前只能连接到那些你已经配置好SSID的无线网络,也就是使用前需要配置好wpa_supplicant的配置文件wpa_supplicant.conf。 wpa_supplicatnt内部模块构成如下:
重要模块有:
-
wpa_supplicant所有模块围绕事件(event loop模块)展开,它是基于事件驱动的。事件驱动:和消息驱动类似,主线程等待事件的发生并处理它们(wpa_supplicant没有使用多线程编程),所有事件处理都在主线程中完成。
-
位于event loop模块下方的driver i/f接口模块用于隔离和底层驱动直接交互的那些driver控制模块(如wext、ndiswrapper),称为driver wrapper,这种隔离作用,能最大程度保持平台以及驱动无关性,driver wrapper经常要返回一些信息给上层,这些信息通过driver event的方式反馈给wpa_supplicant其他模块处理。
-
wpa_supplicant实现了EAP和EAPOL状态机,此外,还定义了自己的状态机(WPA/WPA2 state machine)。
-
wpa_supplicant实现多种EAP方法,如EAP method模块,还包含TLS模块和crypto模块用于支持对应的EAP方法。
-
l2_packet模块用于收发EAPOL和EAP消息。
-
wpa_supplicant通过configuration模块配置参数。
-
wpa_supplicant是C/S结构中的server端,通过ctrl i/f模块向客户端提供通信接口。
wpa_supplicant源码位置:external/wpa_supplicant_8
二、wpa_supplicant相关接口
IfaceInfo
Structure describing the type and name of an iface controlled by the supplicant.
描述由请求方控制的 iface 的类型和名称的结构。
IfaceInfo文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceInfo.aidl
IfaceInfo定义:
parcelable IfaceInfo {}
IfaceType
List of Iface types supported.
IfaceType文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceType.aidl
IfaceType定义:
enum IfaceType {}
IpVersion
Enum values for IP version.
IpVersion 文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IpVersion.aidl
IpVersion 定义:
enum IpVersion {}
ISupplicant
Interface exposed by the supplicant AIDL service registered with the service manager. This is the root level object for any of the supplicant interactions.
向服务管理器注册的请求方 AIDL 服务公开的接口。这是任何请求方交互的根级别对象。
ISupplicant文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
ISupplicant定义:
interface ISupplicant{}
ISupplicantCallback
Callback Interface exposed by the supplicant service (ISupplicant).
请求方服务 (ISupplicant) 公开的回调接口。
ISupplicantCallback文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
ISupplicantCallback定义:
interface ISupplicantCallback{}
ISupplicantP2pIface
Interface exposed by the supplicant for each P2P mode network interface (e.g p2p0) it controls.
请求方为其控制的每个 P2P 模式网络接口(例如 p2p0)公开的接口。
ISupplicantP2pIface文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
ISupplicantP2pIface定义:
interface ISupplicantP2pIface{}
ISupplicantP2pIfaceCallback
Callback Interface exposed by the supplicant service for each P2P mode interface (ISupplicantP2pIface).
请求方服务为每个 P2P 模式接口公开的回调接口 (ISupplicantP2pIface)。
ISupplicantP2pIfaceCallback文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
ISupplicantP2pIfaceCallback定义:
interface ISupplicantP2pIfaceCallback{}
ISupplicantP2pNetwork
Interface exposed by the supplicant for each P2P mode network configuration it controls.
请求方为其控制的每个 P2P 模式网络配置公开的接口。
ISupplicantP2pNetwork文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
ISupplicantP2pNetwork定义:
interface ISupplicantP2pNetwork{}
ISupplicantStaIface
Interface exposed by the supplicant for each station mode network interface (e.g wlan0) it controls.
请求方为其控制的每个工作站模式网络接口(例如 wlan0)公开的接口。
ISupplicantStaIface文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
ISupplicantStaIface定义:
interface ISupplicantStaIface{}
ISupplicantStaIfaceCallback
Callback Interface exposed by the supplicant service for each station mode interface (ISupplicantStaIface).
请求方服务为每个工作站模式接口公开的回调接口 (ISupplicantStaIface)。
ISupplicantStaIfaceCallback文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
ISupplicantStaIfaceCallback定义:
interface ISupplicantStaIfaceCallback{}
ISupplicantStaNetwork
Interface exposed by the supplicant for each station mode network configuration it controls.
请求方为其控制的每个工作站模式网络配置公开的接口。
ISupplicantStaNetwork文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
ISupplicantStaNetwork定义:
interface ISupplicantStaNetwork{}
ISupplicantStaNetwork方法:
void disable();
void enable(in boolean noConnect);
void enableSaePkOnlyMode(in boolean enable);
void enableSuiteBEapOpenSslCiphers();
void enableTlsSuiteBEapPhase1Param(in boolean enable);
android.hardware.wifi.supplicant.AuthAlgMask getAuthAlg();
byte[] getBssid();
String getEapAltSubjectMatch();
byte[] getEapAnonymousIdentity();
String getEapCACert();
String getEapCAPath();
String getEapClientCert();
String getEapDomainSuffixMatch();
boolean getEapEngine();
String getEapEngineId();
byte[] getEapIdentity();
android.hardware.wifi.supplicant.EapMethod getEapMethod();
byte[] getEapPassword();
android.hardware.wifi.supplicant.EapPhase2Method getEapPhase2Method();
String getEapPrivateKeyId();
String getEapSubjectMatch();
boolean getEdmg();
android.hardware.wifi.supplicant.GroupCipherMask getGroupCipher();
android.hardware.wifi.supplicant.GroupMgmtCipherMask getGroupMgmtCipher();
int getId();
String getIdStr();
String getInterfaceName();
android.hardware.wifi.supplicant.KeyMgmtMask getKeyMgmt();
android.hardware.wifi.supplicant.OcspType getOcsp();
android.hardware.wifi.supplicant.PairwiseCipherMask getPairwiseCipher();
android.hardware.wifi.supplicant.ProtoMask getProto();
byte[] getPsk();
String getPskPassphrase();
boolean getRequirePmf();
String getSaePassword();
String getSaePasswordId();
boolean getScanSsid();
byte[] getSsid();
android.hardware.wifi.supplicant.IfaceType getType();
String getWapiCertSuite();
byte[] getWepKey(in int keyIdx);
int getWepTxKeyIdx();
byte[] getWpsNfcConfigurationToken();
void registerCallback(in android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback callback);
void select();
void sendNetworkEapIdentityResponse(in byte[] identity, in byte[] encryptedIdentity);
void sendNetworkEapSimGsmAuthFailure();
void sendNetworkEapSimGsmAuthResponse(in android.hardware.wifi.supplicant.NetworkResponseEapSimGsmAuthParams[] params);
void sendNetworkEapSimUmtsAuthFailure();
void sendNetworkEapSimUmtsAuthResponse(in android.hardware.wifi.supplicant.NetworkResponseEapSimUmtsAuthParams params);
void sendNetworkEapSimUmtsAutsResponse(in byte[] auts);
void setAuthAlg(in android.hardware.wifi.supplicant.AuthAlgMask authAlgMask);
void setBssid(in byte[] bssid);
void setDppKeys(in android.hardware.wifi.supplicant.DppConnectionKeys keys);
void setEapAltSubjectMatch(in String match);
void setEapAnonymousIdentity(in byte[] identity);
void setEapCACert(in String path);
void setEapCAPath(in String path);
void setEapClientCert(in String path);
void setEapDomainSuffixMatch(in String match);
void setEapEncryptedImsiIdentity(in byte[] identity);
void setEapEngine(in boolean enable);
void setEapEngineID(in String id);
void setEapErp(in boolean enable);
void setEapIdentity(in byte[] identity);
void setEapMethod(in android.hardware.wifi.supplicant.EapMethod method);
void setEapPassword(in byte[] password);
void setEapPhase2Method(in android.hardware.wifi.supplicant.EapPhase2Method method);
void setEapPrivateKeyId(in String id);
void setEapSubjectMatch(in String match);
void setEdmg(in boolean enable);
void setGroupCipher(in android.hardware.wifi.supplicant.GroupCipherMask groupCipherMask);
void setGroupMgmtCipher(in android.hardware.wifi.supplicant.GroupMgmtCipherMask groupMgmtCipherMask);
void setIdStr(in String idStr);
void setKeyMgmt(in android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask);
void setOcsp(in android.hardware.wifi.supplicant.OcspType ocspType);
void setPairwiseCipher(in android.hardware.wifi.supplicant.PairwiseCipherMask pairwiseCipherMask);
void setPmkCache(in byte[] serializedEntry);
void setProactiveKeyCaching(in boolean enable);
void setProto(in android.hardware.wifi.supplicant.ProtoMask protoMask);
void setPsk(in byte[] psk);
void setPskPassphrase(in String psk);
void setRequirePmf(in boolean enable);
void setSaeH2eMode(in android.hardware.wifi.supplicant.SaeH2eMode mode);
void setSaePassword(in String saePassword);
void setSaePasswordId(in String saePasswordId);
void setScanSsid(in boolean enable);
void setSsid(in byte[] ssid);
void setUpdateIdentifier(in int id);
void setWapiCertSuite(in String suite);
void setWepKey(in int keyIdx, in byte[] wepKey);
void setWepTxKeyIdx(in int keyIdx);
void setRoamingConsortiumSelection(in byte[] selectedRcoi);
ISupplicantStaNetworkCallback
Callback Interface exposed by the supplicant service for each network (ISupplicantStaNetwork).
由请求方服务为每个网络公开的回调接口 (ISupplicantStaNetwork)。
ISupplicantStaNetworkCallback文件路径:
hardware/interfaces/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
ISupplicantStaNetworkCallback定义:
interface ISupplicantStaNetworkCallback{}
ISupplicantStaNetworkCallback方法:
void onNetworkEapIdentityRequest();
void onNetworkEapSimGsmAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimGsmAuthParams params);
void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params);
void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind);
void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
三、wpa_supplicant命令
在Android平台,wpa_supplicant的客户端是位于Framework中的WifiService,用户在Settings界面进行wifi相关的操作最终都会经过WifiService通过发送命令的方式转交给pwa_supplicant执行,wpa_supplicant定义了许多命令,比如:
-
PING 客户端用它判断wpa_supplicant是否正常工作,wpa_supplicant收到需要回复PONG
-
MIB (Management Information Base),客户端用此命令获取设备的MIB信息
-
STATUS 客户端获取wpa_supplicant的工作状态
-
ADD_NETWORK 为wpa_supplicant添加一个新的无线网络,它将返回新网络的ID(从0开始),此network id后续被客户端用来指明想操作的无线网络
-
SET_NETWORK 用于设置指定无线网络的信息
-
ENABLE_NETWORK 使能某个无线网络
除了接收来自Client的命令,wpa_supplicant也会主动向Client发送命令
例如,wpa_supplicant需用户输入密码,这类命令称为Interactive Request
wpa_supplicant向客户端发送命令遵循以下格式:
CTRL-REQ-<field name>-<network id>-<human readable text>
四、wpa_supplicant.conf
wpa_supplicant.conf配置文件解析:
update_config=1 //是否允许wpa_supplicant更新(覆盖)配置
eapol_version=1 //IEEE 802.1X / EAPOL版本
ap_scan=1 //AP扫描/选择
passive_scan=0 //是否强制被动扫描进行网络连接
user_mpm=1 //MPM驻留
max_peer_links=99 //最大对等链路数(0-255;默认值:99)
mesh_max_inactivity=300 //检测STA不活动的超时(以秒为单位)(默认值:300秒)
cert_in_cb=1 //cert_in_cb - 是否在事件中包含对等证书转储
fast_reauth=1 //EAP快速重新认证
driver_param="field=value" //驱动程序接口参数
country=US //国家码
dot11RSNAConfigSATimeout=60 //PMKSA的最长寿命,以秒为单位; 默认43200
uuid=12345678-9abc-def0-1234-56789abcdef0 //设备的通用唯一标识符
auto_uuid=0 //自动UUID行为
device_name=Wireless Client //设备名称
manufacturer=Company //生产厂家
model_name=cmodel //型号名称
model_number=123 // 型号
serial_number=12345 //序列号
device_type=1-0050F204-1 //主要设备类型
os_version=01020300 //操作系统版本
config_methods=label virtual_display virtual_push_button keypad //配置方法
wps_cred_processing=0 //凭证处理
wps_vendor_ext_m1=000137100100020001 //WPS M1中的供应商属性,例如,Windows 7垂直配对
wps_nfc_dev_pw: Hexdump of Device Password //WPS的NFC密码令牌
wps_priority=0 //通过WPS添加网络的优先级
bss_max_count=200 //要保留在内存中的最大BSS条目数
filter_ssids=0 //filter_ssids - 基于SSID的扫描结果过滤
p2p_disabled=1 //禁用P2P功能
p2p_go_max_inactivity=300 //检测STA不活动的超时(以秒为单位)(默认值:300秒)
p2p_passphrase_len=8 //P2P GO的密码长度
p2p_search_delay=500 //并发P2P搜索迭代之间的额外延迟
okc=0 //机会密钥缓存(也称为主动密钥缓存)默认
pmf=0 //受保护的管理框架
sae_groups=21 20 19 26 25 //按优先顺序启用SAE有限循环组
dtim_period=2 //DTIM周期的默认值(如果未在网络块中覆盖)
beacon_int=100 //Beacon间隔的默认值(如果未在网络块中覆盖)
ap_vendor_elements=dd0411223301 //Beacon和Probe Response帧的其他供应商特定元素
ignore_old_scan_res=0 //忽略比请求更早的扫描结果
mac_addr=0 //MAC地址策略
rand_addr_lifetime=60 //随机MAC地址的生命周期,以秒为单位(默认值:60)
preassoc_mac_addr=0 //预关联操作的MAC地址策略(扫描,ANQP)
gas_rand_mac_addr=0 //GAS操作的MAC地址策略
gas_rand_addr_lifetime=60 //GAS随机MAC地址的生命周期(以秒为单位)
interworking=1 //启用互通
go_interworking=1 //启用互通的P2P GO广告
go_access_network_type=0 //P2P GO互通:接入网络类型
go_internet=1 //P2P GO互通:网络是否提供到Internet的连接
go_venue_group=7 go_venue_type=1 //p2p-go互通:群组场馆信息(可选)
hessid=00:11:22:33:44:55 //同源ESS标识符
auto_interworking=0 //自动网络选择行为
gas_address3=0 //GAS Address3字段行为
ftm_responder=0 // 在扩展功能元素位70中发布精确定时测量(FTM)响应器功能。
ftm_initiator=0 //在扩展功能元素位71中发布精确定时测量(FTM)启动器功能。
mbo_cell_capa=3 //MBO蜂窝数据功能
non_pref_chan=81:5:10:2 81:1:0:2 81:9:0:2 //多频段操作(MBO)非首选频道
oce=1 //优化的连接体验(OCE)
mem_only_psk=0 //mem_only_psk:是否仅在内存中保留PSK /密码
五、wpa_supplicant文件
wpa_supplicant的源码文件很多,下面列举一些主要的源码文件:
wpa_supplicant_8/wpa_supplicant/aidl/aidl.cpp
wpa_supplicant_8/wpa_supplicant/aidl/aidl_return_util.cpp
wpa_supplicant_8/wpa_supplicant/aidl/supplicant.cpp
wpa_supplicant_8/wpa_supplicant/aidl/aidl_manager.cpp
wpa_supplicant_8/wpa_supplicant/aidl/sta_iface.cpp
wpa_supplicant_8/wpa_supplicant/aidl/sta_network.cpp:
wpa_supplicant_8/wpa_supplicant/aidl/p2p_iface.cpp
wpa_supplicant_8/wpa_supplicant/aidl/p2p_network.cpp
wpa_supplicant_8/wpa_supplicant/scan.c
wpa_supplicant_8/wpa_supplicant/mesh.c
wpa_supplicant_8/wpa_supplicant/driver_i.h
wpa_supplicant_8/wpa_supplicant/wpa_supplicant.c
wpa_supplicant_8/wpa_supplicant/driver/driver_bsd.c