557-hostapd-support-Multi-AP-backhaul-STA-onboarding.patch 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. From 8b04a4cddbd6dbadb24279713af7ac677e80d342 Mon Sep 17 00:00:00 2001
  2. From: Davina Lu <[email protected]>
  3. Date: Tue, 2 Oct 2018 18:34:14 -0700
  4. Subject: [PATCH] hostapd: support Multi-AP backhaul STA onboarding
  5. The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
  6. backhaul STA through WPS. To enable this, the WPS registrar offers a
  7. different set of credentials (backhaul credentials instead of fronthaul
  8. credentials) when the Multi-AP subelement is present in the WFA vendor
  9. extension element of the WSC M1 message.
  10. Add 3 new configuration options to specify the backhaul credentials for
  11. the hostapd internal registrar: multi_ap_backhaul_ssid,
  12. multi_ap_backhaul_wpa_psk, multi_ap_backhaul_wpa_passphrase. These are
  13. only relevant for a fronthaul SSID, i.e. where multi_ap is set to 2 or
  14. 3. When these options are set, pass the backhaul credentials instead of
  15. the normal credentials when the Multi-AP subelement is present.
  16. Ignore the Multi-AP subelement if the backhaul config options are not
  17. set. Note that for an SSID which is fronthaul and backhaul at the same
  18. time (i.e., multi_ap == 3), this results in the correct credentials
  19. being sent anyway.
  20. The security to be used for the backaul BSS is fixed to WPA2PSK. The
  21. Multi-AP Specification only allows Open and WPA2PSK networks to be
  22. configured. Although not stated explicitly, the backhaul link is
  23. intended to be always encrypted, hence WPA2PSK.
  24. To build the credentials, the credential-building code is essentially
  25. copied and simplified. Indeed, the backhaul credentials are always
  26. WPA2PSK and never use per-device PSK. All the options set for the
  27. fronthaul BSS WPS are simply ignored.
  28. Signed-off-by: Davina Lu <[email protected]>
  29. Signed-off-by: Igor Mitsyanko <[email protected]>
  30. Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <[email protected]>
  31. ---
  32. v4: no change
  33. ---
  34. hostapd/config_file.c | 47 ++++++++++++++++++++++++++++++++++++++++
  35. hostapd/hostapd.conf | 9 ++++++++
  36. src/ap/ap_config.c | 2 ++
  37. src/ap/ap_config.h | 1 +
  38. src/ap/wps_hostapd.c | 26 ++++++++++++++++++++++
  39. src/wps/wps.h | 32 +++++++++++++++++++++++++++
  40. src/wps/wps_attr_parse.c | 11 ++++++++++
  41. src/wps/wps_attr_parse.h | 1 +
  42. src/wps/wps_dev_attr.c | 5 +++++
  43. src/wps/wps_dev_attr.h | 1 +
  44. src/wps/wps_registrar.c | 25 ++++++++++++++++++++-
  45. 11 files changed, 159 insertions(+), 1 deletion(-)
  46. --- a/hostapd/config_file.c
  47. +++ b/hostapd/config_file.c
  48. @@ -3479,6 +3479,53 @@ static int hostapd_config_fill(struct ho
  49. line, pos);
  50. return 1;
  51. }
  52. + } else if (os_strcmp(buf, "multi_ap_backhaul_ssid") == 0) {
  53. + size_t slen;
  54. + char *str = wpa_config_parse_string(pos, &slen);
  55. +
  56. + if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
  57. + wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
  58. + line, pos);
  59. + os_free(str);
  60. + return 1;
  61. + }
  62. + os_memcpy(bss->multi_ap_backhaul_ssid.ssid, str, slen);
  63. + bss->multi_ap_backhaul_ssid.ssid_len = slen;
  64. + bss->multi_ap_backhaul_ssid.ssid_set = 1;
  65. + os_free(str);
  66. + } else if (os_strcmp(buf, "multi_ap_backhaul_wpa_passphrase") == 0) {
  67. + int len = os_strlen(pos);
  68. +
  69. + if (len < 8 || len > 63) {
  70. + wpa_printf(MSG_ERROR,
  71. + "Line %d: invalid WPA passphrase length %d (expected 8..63)",
  72. + line, len);
  73. + return 1;
  74. + }
  75. + os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
  76. + bss->multi_ap_backhaul_ssid.wpa_passphrase = os_strdup(pos);
  77. + if (bss->multi_ap_backhaul_ssid.wpa_passphrase) {
  78. + hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
  79. + bss->multi_ap_backhaul_ssid.wpa_passphrase_set = 1;
  80. + }
  81. + } else if (os_strcmp(buf, "multi_ap_backhaul_wpa_psk") == 0) {
  82. + hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
  83. + bss->multi_ap_backhaul_ssid.wpa_psk =
  84. + os_zalloc(sizeof(struct hostapd_wpa_psk));
  85. + if (bss->multi_ap_backhaul_ssid.wpa_psk == NULL)
  86. + return 1;
  87. + if (hexstr2bin(pos, bss->multi_ap_backhaul_ssid.wpa_psk->psk,
  88. + PMK_LEN) ||
  89. + pos[PMK_LEN * 2] != '\0') {
  90. + wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
  91. + line, pos);
  92. + hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
  93. + return 1;
  94. + }
  95. + bss->multi_ap_backhaul_ssid.wpa_psk->group = 1;
  96. + os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
  97. + bss->multi_ap_backhaul_ssid.wpa_passphrase = NULL;
  98. + bss->multi_ap_backhaul_ssid.wpa_psk_set = 1;
  99. } else if (os_strcmp(buf, "upnp_iface") == 0) {
  100. os_free(bss->upnp_iface);
  101. bss->upnp_iface = os_strdup(pos);
  102. --- a/hostapd/hostapd.conf
  103. +++ b/hostapd/hostapd.conf
  104. @@ -1852,6 +1852,15 @@ own_ip_addr=127.0.0.1
  105. # attribute.
  106. #ap_settings=hostapd.ap_settings
  107. +# Multi-AP backhaul BSS config
  108. +# Used in WPS when multi_ap=2 or 3. Defines "backhaul BSS" credentials.
  109. +# These are passed in WPS M8 instead of the normal (fronthaul) credentials
  110. +# if the enrollee has the Multi-AP subelement set. Backhaul SSID is formatted
  111. +# like ssid2. The key is set like wpa_psk or wpa_passphrase.
  112. +#multi_ap_backhaul_ssid="backhaul"
  113. +#multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
  114. +#multi_ap_backhaul_wpa_passphrase=secret passphrase
  115. +
  116. # WPS UPnP interface
  117. # If set, support for external Registrars is enabled.
  118. #upnp_iface=br0
  119. --- a/src/ap/ap_config.c
  120. +++ b/src/ap/ap_config.c
  121. @@ -582,6 +582,8 @@ void hostapd_config_free_bss(struct host
  122. os_free(conf->ap_pin);
  123. os_free(conf->extra_cred);
  124. os_free(conf->ap_settings);
  125. + hostapd_config_clear_wpa_psk(&conf->multi_ap_backhaul_ssid.wpa_psk);
  126. + str_clear_free(conf->multi_ap_backhaul_ssid.wpa_passphrase);
  127. os_free(conf->upnp_iface);
  128. os_free(conf->friendly_name);
  129. os_free(conf->manufacturer_url);
  130. --- a/src/ap/ap_config.h
  131. +++ b/src/ap/ap_config.h
  132. @@ -456,6 +456,7 @@ struct hostapd_bss_config {
  133. int force_per_enrollee_psk;
  134. u8 *ap_settings;
  135. size_t ap_settings_len;
  136. + struct hostapd_ssid multi_ap_backhaul_ssid;
  137. char *upnp_iface;
  138. char *friendly_name;
  139. char *manufacturer_url;
  140. --- a/src/ap/wps_hostapd.c
  141. +++ b/src/ap/wps_hostapd.c
  142. @@ -962,6 +962,7 @@ static void hostapd_free_wps(struct wps_
  143. wpabuf_free(wps->dev.vendor_ext[i]);
  144. wps_device_data_free(&wps->dev);
  145. os_free(wps->network_key);
  146. + os_free(wps->multi_ap_backhaul_network_key);
  147. hostapd_wps_nfc_clear(wps);
  148. wpabuf_free(wps->dh_pubkey);
  149. wpabuf_free(wps->dh_privkey);
  150. @@ -1131,6 +1132,31 @@ int hostapd_init_wps(struct hostapd_data
  151. wps->encr_types_wpa = WPS_ENCR_AES | WPS_ENCR_TKIP;
  152. }
  153. + if (hapd->conf->multi_ap & FRONTHAUL_BSS &&
  154. + hapd->conf->multi_ap_backhaul_ssid.ssid_len) {
  155. + wps->multi_ap_backhaul_ssid_len =
  156. + hapd->conf->multi_ap_backhaul_ssid.ssid_len;
  157. + os_memcpy(wps->multi_ap_backhaul_ssid,
  158. + hapd->conf->multi_ap_backhaul_ssid.ssid,
  159. + wps->multi_ap_backhaul_ssid_len);
  160. + if (conf->multi_ap_backhaul_ssid.wpa_passphrase) {
  161. + wps->multi_ap_backhaul_network_key =
  162. + (u8 *) os_strdup(conf->multi_ap_backhaul_ssid.wpa_passphrase);
  163. + wps->multi_ap_backhaul_network_key_len =
  164. + os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase);
  165. + } else if (conf->multi_ap_backhaul_ssid.wpa_psk) {
  166. + wps->multi_ap_backhaul_network_key =
  167. + os_malloc(2 * PMK_LEN + 1);
  168. + if (wps->multi_ap_backhaul_network_key == NULL)
  169. + goto fail;
  170. + wpa_snprintf_hex((char *) wps->multi_ap_backhaul_network_key,
  171. + 2 * PMK_LEN + 1,
  172. + conf->multi_ap_backhaul_ssid.wpa_psk->psk,
  173. + PMK_LEN);
  174. + wps->multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
  175. + }
  176. + }
  177. +
  178. wps->ap_settings = conf->ap_settings;
  179. wps->ap_settings_len = conf->ap_settings_len;
  180. --- a/src/wps/wps.h
  181. +++ b/src/wps/wps.h
  182. @@ -100,6 +100,7 @@ struct wps_device_data {
  183. struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
  184. int p2p;
  185. + u8 multi_ap_ext;
  186. };
  187. /**
  188. @@ -730,6 +731,37 @@ struct wps_context {
  189. int psk_set;
  190. /**
  191. + * multi_ap_backhaul_ssid - SSID to supply to a Multi-AP backhaul
  192. + * enrollee
  193. + *
  194. + * This SSID is used by the Registrar to fill in information for
  195. + * Credentials when the enrollee advertises it is a Multi-AP backhaul
  196. + * STA.
  197. + */
  198. + u8 multi_ap_backhaul_ssid[SSID_MAX_LEN];
  199. +
  200. + /**
  201. + * multi_ap_backhaul_ssid_len - Length of multi_ap_backhaul_ssid in
  202. + * octets
  203. + */
  204. + size_t multi_ap_backhaul_ssid_len;
  205. +
  206. + /**
  207. + * multi_ap_backhaul_network_key - The Network Key (PSK) for the
  208. + * Multi-AP backhaul enrollee.
  209. + *
  210. + * This key can be either the ASCII passphrase (8..63 characters) or the
  211. + * 32-octet PSK (64 hex characters).
  212. + */
  213. + u8 *multi_ap_backhaul_network_key;
  214. +
  215. + /**
  216. + * multi_ap_backhaul_network_key_len - Length of
  217. + * multi_ap_backhaul_network_key in octets
  218. + */
  219. + size_t multi_ap_backhaul_network_key_len;
  220. +
  221. + /**
  222. * ap_settings - AP Settings override for M7 (only used at AP)
  223. *
  224. * If %NULL, AP Settings attributes will be generated based on the
  225. --- a/src/wps/wps_attr_parse.c
  226. +++ b/src/wps/wps_attr_parse.c
  227. @@ -67,6 +67,17 @@ static int wps_set_vendor_ext_wfa_subele
  228. }
  229. attr->registrar_configuration_methods = pos;
  230. break;
  231. + case WFA_ELEM_MULTI_AP:
  232. + if (len != 1) {
  233. + wpa_printf(MSG_DEBUG,
  234. + "WPS: Invalid Multi-AP Extension length %u",
  235. + len);
  236. + return -1;
  237. + }
  238. + attr->multi_ap_ext = *pos;
  239. + wpa_printf(MSG_DEBUG, "WPS: Multi-AP Extension 0x%02x",
  240. + attr->multi_ap_ext);
  241. + break;
  242. default:
  243. wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
  244. "Extension subelement %u", id);
  245. --- a/src/wps/wps_attr_parse.h
  246. +++ b/src/wps/wps_attr_parse.h
  247. @@ -97,6 +97,7 @@ struct wps_parse_attr {
  248. const u8 *cred[MAX_CRED_COUNT];
  249. const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
  250. const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
  251. + u8 multi_ap_ext;
  252. };
  253. int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
  254. --- a/src/wps/wps_dev_attr.c
  255. +++ b/src/wps/wps_dev_attr.c
  256. @@ -389,6 +389,11 @@ int wps_process_os_version(struct wps_de
  257. return 0;
  258. }
  259. +void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext)
  260. +{
  261. + dev->multi_ap_ext = ext;
  262. + wpa_printf(MSG_DEBUG, "WPS: Multi-AP extension value %02x", dev->multi_ap_ext);
  263. +}
  264. int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
  265. {
  266. --- a/src/wps/wps_dev_attr.h
  267. +++ b/src/wps/wps_dev_attr.h
  268. @@ -29,6 +29,7 @@ int wps_build_dev_name(struct wps_device
  269. int wps_process_device_attrs(struct wps_device_data *dev,
  270. struct wps_parse_attr *attr);
  271. int wps_process_os_version(struct wps_device_data *dev, const u8 *ver);
  272. +void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
  273. int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
  274. void wps_device_data_free(struct wps_device_data *dev);
  275. int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
  276. --- a/src/wps/wps_registrar.c
  277. +++ b/src/wps/wps_registrar.c
  278. @@ -1588,7 +1588,6 @@ int wps_build_credential_wrap(struct wpa
  279. return 0;
  280. }
  281. -
  282. int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
  283. {
  284. struct wpabuf *cred;
  285. @@ -1603,6 +1602,29 @@ int wps_build_cred(struct wps_data *wps,
  286. }
  287. os_memset(&wps->cred, 0, sizeof(wps->cred));
  288. + if (wps->peer_dev.multi_ap_ext == MULTI_AP_BACKHAUL_STA &&
  289. + wps->wps->multi_ap_backhaul_ssid_len) {
  290. + wpa_printf(MSG_DEBUG, "WPS: Use backhaul STA credentials");
  291. + os_memcpy(wps->cred.ssid, wps->wps->multi_ap_backhaul_ssid,
  292. + wps->wps->multi_ap_backhaul_ssid_len);
  293. + wps->cred.ssid_len = wps->wps->multi_ap_backhaul_ssid_len;
  294. + /* Backhaul is always WPA2PSK */
  295. + wps->cred.auth_type = WPS_AUTH_WPA2PSK;
  296. + wps->cred.encr_type = WPS_ENCR_AES;
  297. + /* Set MAC address in the Credential to be the Enrollee's MAC
  298. + * address
  299. + */
  300. + os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
  301. + if (wps->wps->multi_ap_backhaul_network_key) {
  302. + os_memcpy(wps->cred.key,
  303. + wps->wps->multi_ap_backhaul_network_key,
  304. + wps->wps->multi_ap_backhaul_network_key_len);
  305. + wps->cred.key_len =
  306. + wps->wps->multi_ap_backhaul_network_key_len;
  307. + }
  308. + goto use_provided;
  309. + }
  310. +
  311. os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
  312. wps->cred.ssid_len = wps->wps->ssid_len;
  313. @@ -2705,6 +2727,7 @@ static enum wps_process_res wps_process_
  314. wps->use_psk_key = 1;
  315. }
  316. #endif /* WPS_WORKAROUNDS */
  317. + wps_process_vendor_ext_m1(&wps->peer_dev, attr->multi_ap_ext);
  318. wps->state = SEND_M2;
  319. return WPS_CONTINUE;