wps_er.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098
  1. /*
  2. * Wi-Fi Protected Setup - External Registrar
  3. * Copyright (c) 2009-2013, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "base64.h"
  11. #include "uuid.h"
  12. #include "eloop.h"
  13. #include "httpread.h"
  14. #include "http_client.h"
  15. #include "http_server.h"
  16. #include "upnp_xml.h"
  17. #include "wps_i.h"
  18. #include "wps_upnp.h"
  19. #include "wps_upnp_i.h"
  20. #include "wps_er.h"
  21. static void wps_er_deinit_finish(void *eloop_data, void *user_ctx);
  22. static void wps_er_ap_timeout(void *eloop_data, void *user_ctx);
  23. static void wps_er_sta_timeout(void *eloop_data, void *user_ctx);
  24. static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg);
  25. static int wps_er_send_get_device_info(struct wps_er_ap *ap,
  26. void (*m1_handler)(struct wps_er_ap *ap,
  27. struct wpabuf *m1));
  28. static void wps_er_sta_event(struct wps_context *wps, struct wps_er_sta *sta,
  29. enum wps_event event)
  30. {
  31. union wps_event_data data;
  32. struct wps_event_er_enrollee *ev = &data.enrollee;
  33. if (wps->event_cb == NULL)
  34. return;
  35. os_memset(&data, 0, sizeof(data));
  36. ev->uuid = sta->uuid;
  37. ev->mac_addr = sta->addr;
  38. ev->m1_received = sta->m1_received;
  39. ev->config_methods = sta->config_methods;
  40. ev->dev_passwd_id = sta->dev_passwd_id;
  41. ev->pri_dev_type = sta->pri_dev_type;
  42. ev->dev_name = sta->dev_name;
  43. ev->manufacturer = sta->manufacturer;
  44. ev->model_name = sta->model_name;
  45. ev->model_number = sta->model_number;
  46. ev->serial_number = sta->serial_number;
  47. wps->event_cb(wps->cb_ctx, event, &data);
  48. }
  49. static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr,
  50. const u8 *uuid)
  51. {
  52. struct wps_er_sta *sta;
  53. dl_list_for_each(sta, &ap->sta, struct wps_er_sta, list) {
  54. if ((addr == NULL ||
  55. os_memcmp(sta->addr, addr, ETH_ALEN) == 0) &&
  56. (uuid == NULL ||
  57. os_memcmp(uuid, sta->uuid, WPS_UUID_LEN) == 0))
  58. return sta;
  59. }
  60. return NULL;
  61. }
  62. static void wps_er_sta_free(struct wps_er_sta *sta)
  63. {
  64. wps_er_sta_event(sta->ap->er->wps, sta, WPS_EV_ER_ENROLLEE_REMOVE);
  65. if (sta->wps)
  66. wps_deinit(sta->wps);
  67. os_free(sta->manufacturer);
  68. os_free(sta->model_name);
  69. os_free(sta->model_number);
  70. os_free(sta->serial_number);
  71. os_free(sta->dev_name);
  72. http_client_free(sta->http);
  73. eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
  74. os_free(sta->cred);
  75. os_free(sta);
  76. }
  77. static void wps_er_sta_remove_all(struct wps_er_ap *ap)
  78. {
  79. struct wps_er_sta *prev, *sta;
  80. dl_list_for_each_safe(sta, prev, &ap->sta, struct wps_er_sta, list)
  81. wps_er_sta_free(sta);
  82. }
  83. static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
  84. struct in_addr *addr, const u8 *uuid,
  85. const u8 *mac_addr)
  86. {
  87. struct wps_er_ap *ap;
  88. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  89. if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
  90. (uuid == NULL ||
  91. os_memcmp(uuid, ap->uuid, WPS_UUID_LEN) == 0) &&
  92. (mac_addr == NULL ||
  93. os_memcmp(mac_addr, ap->mac_addr, ETH_ALEN) == 0))
  94. return ap;
  95. }
  96. return NULL;
  97. }
  98. static struct wps_er_ap * wps_er_ap_get_id(struct wps_er *er, unsigned int id)
  99. {
  100. struct wps_er_ap *ap;
  101. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  102. if (ap->id == id)
  103. return ap;
  104. }
  105. return NULL;
  106. }
  107. static void wps_er_ap_event(struct wps_context *wps, struct wps_er_ap *ap,
  108. enum wps_event event)
  109. {
  110. union wps_event_data data;
  111. struct wps_event_er_ap *evap = &data.ap;
  112. if (wps->event_cb == NULL)
  113. return;
  114. os_memset(&data, 0, sizeof(data));
  115. evap->uuid = ap->uuid;
  116. evap->friendly_name = ap->friendly_name;
  117. evap->manufacturer = ap->manufacturer;
  118. evap->manufacturer_url = ap->manufacturer_url;
  119. evap->model_description = ap->model_description;
  120. evap->model_name = ap->model_name;
  121. evap->model_number = ap->model_number;
  122. evap->model_url = ap->model_url;
  123. evap->serial_number = ap->serial_number;
  124. evap->upc = ap->upc;
  125. evap->pri_dev_type = ap->pri_dev_type;
  126. evap->wps_state = ap->wps_state;
  127. evap->mac_addr = ap->mac_addr;
  128. wps->event_cb(wps->cb_ctx, event, &data);
  129. }
  130. static void wps_er_ap_free(struct wps_er_ap *ap)
  131. {
  132. http_client_free(ap->http);
  133. ap->http = NULL;
  134. os_free(ap->location);
  135. os_free(ap->friendly_name);
  136. os_free(ap->manufacturer);
  137. os_free(ap->manufacturer_url);
  138. os_free(ap->model_description);
  139. os_free(ap->model_name);
  140. os_free(ap->model_number);
  141. os_free(ap->model_url);
  142. os_free(ap->serial_number);
  143. os_free(ap->udn);
  144. os_free(ap->upc);
  145. os_free(ap->scpd_url);
  146. os_free(ap->control_url);
  147. os_free(ap->event_sub_url);
  148. os_free(ap->ap_settings);
  149. os_free(ap);
  150. }
  151. static void wps_er_ap_unsubscribed(struct wps_er *er, struct wps_er_ap *ap)
  152. {
  153. wpa_printf(MSG_DEBUG, "WPS ER: Unsubscribed from AP %s (%s)",
  154. inet_ntoa(ap->addr), ap->location);
  155. dl_list_del(&ap->list);
  156. wps_er_ap_free(ap);
  157. if (er->deinitializing && dl_list_empty(&er->ap_unsubscribing))
  158. wps_er_deinit_finish(er, NULL);
  159. }
  160. static void wps_er_http_unsubscribe_cb(void *ctx, struct http_client *c,
  161. enum http_client_event event)
  162. {
  163. struct wps_er_ap *ap = ctx;
  164. switch (event) {
  165. case HTTP_CLIENT_OK:
  166. wpa_printf(MSG_DEBUG, "WPS ER: Unsubscribed from events");
  167. ap->subscribed = 0;
  168. break;
  169. case HTTP_CLIENT_FAILED:
  170. case HTTP_CLIENT_INVALID_REPLY:
  171. case HTTP_CLIENT_TIMEOUT:
  172. wpa_printf(MSG_DEBUG, "WPS ER: Failed to unsubscribe from "
  173. "events");
  174. break;
  175. }
  176. http_client_free(ap->http);
  177. ap->http = NULL;
  178. /*
  179. * Need to get rid of the AP entry regardless of whether we managed to
  180. * unsubscribe cleanly or not.
  181. */
  182. wps_er_ap_unsubscribed(ap->er, ap);
  183. }
  184. static void wps_er_ap_unsubscribe(struct wps_er *er, struct wps_er_ap *ap)
  185. {
  186. struct wpabuf *req;
  187. struct sockaddr_in dst;
  188. char *url, *path;
  189. char sid[100];
  190. if (ap->event_sub_url == NULL) {
  191. wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot "
  192. "subscribe");
  193. goto fail;
  194. }
  195. if (ap->http) {
  196. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot "
  197. "send subscribe request");
  198. goto fail;
  199. }
  200. url = http_client_url_parse(ap->event_sub_url, &dst, &path);
  201. if (url == NULL) {
  202. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
  203. goto fail;
  204. }
  205. req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000);
  206. if (req == NULL) {
  207. os_free(url);
  208. goto fail;
  209. }
  210. uuid_bin2str(ap->sid, sid, sizeof(sid));
  211. wpabuf_printf(req,
  212. "UNSUBSCRIBE %s HTTP/1.1\r\n"
  213. "HOST: %s:%d\r\n"
  214. "SID: uuid:%s\r\n"
  215. "\r\n",
  216. path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port), sid);
  217. os_free(url);
  218. wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Unsubscription request",
  219. wpabuf_head(req), wpabuf_len(req));
  220. ap->http = http_client_addr(&dst, req, 1000,
  221. wps_er_http_unsubscribe_cb, ap);
  222. if (ap->http == NULL) {
  223. wpabuf_free(req);
  224. goto fail;
  225. }
  226. return;
  227. fail:
  228. /*
  229. * Need to get rid of the AP entry even when we fail to unsubscribe
  230. * cleanly.
  231. */
  232. wps_er_ap_unsubscribed(ap->er, ap);
  233. }
  234. static struct wps_er_ap_settings * wps_er_ap_get_settings(struct wps_er *er,
  235. const u8 *uuid)
  236. {
  237. struct wps_er_ap_settings *s;
  238. dl_list_for_each(s, &er->ap_settings, struct wps_er_ap_settings, list)
  239. if (os_memcmp(uuid, s->uuid, WPS_UUID_LEN) == 0)
  240. return s;
  241. return NULL;
  242. }
  243. int wps_er_ap_cache_settings(struct wps_er *er, struct in_addr *addr)
  244. {
  245. struct wps_er_ap *ap;
  246. struct wps_er_ap_settings *settings;
  247. ap = wps_er_ap_get(er, addr, NULL, NULL);
  248. if (ap == NULL || ap->ap_settings == NULL)
  249. return -1;
  250. settings = wps_er_ap_get_settings(er, ap->uuid);
  251. if (!settings) {
  252. settings = os_zalloc(sizeof(*settings));
  253. if (settings == NULL)
  254. return -1;
  255. os_memcpy(settings->uuid, ap->uuid, WPS_UUID_LEN);
  256. dl_list_add(&er->ap_settings, &settings->list);
  257. }
  258. os_memcpy(&settings->ap_settings, ap->ap_settings,
  259. sizeof(struct wps_credential));
  260. return 0;
  261. }
  262. static int wps_er_ap_use_cached_settings(struct wps_er *er,
  263. struct wps_er_ap *ap)
  264. {
  265. struct wps_er_ap_settings *s;
  266. if (ap->ap_settings)
  267. return 0;
  268. s = wps_er_ap_get_settings(ap->er, ap->uuid);
  269. if (!s)
  270. return -1;
  271. ap->ap_settings = os_malloc(sizeof(*ap->ap_settings));
  272. if (ap->ap_settings == NULL)
  273. return -1;
  274. os_memcpy(ap->ap_settings, &s->ap_settings, sizeof(*ap->ap_settings));
  275. wpa_printf(MSG_DEBUG, "WPS ER: Use cached AP settings");
  276. return 0;
  277. }
  278. static void wps_er_ap_remove_entry(struct wps_er *er, struct wps_er_ap *ap)
  279. {
  280. wpa_printf(MSG_DEBUG, "WPS ER: Removing AP entry for %s (%s)",
  281. inet_ntoa(ap->addr), ap->location);
  282. eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
  283. wps_er_sta_remove_all(ap);
  284. wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_REMOVE);
  285. http_client_free(ap->http);
  286. ap->http = NULL;
  287. if (ap->wps) {
  288. wps_deinit(ap->wps);
  289. ap->wps = NULL;
  290. }
  291. dl_list_del(&ap->list);
  292. if (ap->subscribed) {
  293. dl_list_add(&er->ap_unsubscribing, &ap->list);
  294. wps_er_ap_unsubscribe(er, ap);
  295. } else
  296. wps_er_ap_free(ap);
  297. }
  298. static void wps_er_ap_timeout(void *eloop_data, void *user_ctx)
  299. {
  300. struct wps_er *er = eloop_data;
  301. struct wps_er_ap *ap = user_ctx;
  302. wpa_printf(MSG_DEBUG, "WPS ER: AP advertisement timed out");
  303. wps_er_ap_remove_entry(er, ap);
  304. }
  305. static int wps_er_get_sid(struct wps_er_ap *ap, char *sid)
  306. {
  307. char *pos;
  308. char txt[100];
  309. if (!sid) {
  310. wpa_printf(MSG_DEBUG, "WPS ER: No SID received from %s (%s)",
  311. inet_ntoa(ap->addr), ap->location);
  312. return -1;
  313. }
  314. pos = os_strstr(sid, "uuid:");
  315. if (!pos) {
  316. wpa_printf(MSG_DEBUG, "WPS ER: Invalid SID received from "
  317. "%s (%s): '%s'", inet_ntoa(ap->addr), ap->location,
  318. sid);
  319. return -1;
  320. }
  321. pos += 5;
  322. if (uuid_str2bin(pos, ap->sid) < 0) {
  323. wpa_printf(MSG_DEBUG, "WPS ER: Invalid SID received from "
  324. "%s (%s): '%s'", inet_ntoa(ap->addr), ap->location,
  325. sid);
  326. return -1;
  327. }
  328. uuid_bin2str(ap->sid, txt, sizeof(txt));
  329. wpa_printf(MSG_DEBUG, "WPS ER: SID for subscription with %s (%s): %s",
  330. inet_ntoa(ap->addr), ap->location, txt);
  331. return 0;
  332. }
  333. static void wps_er_http_subscribe_cb(void *ctx, struct http_client *c,
  334. enum http_client_event event)
  335. {
  336. struct wps_er_ap *ap = ctx;
  337. switch (event) {
  338. case HTTP_CLIENT_OK:
  339. wpa_printf(MSG_DEBUG, "WPS ER: Subscribed to events");
  340. ap->subscribed = 1;
  341. wps_er_get_sid(ap, http_client_get_hdr_line(c, "SID"));
  342. wps_er_ap_use_cached_settings(ap->er, ap);
  343. wps_er_ap_event(ap->er->wps, ap, WPS_EV_ER_AP_ADD);
  344. break;
  345. case HTTP_CLIENT_FAILED:
  346. case HTTP_CLIENT_INVALID_REPLY:
  347. case HTTP_CLIENT_TIMEOUT:
  348. wpa_printf(MSG_DEBUG, "WPS ER: Failed to subscribe to events");
  349. break;
  350. }
  351. http_client_free(ap->http);
  352. ap->http = NULL;
  353. }
  354. static void wps_er_subscribe(struct wps_er_ap *ap)
  355. {
  356. struct wpabuf *req;
  357. struct sockaddr_in dst;
  358. char *url, *path;
  359. if (ap->event_sub_url == NULL) {
  360. wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot "
  361. "subscribe");
  362. return;
  363. }
  364. if (ap->http) {
  365. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot "
  366. "send subscribe request");
  367. return;
  368. }
  369. url = http_client_url_parse(ap->event_sub_url, &dst, &path);
  370. if (url == NULL) {
  371. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
  372. return;
  373. }
  374. req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000);
  375. if (req == NULL) {
  376. os_free(url);
  377. return;
  378. }
  379. wpabuf_printf(req,
  380. "SUBSCRIBE %s HTTP/1.1\r\n"
  381. "HOST: %s:%d\r\n"
  382. "CALLBACK: <http://%s:%d/event/%u/%u>\r\n"
  383. "NT: upnp:event\r\n"
  384. "TIMEOUT: Second-%d\r\n"
  385. "\r\n",
  386. path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port),
  387. ap->er->ip_addr_text, ap->er->http_port,
  388. ap->er->event_id, ap->id, 1800);
  389. os_free(url);
  390. wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Subscription request",
  391. wpabuf_head(req), wpabuf_len(req));
  392. ap->http = http_client_addr(&dst, req, 1000, wps_er_http_subscribe_cb,
  393. ap);
  394. if (ap->http == NULL)
  395. wpabuf_free(req);
  396. }
  397. static void wps_er_ap_get_m1(struct wps_er_ap *ap, struct wpabuf *m1)
  398. {
  399. struct wps_parse_attr attr;
  400. if (wps_parse_msg(m1, &attr) < 0) {
  401. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse M1");
  402. return;
  403. }
  404. if (attr.primary_dev_type)
  405. os_memcpy(ap->pri_dev_type, attr.primary_dev_type, 8);
  406. if (attr.wps_state)
  407. ap->wps_state = *attr.wps_state;
  408. if (attr.mac_addr)
  409. os_memcpy(ap->mac_addr, attr.mac_addr, ETH_ALEN);
  410. wps_er_subscribe(ap);
  411. }
  412. static void wps_er_get_device_info(struct wps_er_ap *ap)
  413. {
  414. wps_er_send_get_device_info(ap, wps_er_ap_get_m1);
  415. }
  416. static const char * wps_er_find_wfadevice(const char *data)
  417. {
  418. const char *tag, *tagname, *end;
  419. char *val;
  420. int found = 0;
  421. while (!found) {
  422. /* Find next <device> */
  423. for (;;) {
  424. if (xml_next_tag(data, &tag, &tagname, &end))
  425. return NULL;
  426. data = end;
  427. if (!os_strncasecmp(tagname, "device", 6) &&
  428. *tag != '/' &&
  429. (tagname[6] == '>' || !isgraph(tagname[6]))) {
  430. break;
  431. }
  432. }
  433. /* Check whether deviceType is WFADevice */
  434. val = xml_get_first_item(data, "deviceType");
  435. if (val == NULL)
  436. return NULL;
  437. wpa_printf(MSG_DEBUG, "WPS ER: Found deviceType '%s'", val);
  438. found = os_strcasecmp(val, "urn:schemas-wifialliance-org:"
  439. "device:WFADevice:1") == 0;
  440. os_free(val);
  441. }
  442. return data;
  443. }
  444. static void wps_er_parse_device_description(struct wps_er_ap *ap,
  445. struct wpabuf *reply)
  446. {
  447. /* Note: reply includes null termination after the buffer data */
  448. const char *tmp, *data = wpabuf_head(reply);
  449. char *pos;
  450. wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Device info",
  451. wpabuf_head(reply), wpabuf_len(reply));
  452. /*
  453. * The root device description may include multiple devices, so first
  454. * find the beginning of the WFADevice description to allow the
  455. * simplistic parser to pick the correct entries.
  456. */
  457. tmp = wps_er_find_wfadevice(data);
  458. if (tmp == NULL) {
  459. wpa_printf(MSG_DEBUG, "WPS ER: WFADevice:1 device not found - "
  460. "trying to parse invalid data");
  461. } else
  462. data = tmp;
  463. ap->friendly_name = xml_get_first_item(data, "friendlyName");
  464. wpa_printf(MSG_DEBUG, "WPS ER: friendlyName='%s'", ap->friendly_name);
  465. ap->manufacturer = xml_get_first_item(data, "manufacturer");
  466. wpa_printf(MSG_DEBUG, "WPS ER: manufacturer='%s'", ap->manufacturer);
  467. ap->manufacturer_url = xml_get_first_item(data, "manufacturerURL");
  468. wpa_printf(MSG_DEBUG, "WPS ER: manufacturerURL='%s'",
  469. ap->manufacturer_url);
  470. ap->model_description = xml_get_first_item(data, "modelDescription");
  471. wpa_printf(MSG_DEBUG, "WPS ER: modelDescription='%s'",
  472. ap->model_description);
  473. ap->model_name = xml_get_first_item(data, "modelName");
  474. wpa_printf(MSG_DEBUG, "WPS ER: modelName='%s'", ap->model_name);
  475. ap->model_number = xml_get_first_item(data, "modelNumber");
  476. wpa_printf(MSG_DEBUG, "WPS ER: modelNumber='%s'", ap->model_number);
  477. ap->model_url = xml_get_first_item(data, "modelURL");
  478. wpa_printf(MSG_DEBUG, "WPS ER: modelURL='%s'", ap->model_url);
  479. ap->serial_number = xml_get_first_item(data, "serialNumber");
  480. wpa_printf(MSG_DEBUG, "WPS ER: serialNumber='%s'", ap->serial_number);
  481. ap->udn = xml_get_first_item(data, "UDN");
  482. wpa_printf(MSG_DEBUG, "WPS ER: UDN='%s'", ap->udn);
  483. pos = os_strstr(ap->udn, "uuid:");
  484. if (pos) {
  485. pos += 5;
  486. if (uuid_str2bin(pos, ap->uuid) < 0)
  487. wpa_printf(MSG_DEBUG, "WPS ER: Invalid UUID in UDN");
  488. }
  489. ap->upc = xml_get_first_item(data, "UPC");
  490. wpa_printf(MSG_DEBUG, "WPS ER: UPC='%s'", ap->upc);
  491. ap->scpd_url = http_link_update(
  492. xml_get_first_item(data, "SCPDURL"), ap->location);
  493. wpa_printf(MSG_DEBUG, "WPS ER: SCPDURL='%s'", ap->scpd_url);
  494. ap->control_url = http_link_update(
  495. xml_get_first_item(data, "controlURL"), ap->location);
  496. wpa_printf(MSG_DEBUG, "WPS ER: controlURL='%s'", ap->control_url);
  497. ap->event_sub_url = http_link_update(
  498. xml_get_first_item(data, "eventSubURL"), ap->location);
  499. wpa_printf(MSG_DEBUG, "WPS ER: eventSubURL='%s'", ap->event_sub_url);
  500. }
  501. static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c,
  502. enum http_client_event event)
  503. {
  504. struct wps_er_ap *ap = ctx;
  505. struct wpabuf *reply;
  506. int ok = 0;
  507. switch (event) {
  508. case HTTP_CLIENT_OK:
  509. reply = http_client_get_body(c);
  510. if (reply == NULL)
  511. break;
  512. wps_er_parse_device_description(ap, reply);
  513. ok = 1;
  514. break;
  515. case HTTP_CLIENT_FAILED:
  516. case HTTP_CLIENT_INVALID_REPLY:
  517. case HTTP_CLIENT_TIMEOUT:
  518. wpa_printf(MSG_DEBUG, "WPS ER: Failed to fetch device info");
  519. break;
  520. }
  521. http_client_free(ap->http);
  522. ap->http = NULL;
  523. if (ok)
  524. wps_er_get_device_info(ap);
  525. }
  526. void wps_er_ap_add(struct wps_er *er, const u8 *uuid, struct in_addr *addr,
  527. const char *location, int max_age)
  528. {
  529. struct wps_er_ap *ap;
  530. ap = wps_er_ap_get(er, addr, uuid, NULL);
  531. if (ap) {
  532. /* Update advertisement timeout */
  533. eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
  534. eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap);
  535. return;
  536. }
  537. ap = os_zalloc(sizeof(*ap));
  538. if (ap == NULL)
  539. return;
  540. dl_list_init(&ap->sta);
  541. ap->er = er;
  542. ap->id = ++er->next_ap_id;
  543. ap->location = os_strdup(location);
  544. if (ap->location == NULL) {
  545. os_free(ap);
  546. return;
  547. }
  548. dl_list_add(&er->ap, &ap->list);
  549. ap->addr.s_addr = addr->s_addr;
  550. os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
  551. eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap);
  552. wpa_printf(MSG_DEBUG, "WPS ER: Added AP entry for %s (%s)",
  553. inet_ntoa(ap->addr), ap->location);
  554. /* Fetch device description */
  555. ap->http = http_client_url(ap->location, NULL, 10000,
  556. wps_er_http_dev_desc_cb, ap);
  557. }
  558. void wps_er_ap_remove(struct wps_er *er, struct in_addr *addr)
  559. {
  560. struct wps_er_ap *ap;
  561. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  562. if (ap->addr.s_addr == addr->s_addr) {
  563. wps_er_ap_remove_entry(er, ap);
  564. return;
  565. }
  566. }
  567. }
  568. static void wps_er_ap_remove_all(struct wps_er *er)
  569. {
  570. struct wps_er_ap *prev, *ap;
  571. struct wps_er_ap_settings *prev_s, *s;
  572. dl_list_for_each_safe(ap, prev, &er->ap, struct wps_er_ap, list)
  573. wps_er_ap_remove_entry(er, ap);
  574. dl_list_for_each_safe(s, prev_s, &er->ap_settings,
  575. struct wps_er_ap_settings, list)
  576. os_free(s);
  577. }
  578. static void http_put_date(struct wpabuf *buf)
  579. {
  580. wpabuf_put_str(buf, "Date: ");
  581. format_date(buf);
  582. wpabuf_put_str(buf, "\r\n");
  583. }
  584. static void wps_er_http_resp_not_found(struct http_request *req)
  585. {
  586. struct wpabuf *buf;
  587. buf = wpabuf_alloc(200);
  588. if (buf == NULL) {
  589. http_request_deinit(req);
  590. return;
  591. }
  592. wpabuf_put_str(buf,
  593. "HTTP/1.1 404 Not Found\r\n"
  594. "Server: unspecified, UPnP/1.0, unspecified\r\n"
  595. "Connection: close\r\n");
  596. http_put_date(buf);
  597. wpabuf_put_str(buf, "\r\n");
  598. http_request_send_and_deinit(req, buf);
  599. }
  600. static void wps_er_http_resp_ok(struct http_request *req)
  601. {
  602. struct wpabuf *buf;
  603. buf = wpabuf_alloc(200);
  604. if (buf == NULL) {
  605. http_request_deinit(req);
  606. return;
  607. }
  608. wpabuf_put_str(buf,
  609. "HTTP/1.1 200 OK\r\n"
  610. "Server: unspecified, UPnP/1.0, unspecified\r\n"
  611. "Connection: close\r\n"
  612. "Content-Length: 0\r\n");
  613. http_put_date(buf);
  614. wpabuf_put_str(buf, "\r\n");
  615. http_request_send_and_deinit(req, buf);
  616. }
  617. static void wps_er_sta_timeout(void *eloop_data, void *user_ctx)
  618. {
  619. struct wps_er_sta *sta = eloop_data;
  620. wpa_printf(MSG_DEBUG, "WPS ER: STA entry timed out");
  621. dl_list_del(&sta->list);
  622. wps_er_sta_free(sta);
  623. }
  624. static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
  625. const u8 *addr,
  626. struct wps_parse_attr *attr,
  627. int probe_req)
  628. {
  629. struct wps_er_sta *sta = wps_er_sta_get(ap, addr, NULL);
  630. int new_sta = 0;
  631. int m1;
  632. m1 = !probe_req && attr->msg_type && *attr->msg_type == WPS_M1;
  633. if (sta == NULL) {
  634. /*
  635. * Only allow new STA entry to be added based on Probe Request
  636. * or M1. This will filter out bogus events and anything that
  637. * may have been ongoing at the time ER subscribed for events.
  638. */
  639. if (!probe_req && !m1)
  640. return NULL;
  641. sta = os_zalloc(sizeof(*sta));
  642. if (sta == NULL)
  643. return NULL;
  644. os_memcpy(sta->addr, addr, ETH_ALEN);
  645. sta->ap = ap;
  646. dl_list_add(&ap->sta, &sta->list);
  647. new_sta = 1;
  648. }
  649. if (m1)
  650. sta->m1_received = 1;
  651. if (attr->config_methods && (!probe_req || !sta->m1_received))
  652. sta->config_methods = WPA_GET_BE16(attr->config_methods);
  653. if (attr->uuid_e && (!probe_req || !sta->m1_received))
  654. os_memcpy(sta->uuid, attr->uuid_e, WPS_UUID_LEN);
  655. if (attr->primary_dev_type && (!probe_req || !sta->m1_received))
  656. os_memcpy(sta->pri_dev_type, attr->primary_dev_type, 8);
  657. if (attr->dev_password_id && (!probe_req || !sta->m1_received))
  658. sta->dev_passwd_id = WPA_GET_BE16(attr->dev_password_id);
  659. if (attr->manufacturer) {
  660. os_free(sta->manufacturer);
  661. sta->manufacturer = dup_binstr(attr->manufacturer,
  662. attr->manufacturer_len);
  663. }
  664. if (attr->model_name) {
  665. os_free(sta->model_name);
  666. sta->model_name = dup_binstr(attr->model_name,
  667. attr->model_name_len);
  668. }
  669. if (attr->model_number) {
  670. os_free(sta->model_number);
  671. sta->model_number = dup_binstr(attr->model_number,
  672. attr->model_number_len);
  673. }
  674. if (attr->serial_number) {
  675. os_free(sta->serial_number);
  676. sta->serial_number = dup_binstr(attr->serial_number,
  677. attr->serial_number_len);
  678. }
  679. if (attr->dev_name) {
  680. os_free(sta->dev_name);
  681. sta->dev_name = dup_binstr(attr->dev_name, attr->dev_name_len);
  682. }
  683. eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
  684. eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL);
  685. if (m1 || new_sta)
  686. wps_er_sta_event(ap->er->wps, sta, WPS_EV_ER_ENROLLEE_ADD);
  687. return sta;
  688. }
  689. static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
  690. const u8 *addr,
  691. struct wpabuf *msg)
  692. {
  693. struct wps_parse_attr attr;
  694. wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - Probe Request - from "
  695. MACSTR, MAC2STR(addr));
  696. wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
  697. "(TLVs from Probe Request)", msg);
  698. if (wps_validate_probe_req(msg, addr) < 0) {
  699. wpa_printf(MSG_INFO, "WPS-STRICT: ER: Ignore invalid proxied "
  700. "Probe Request frame from " MACSTR, MAC2STR(addr));
  701. return;
  702. }
  703. if (wps_parse_msg(msg, &attr) < 0) {
  704. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
  705. "WLANEvent message");
  706. return;
  707. }
  708. wps_er_add_sta_data(ap, addr, &attr, 1);
  709. wps_registrar_probe_req_rx(ap->er->wps->registrar, addr, msg, 0);
  710. }
  711. static void wps_er_http_put_wlan_response_cb(void *ctx, struct http_client *c,
  712. enum http_client_event event)
  713. {
  714. struct wps_er_sta *sta = ctx;
  715. switch (event) {
  716. case HTTP_CLIENT_OK:
  717. wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse OK");
  718. break;
  719. case HTTP_CLIENT_FAILED:
  720. case HTTP_CLIENT_INVALID_REPLY:
  721. case HTTP_CLIENT_TIMEOUT:
  722. wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse failed");
  723. break;
  724. }
  725. http_client_free(sta->http);
  726. sta->http = NULL;
  727. }
  728. static const char *soap_prefix =
  729. "<?xml version=\"1.0\"?>\n"
  730. "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
  731. "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
  732. "<s:Body>\n";
  733. static const char *soap_postfix =
  734. "</s:Body>\n</s:Envelope>\n";
  735. static const char *urn_wfawlanconfig =
  736. "urn:schemas-wifialliance-org:service:WFAWLANConfig:1";
  737. static struct wpabuf * wps_er_soap_hdr(const struct wpabuf *msg,
  738. const char *name, const char *arg_name,
  739. const char *path,
  740. const struct sockaddr_in *dst,
  741. char **len_ptr, char **body_ptr)
  742. {
  743. unsigned char *encoded;
  744. size_t encoded_len;
  745. struct wpabuf *buf;
  746. if (msg) {
  747. encoded = base64_encode(wpabuf_head(msg), wpabuf_len(msg),
  748. &encoded_len);
  749. if (encoded == NULL)
  750. return NULL;
  751. } else {
  752. encoded = NULL;
  753. encoded_len = 0;
  754. }
  755. buf = wpabuf_alloc(1000 + encoded_len);
  756. if (buf == NULL) {
  757. os_free(encoded);
  758. return NULL;
  759. }
  760. wpabuf_printf(buf,
  761. "POST %s HTTP/1.1\r\n"
  762. "Host: %s:%d\r\n"
  763. "Content-Type: text/xml; charset=\"utf-8\"\r\n"
  764. "Content-Length: ",
  765. path, inet_ntoa(dst->sin_addr), ntohs(dst->sin_port));
  766. *len_ptr = wpabuf_put(buf, 0);
  767. wpabuf_printf(buf,
  768. " \r\n"
  769. "SOAPACTION: \"%s#%s\"\r\n"
  770. "\r\n",
  771. urn_wfawlanconfig, name);
  772. *body_ptr = wpabuf_put(buf, 0);
  773. wpabuf_put_str(buf, soap_prefix);
  774. wpabuf_printf(buf, "<u:%s xmlns:u=\"", name);
  775. wpabuf_put_str(buf, urn_wfawlanconfig);
  776. wpabuf_put_str(buf, "\">\n");
  777. if (encoded) {
  778. wpabuf_printf(buf, "<%s>%s</%s>\n",
  779. arg_name, (char *) encoded, arg_name);
  780. os_free(encoded);
  781. }
  782. return buf;
  783. }
  784. static void wps_er_soap_end(struct wpabuf *buf, const char *name,
  785. char *len_ptr, char *body_ptr)
  786. {
  787. char len_buf[10];
  788. wpabuf_printf(buf, "</u:%s>\n", name);
  789. wpabuf_put_str(buf, soap_postfix);
  790. os_snprintf(len_buf, sizeof(len_buf), "%d",
  791. (int) ((char *) wpabuf_put(buf, 0) - body_ptr));
  792. os_memcpy(len_ptr, len_buf, os_strlen(len_buf));
  793. }
  794. static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
  795. {
  796. struct wpabuf *buf;
  797. char *len_ptr, *body_ptr;
  798. struct sockaddr_in dst;
  799. char *url, *path;
  800. if (sta->http) {
  801. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for STA - "
  802. "ignore new request");
  803. wpabuf_free(msg);
  804. return;
  805. }
  806. if (sta->ap->control_url == NULL) {
  807. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  808. wpabuf_free(msg);
  809. return;
  810. }
  811. url = http_client_url_parse(sta->ap->control_url, &dst, &path);
  812. if (url == NULL) {
  813. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
  814. wpabuf_free(msg);
  815. return;
  816. }
  817. buf = wps_er_soap_hdr(msg, "PutWLANResponse", "NewMessage", path, &dst,
  818. &len_ptr, &body_ptr);
  819. wpabuf_free(msg);
  820. os_free(url);
  821. if (buf == NULL)
  822. return;
  823. wpabuf_printf(buf, "<NewWLANEventType>%d</NewWLANEventType>\n",
  824. UPNP_WPS_WLANEVENT_TYPE_EAP);
  825. wpabuf_printf(buf, "<NewWLANEventMAC>" MACSTR "</NewWLANEventMAC>\n",
  826. MAC2STR(sta->addr));
  827. wps_er_soap_end(buf, "PutWLANResponse", len_ptr, body_ptr);
  828. sta->http = http_client_addr(&dst, buf, 1000,
  829. wps_er_http_put_wlan_response_cb, sta);
  830. if (sta->http == NULL)
  831. wpabuf_free(buf);
  832. }
  833. static void wps_er_sta_process(struct wps_er_sta *sta, struct wpabuf *msg,
  834. enum wsc_op_code op_code)
  835. {
  836. enum wps_process_res res;
  837. res = wps_process_msg(sta->wps, op_code, msg);
  838. if (res == WPS_CONTINUE) {
  839. struct wpabuf *next = wps_get_msg(sta->wps, &op_code);
  840. if (next)
  841. wps_er_sta_send_msg(sta, next);
  842. } else {
  843. wpa_printf(MSG_DEBUG, "WPS ER: Protocol run %s with the "
  844. "enrollee (res=%d)",
  845. res == WPS_DONE ? "succeeded" : "failed", res);
  846. wps_deinit(sta->wps);
  847. sta->wps = NULL;
  848. if (res == WPS_DONE) {
  849. /* Remove the STA entry after short timeout */
  850. eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
  851. eloop_register_timeout(10, 0, wps_er_sta_timeout, sta,
  852. NULL);
  853. }
  854. }
  855. }
  856. static void wps_er_sta_start(struct wps_er_sta *sta, struct wpabuf *msg)
  857. {
  858. struct wps_config cfg;
  859. if (sta->wps)
  860. wps_deinit(sta->wps);
  861. os_memset(&cfg, 0, sizeof(cfg));
  862. cfg.wps = sta->ap->er->wps;
  863. cfg.registrar = 1;
  864. cfg.peer_addr = sta->addr;
  865. sta->wps = wps_init(&cfg);
  866. if (sta->wps == NULL)
  867. return;
  868. sta->wps->er = 1;
  869. sta->wps->use_cred = sta->ap->ap_settings;
  870. if (sta->ap->ap_settings) {
  871. os_free(sta->cred);
  872. sta->cred = os_malloc(sizeof(*sta->cred));
  873. if (sta->cred) {
  874. os_memcpy(sta->cred, sta->ap->ap_settings,
  875. sizeof(*sta->cred));
  876. sta->cred->cred_attr = NULL;
  877. os_memcpy(sta->cred->mac_addr, sta->addr, ETH_ALEN);
  878. sta->wps->use_cred = sta->cred;
  879. }
  880. }
  881. wps_er_sta_process(sta, msg, WSC_MSG);
  882. }
  883. static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr,
  884. struct wpabuf *msg)
  885. {
  886. struct wps_parse_attr attr;
  887. struct wps_er_sta *sta;
  888. wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR,
  889. MAC2STR(addr));
  890. wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
  891. "(TLVs from EAP-WSC)", msg);
  892. if (wps_parse_msg(msg, &attr) < 0) {
  893. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
  894. "WLANEvent message");
  895. return;
  896. }
  897. sta = wps_er_add_sta_data(ap, addr, &attr, 0);
  898. if (sta == NULL)
  899. return;
  900. if (attr.msg_type && *attr.msg_type == WPS_M1)
  901. wps_er_sta_start(sta, msg);
  902. else if (sta->wps) {
  903. enum wsc_op_code op_code = WSC_MSG;
  904. if (attr.msg_type) {
  905. switch (*attr.msg_type) {
  906. case WPS_WSC_ACK:
  907. op_code = WSC_ACK;
  908. break;
  909. case WPS_WSC_NACK:
  910. op_code = WSC_NACK;
  911. break;
  912. case WPS_WSC_DONE:
  913. op_code = WSC_Done;
  914. break;
  915. }
  916. }
  917. wps_er_sta_process(sta, msg, op_code);
  918. }
  919. }
  920. static void wps_er_process_wlanevent(struct wps_er_ap *ap,
  921. struct wpabuf *event)
  922. {
  923. u8 *data;
  924. u8 wlan_event_type;
  925. u8 wlan_event_mac[ETH_ALEN];
  926. struct wpabuf msg;
  927. wpa_hexdump(MSG_MSGDUMP, "WPS ER: Received WLANEvent",
  928. wpabuf_head(event), wpabuf_len(event));
  929. if (wpabuf_len(event) < 1 + 17) {
  930. wpa_printf(MSG_DEBUG, "WPS ER: Too short WLANEvent");
  931. return;
  932. }
  933. data = wpabuf_mhead(event);
  934. wlan_event_type = data[0];
  935. if (hwaddr_aton((char *) data + 1, wlan_event_mac) < 0) {
  936. wpa_printf(MSG_DEBUG, "WPS ER: Invalid WLANEventMAC in "
  937. "WLANEvent");
  938. return;
  939. }
  940. wpabuf_set(&msg, data + 1 + 17, wpabuf_len(event) - (1 + 17));
  941. switch (wlan_event_type) {
  942. case 1:
  943. wps_er_process_wlanevent_probe_req(ap, wlan_event_mac, &msg);
  944. break;
  945. case 2:
  946. wps_er_process_wlanevent_eap(ap, wlan_event_mac, &msg);
  947. break;
  948. default:
  949. wpa_printf(MSG_DEBUG, "WPS ER: Unknown WLANEventType %d",
  950. wlan_event_type);
  951. break;
  952. }
  953. }
  954. static void wps_er_http_event(struct wps_er *er, struct http_request *req,
  955. unsigned int ap_id)
  956. {
  957. struct wps_er_ap *ap = wps_er_ap_get_id(er, ap_id);
  958. struct wpabuf *event;
  959. enum http_reply_code ret;
  960. if (ap == NULL) {
  961. wpa_printf(MSG_DEBUG, "WPS ER: HTTP event from unknown AP id "
  962. "%u", ap_id);
  963. wps_er_http_resp_not_found(req);
  964. return;
  965. }
  966. wpa_printf(MSG_MSGDUMP, "WPS ER: HTTP event from AP id %u: %s",
  967. ap_id, http_request_get_data(req));
  968. event = xml_get_base64_item(http_request_get_data(req), "WLANEvent",
  969. &ret);
  970. if (event == NULL) {
  971. wpa_printf(MSG_DEBUG, "WPS ER: Could not extract WLANEvent "
  972. "from the event notification");
  973. /*
  974. * Reply with OK anyway to avoid getting unregistered from
  975. * events.
  976. */
  977. wps_er_http_resp_ok(req);
  978. return;
  979. }
  980. wps_er_process_wlanevent(ap, event);
  981. wpabuf_free(event);
  982. wps_er_http_resp_ok(req);
  983. }
  984. static void wps_er_http_notify(struct wps_er *er, struct http_request *req)
  985. {
  986. char *uri = http_request_get_uri(req);
  987. if (os_strncmp(uri, "/event/", 7) == 0) {
  988. unsigned int event_id;
  989. char *pos;
  990. event_id = atoi(uri + 7);
  991. if (event_id != er->event_id) {
  992. wpa_printf(MSG_DEBUG, "WPS ER: HTTP event for an "
  993. "unknown event id %u", event_id);
  994. return;
  995. }
  996. pos = os_strchr(uri + 7, '/');
  997. if (pos == NULL)
  998. return;
  999. pos++;
  1000. wps_er_http_event(er, req, atoi(pos));
  1001. } else {
  1002. wpa_printf(MSG_DEBUG, "WPS ER: Unknown HTTP NOTIFY for '%s'",
  1003. uri);
  1004. wps_er_http_resp_not_found(req);
  1005. }
  1006. }
  1007. static void wps_er_http_req(void *ctx, struct http_request *req)
  1008. {
  1009. struct wps_er *er = ctx;
  1010. struct sockaddr_in *cli = http_request_get_cli_addr(req);
  1011. enum httpread_hdr_type type = http_request_get_type(req);
  1012. struct wpabuf *buf;
  1013. wpa_printf(MSG_DEBUG, "WPS ER: HTTP request: '%s' (type %d) from "
  1014. "%s:%d",
  1015. http_request_get_uri(req), type,
  1016. inet_ntoa(cli->sin_addr), ntohs(cli->sin_port));
  1017. switch (type) {
  1018. case HTTPREAD_HDR_TYPE_NOTIFY:
  1019. wps_er_http_notify(er, req);
  1020. break;
  1021. default:
  1022. wpa_printf(MSG_DEBUG, "WPS ER: Unsupported HTTP request type "
  1023. "%d", type);
  1024. buf = wpabuf_alloc(200);
  1025. if (buf == NULL) {
  1026. http_request_deinit(req);
  1027. return;
  1028. }
  1029. wpabuf_put_str(buf,
  1030. "HTTP/1.1 501 Unimplemented\r\n"
  1031. "Connection: close\r\n");
  1032. http_put_date(buf);
  1033. wpabuf_put_str(buf, "\r\n");
  1034. http_request_send_and_deinit(req, buf);
  1035. break;
  1036. }
  1037. }
  1038. struct wps_er *
  1039. wps_er_init(struct wps_context *wps, const char *ifname, const char *filter)
  1040. {
  1041. struct wps_er *er;
  1042. struct in_addr addr;
  1043. er = os_zalloc(sizeof(*er));
  1044. if (er == NULL)
  1045. return NULL;
  1046. dl_list_init(&er->ap);
  1047. dl_list_init(&er->ap_unsubscribing);
  1048. dl_list_init(&er->ap_settings);
  1049. er->multicast_sd = -1;
  1050. er->ssdp_sd = -1;
  1051. os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
  1052. er->wps = wps;
  1053. if (os_get_random((unsigned char *) &er->event_id,
  1054. sizeof(er->event_id)) < 0) {
  1055. wps_er_deinit(er, NULL, NULL);
  1056. return NULL;
  1057. }
  1058. /* Limit event_id to < 32 bits to avoid issues with atoi() */
  1059. er->event_id &= 0x0fffffff;
  1060. if (filter && os_strncmp(filter, "ifname=", 7) == 0) {
  1061. const char *pos, *end;
  1062. pos = filter + 7;
  1063. end = os_strchr(pos, ' ');
  1064. if (end) {
  1065. size_t len = end - pos;
  1066. os_strlcpy(er->ifname, pos, len < sizeof(er->ifname) ?
  1067. len + 1 : sizeof(er->ifname));
  1068. filter = end + 1;
  1069. } else {
  1070. os_strlcpy(er->ifname, pos, sizeof(er->ifname));
  1071. filter = NULL;
  1072. }
  1073. er->forced_ifname = 1;
  1074. }
  1075. if (filter) {
  1076. if (inet_aton(filter, &er->filter_addr) == 0) {
  1077. wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter "
  1078. "address %s", filter);
  1079. wps_er_deinit(er, NULL, NULL);
  1080. return NULL;
  1081. }
  1082. wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections "
  1083. "with %s", filter);
  1084. }
  1085. if (get_netif_info(er->ifname, &er->ip_addr, &er->ip_addr_text,
  1086. er->mac_addr)) {
  1087. wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
  1088. "for %s. Does it have IP address?", er->ifname);
  1089. wps_er_deinit(er, NULL, NULL);
  1090. return NULL;
  1091. }
  1092. if (wps_er_ssdp_init(er) < 0) {
  1093. wpa_printf(MSG_INFO, "WPS UPnP: SSDP initialization failed");
  1094. wps_er_deinit(er, NULL, NULL);
  1095. return NULL;
  1096. }
  1097. addr.s_addr = er->ip_addr;
  1098. er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er);
  1099. if (er->http_srv == NULL) {
  1100. wpa_printf(MSG_INFO, "WPS UPnP: HTTP initialization failed");
  1101. wps_er_deinit(er, NULL, NULL);
  1102. return NULL;
  1103. }
  1104. er->http_port = http_server_get_port(er->http_srv);
  1105. wpa_printf(MSG_DEBUG, "WPS ER: Start (ifname=%s ip_addr=%s)",
  1106. er->ifname, er->ip_addr_text);
  1107. return er;
  1108. }
  1109. void wps_er_refresh(struct wps_er *er)
  1110. {
  1111. struct wps_er_ap *ap;
  1112. struct wps_er_sta *sta;
  1113. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  1114. wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_ADD);
  1115. dl_list_for_each(sta, &ap->sta, struct wps_er_sta, list)
  1116. wps_er_sta_event(er->wps, sta, WPS_EV_ER_ENROLLEE_ADD);
  1117. }
  1118. wps_er_send_ssdp_msearch(er);
  1119. }
  1120. static void wps_er_deinit_finish(void *eloop_data, void *user_ctx)
  1121. {
  1122. struct wps_er *er = eloop_data;
  1123. void (*deinit_done_cb)(void *ctx);
  1124. void *deinit_done_ctx;
  1125. struct wps_er_ap *ap, *tmp;
  1126. wpa_printf(MSG_DEBUG, "WPS ER: Finishing deinit");
  1127. dl_list_for_each_safe(ap, tmp, &er->ap_unsubscribing, struct wps_er_ap,
  1128. list) {
  1129. wpa_printf(MSG_DEBUG, "WPS ER: AP entry for %s (%s) still in ap_unsubscribing list - free it",
  1130. inet_ntoa(ap->addr), ap->location);
  1131. dl_list_del(&ap->list);
  1132. wps_er_ap_free(ap);
  1133. }
  1134. eloop_cancel_timeout(wps_er_deinit_finish, er, NULL);
  1135. deinit_done_cb = er->deinit_done_cb;
  1136. deinit_done_ctx = er->deinit_done_ctx;
  1137. os_free(er->ip_addr_text);
  1138. os_free(er);
  1139. if (deinit_done_cb)
  1140. deinit_done_cb(deinit_done_ctx);
  1141. }
  1142. void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx)
  1143. {
  1144. if (er == NULL)
  1145. return;
  1146. http_server_deinit(er->http_srv);
  1147. wps_er_ap_remove_all(er);
  1148. wps_er_ssdp_deinit(er);
  1149. eloop_register_timeout(dl_list_empty(&er->ap_unsubscribing) ? 0 : 5, 0,
  1150. wps_er_deinit_finish, er, NULL);
  1151. wpa_printf(MSG_DEBUG, "WPS ER: Finish deinit from timeout");
  1152. er->deinitializing = 1;
  1153. er->deinit_done_cb = cb;
  1154. er->deinit_done_ctx = ctx;
  1155. }
  1156. static void wps_er_http_set_sel_reg_cb(void *ctx, struct http_client *c,
  1157. enum http_client_event event)
  1158. {
  1159. struct wps_er_ap *ap = ctx;
  1160. union wps_event_data data;
  1161. os_memset(&data, 0, sizeof(data));
  1162. switch (event) {
  1163. case HTTP_CLIENT_OK:
  1164. wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar OK");
  1165. data.set_sel_reg.state = WPS_ER_SET_SEL_REG_DONE;
  1166. data.set_sel_reg.uuid = ap->uuid;
  1167. break;
  1168. case HTTP_CLIENT_FAILED:
  1169. case HTTP_CLIENT_INVALID_REPLY:
  1170. case HTTP_CLIENT_TIMEOUT:
  1171. wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar failed");
  1172. data.set_sel_reg.state = WPS_ER_SET_SEL_REG_FAILED;
  1173. data.set_sel_reg.uuid = ap->uuid;
  1174. break;
  1175. }
  1176. http_client_free(ap->http);
  1177. ap->http = NULL;
  1178. if (data.set_sel_reg.uuid)
  1179. ap->er->wps->event_cb(ap->er->wps->cb_ctx,
  1180. WPS_EV_ER_SET_SELECTED_REGISTRAR, &data);
  1181. }
  1182. static void wps_er_send_set_sel_reg(struct wps_er_ap *ap, struct wpabuf *msg)
  1183. {
  1184. struct wpabuf *buf;
  1185. char *len_ptr, *body_ptr;
  1186. struct sockaddr_in dst;
  1187. char *url, *path;
  1188. if (ap->control_url == NULL) {
  1189. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  1190. return;
  1191. }
  1192. if (ap->http) {
  1193. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for AP - "
  1194. "ignore new request");
  1195. return;
  1196. }
  1197. if (ap->wps) {
  1198. wpa_printf(MSG_DEBUG, "WPS ER: Pending WPS operation for AP - "
  1199. "skip SetSelectedRegistrar");
  1200. return;
  1201. }
  1202. url = http_client_url_parse(ap->control_url, &dst, &path);
  1203. if (url == NULL) {
  1204. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
  1205. return;
  1206. }
  1207. buf = wps_er_soap_hdr(msg, "SetSelectedRegistrar", "NewMessage", path,
  1208. &dst, &len_ptr, &body_ptr);
  1209. os_free(url);
  1210. if (buf == NULL)
  1211. return;
  1212. wps_er_soap_end(buf, "SetSelectedRegistrar", len_ptr, body_ptr);
  1213. ap->http = http_client_addr(&dst, buf, 1000,
  1214. wps_er_http_set_sel_reg_cb, ap);
  1215. if (ap->http == NULL)
  1216. wpabuf_free(buf);
  1217. }
  1218. static int wps_er_build_selected_registrar(struct wpabuf *msg, int sel_reg)
  1219. {
  1220. wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
  1221. wpabuf_put_be16(msg, 1);
  1222. wpabuf_put_u8(msg, !!sel_reg);
  1223. return 0;
  1224. }
  1225. static int wps_er_build_dev_password_id(struct wpabuf *msg, u16 dev_passwd_id)
  1226. {
  1227. wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
  1228. wpabuf_put_be16(msg, 2);
  1229. wpabuf_put_be16(msg, dev_passwd_id);
  1230. return 0;
  1231. }
  1232. static int wps_er_build_sel_reg_config_methods(struct wpabuf *msg,
  1233. u16 sel_reg_config_methods)
  1234. {
  1235. wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
  1236. wpabuf_put_be16(msg, 2);
  1237. wpabuf_put_be16(msg, sel_reg_config_methods);
  1238. return 0;
  1239. }
  1240. static int wps_er_build_uuid_r(struct wpabuf *msg, const u8 *uuid_r)
  1241. {
  1242. #ifdef CONFIG_WPS2
  1243. wpabuf_put_be16(msg, ATTR_UUID_R);
  1244. wpabuf_put_be16(msg, WPS_UUID_LEN);
  1245. wpabuf_put_data(msg, uuid_r, WPS_UUID_LEN);
  1246. #endif /* CONFIG_WPS2 */
  1247. return 0;
  1248. }
  1249. void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
  1250. u16 sel_reg_config_methods)
  1251. {
  1252. struct wpabuf *msg;
  1253. struct wps_er_ap *ap;
  1254. struct wps_registrar *reg = er->wps->registrar;
  1255. const u8 *auth_macs;
  1256. #ifdef CONFIG_WPS2
  1257. u8 bcast[ETH_ALEN];
  1258. #endif /* CONFIG_WPS2 */
  1259. size_t count;
  1260. union wps_event_data data;
  1261. if (er->skip_set_sel_reg) {
  1262. wpa_printf(MSG_DEBUG, "WPS ER: Skip SetSelectedRegistrar");
  1263. return;
  1264. }
  1265. msg = wpabuf_alloc(500);
  1266. if (msg == NULL)
  1267. return;
  1268. auth_macs = wps_authorized_macs(reg, &count);
  1269. #ifdef CONFIG_WPS2
  1270. if (count == 0) {
  1271. os_memset(bcast, 0xff, ETH_ALEN);
  1272. auth_macs = bcast;
  1273. count = 1;
  1274. }
  1275. #endif /* CONFIG_WPS2 */
  1276. if (wps_build_version(msg) ||
  1277. wps_er_build_selected_registrar(msg, sel_reg) ||
  1278. wps_er_build_dev_password_id(msg, dev_passwd_id) ||
  1279. wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) ||
  1280. wps_build_wfa_ext(msg, 0, auth_macs, count) ||
  1281. wps_er_build_uuid_r(msg, er->wps->uuid)) {
  1282. wpabuf_free(msg);
  1283. return;
  1284. }
  1285. os_memset(&data, 0, sizeof(data));
  1286. data.set_sel_reg.sel_reg = sel_reg;
  1287. data.set_sel_reg.dev_passwd_id = dev_passwd_id;
  1288. data.set_sel_reg.sel_reg_config_methods = sel_reg_config_methods;
  1289. data.set_sel_reg.state = WPS_ER_SET_SEL_REG_START;
  1290. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  1291. if (er->set_sel_reg_uuid_filter &&
  1292. os_memcmp(ap->uuid, er->set_sel_reg_uuid_filter,
  1293. WPS_UUID_LEN) != 0)
  1294. continue;
  1295. data.set_sel_reg.uuid = ap->uuid;
  1296. er->wps->event_cb(er->wps->cb_ctx,
  1297. WPS_EV_ER_SET_SELECTED_REGISTRAR, &data);
  1298. wps_er_send_set_sel_reg(ap, msg);
  1299. }
  1300. wpabuf_free(msg);
  1301. }
  1302. int wps_er_pbc(struct wps_er *er, const u8 *uuid, const u8 *addr)
  1303. {
  1304. int res;
  1305. struct wps_er_ap *ap;
  1306. if (er == NULL || er->wps == NULL)
  1307. return -1;
  1308. if (wps_registrar_pbc_overlap(er->wps->registrar, NULL, NULL)) {
  1309. wpa_printf(MSG_DEBUG, "WPS ER: PBC overlap - do not start PBC "
  1310. "mode");
  1311. return -2;
  1312. }
  1313. if (uuid)
  1314. ap = wps_er_ap_get(er, NULL, uuid, NULL);
  1315. else
  1316. ap = NULL;
  1317. if (ap == NULL) {
  1318. struct wps_er_sta *sta = NULL;
  1319. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  1320. sta = wps_er_sta_get(ap, addr, uuid);
  1321. if (sta) {
  1322. uuid = ap->uuid;
  1323. break;
  1324. }
  1325. }
  1326. if (sta == NULL)
  1327. return -3; /* Unknown UUID */
  1328. }
  1329. if (ap->ap_settings == NULL) {
  1330. wpa_printf(MSG_DEBUG, "WPS ER: AP settings not known");
  1331. return -4;
  1332. }
  1333. er->set_sel_reg_uuid_filter = uuid;
  1334. res = wps_registrar_button_pushed(er->wps->registrar, NULL);
  1335. er->set_sel_reg_uuid_filter = NULL;
  1336. if (res)
  1337. return -1;
  1338. return 0;
  1339. }
  1340. static void wps_er_ap_settings_cb(void *ctx, const struct wps_credential *cred)
  1341. {
  1342. struct wps_er_ap *ap = ctx;
  1343. union wps_event_data data;
  1344. wpa_printf(MSG_DEBUG, "WPS ER: AP Settings received");
  1345. os_free(ap->ap_settings);
  1346. ap->ap_settings = os_malloc(sizeof(*cred));
  1347. if (ap->ap_settings) {
  1348. os_memcpy(ap->ap_settings, cred, sizeof(*cred));
  1349. ap->ap_settings->cred_attr = NULL;
  1350. }
  1351. os_memset(&data, 0, sizeof(data));
  1352. data.ap_settings.uuid = ap->uuid;
  1353. data.ap_settings.cred = cred;
  1354. ap->er->wps->event_cb(ap->er->wps->cb_ctx, WPS_EV_ER_AP_SETTINGS,
  1355. &data);
  1356. }
  1357. const u8 * wps_er_get_sta_uuid(struct wps_er *er, const u8 *addr)
  1358. {
  1359. struct wps_er_ap *ap;
  1360. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  1361. struct wps_er_sta *sta;
  1362. sta = wps_er_sta_get(ap, addr, NULL);
  1363. if (sta)
  1364. return sta->uuid;
  1365. }
  1366. return NULL;
  1367. }
  1368. static void wps_er_http_put_message_cb(void *ctx, struct http_client *c,
  1369. enum http_client_event event)
  1370. {
  1371. struct wps_er_ap *ap = ctx;
  1372. struct wpabuf *reply;
  1373. char *msg = NULL;
  1374. switch (event) {
  1375. case HTTP_CLIENT_OK:
  1376. wpa_printf(MSG_DEBUG, "WPS ER: PutMessage OK");
  1377. reply = http_client_get_body(c);
  1378. if (reply == NULL)
  1379. break;
  1380. msg = os_zalloc(wpabuf_len(reply) + 1);
  1381. if (msg == NULL)
  1382. break;
  1383. os_memcpy(msg, wpabuf_head(reply), wpabuf_len(reply));
  1384. break;
  1385. case HTTP_CLIENT_FAILED:
  1386. case HTTP_CLIENT_INVALID_REPLY:
  1387. case HTTP_CLIENT_TIMEOUT:
  1388. wpa_printf(MSG_DEBUG, "WPS ER: PutMessage failed");
  1389. if (ap->wps) {
  1390. wps_deinit(ap->wps);
  1391. ap->wps = NULL;
  1392. }
  1393. break;
  1394. }
  1395. http_client_free(ap->http);
  1396. ap->http = NULL;
  1397. if (msg) {
  1398. struct wpabuf *buf;
  1399. enum http_reply_code ret;
  1400. buf = xml_get_base64_item(msg, "NewOutMessage", &ret);
  1401. os_free(msg);
  1402. if (buf == NULL) {
  1403. wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
  1404. "NewOutMessage from PutMessage response");
  1405. wps_deinit(ap->wps);
  1406. ap->wps = NULL;
  1407. return;
  1408. }
  1409. wps_er_ap_process(ap, buf);
  1410. wpabuf_free(buf);
  1411. }
  1412. }
  1413. static void wps_er_ap_put_message(struct wps_er_ap *ap,
  1414. const struct wpabuf *msg)
  1415. {
  1416. struct wpabuf *buf;
  1417. char *len_ptr, *body_ptr;
  1418. struct sockaddr_in dst;
  1419. char *url, *path;
  1420. if (ap->http) {
  1421. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
  1422. "with the AP - cannot continue learn");
  1423. return;
  1424. }
  1425. if (ap->control_url == NULL) {
  1426. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  1427. return;
  1428. }
  1429. url = http_client_url_parse(ap->control_url, &dst, &path);
  1430. if (url == NULL) {
  1431. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
  1432. return;
  1433. }
  1434. buf = wps_er_soap_hdr(msg, "PutMessage", "NewInMessage", path, &dst,
  1435. &len_ptr, &body_ptr);
  1436. os_free(url);
  1437. if (buf == NULL)
  1438. return;
  1439. wps_er_soap_end(buf, "PutMessage", len_ptr, body_ptr);
  1440. ap->http = http_client_addr(&dst, buf, 10000,
  1441. wps_er_http_put_message_cb, ap);
  1442. if (ap->http == NULL)
  1443. wpabuf_free(buf);
  1444. }
  1445. static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg)
  1446. {
  1447. enum wps_process_res res;
  1448. struct wps_parse_attr attr;
  1449. enum wsc_op_code op_code;
  1450. op_code = WSC_MSG;
  1451. if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
  1452. switch (*attr.msg_type) {
  1453. case WPS_WSC_ACK:
  1454. op_code = WSC_ACK;
  1455. break;
  1456. case WPS_WSC_NACK:
  1457. op_code = WSC_NACK;
  1458. break;
  1459. case WPS_WSC_DONE:
  1460. op_code = WSC_Done;
  1461. break;
  1462. }
  1463. }
  1464. res = wps_process_msg(ap->wps, op_code, msg);
  1465. if (res == WPS_CONTINUE) {
  1466. struct wpabuf *next = wps_get_msg(ap->wps, &op_code);
  1467. if (next) {
  1468. wps_er_ap_put_message(ap, next);
  1469. wpabuf_free(next);
  1470. } else {
  1471. wpa_printf(MSG_DEBUG, "WPS ER: Failed to build "
  1472. "message");
  1473. wps_deinit(ap->wps);
  1474. ap->wps = NULL;
  1475. }
  1476. } else if (res == WPS_DONE) {
  1477. wpa_printf(MSG_DEBUG, "WPS ER: Protocol run done");
  1478. wps_deinit(ap->wps);
  1479. ap->wps = NULL;
  1480. } else {
  1481. wpa_printf(MSG_DEBUG, "WPS ER: Failed to process message from "
  1482. "AP (res=%d)", res);
  1483. wps_deinit(ap->wps);
  1484. ap->wps = NULL;
  1485. }
  1486. }
  1487. static void wps_er_ap_learn_m1(struct wps_er_ap *ap, struct wpabuf *m1)
  1488. {
  1489. struct wps_config cfg;
  1490. if (ap->wps) {
  1491. wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in "
  1492. "progress with this AP");
  1493. return;
  1494. }
  1495. os_memset(&cfg, 0, sizeof(cfg));
  1496. cfg.wps = ap->er->wps;
  1497. cfg.registrar = 1;
  1498. ap->wps = wps_init(&cfg);
  1499. if (ap->wps == NULL)
  1500. return;
  1501. ap->wps->ap_settings_cb = wps_er_ap_settings_cb;
  1502. ap->wps->ap_settings_cb_ctx = ap;
  1503. wps_er_ap_process(ap, m1);
  1504. }
  1505. static void wps_er_ap_learn(struct wps_er_ap *ap, const char *dev_info)
  1506. {
  1507. struct wpabuf *info;
  1508. enum http_reply_code ret;
  1509. wpa_printf(MSG_DEBUG, "WPS ER: Received GetDeviceInfo response (M1) "
  1510. "from the AP");
  1511. info = xml_get_base64_item(dev_info, "NewDeviceInfo", &ret);
  1512. if (info == NULL) {
  1513. wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
  1514. "NewDeviceInfo from GetDeviceInfo response");
  1515. return;
  1516. }
  1517. ap->m1_handler(ap, info);
  1518. wpabuf_free(info);
  1519. }
  1520. static void wps_er_http_get_dev_info_cb(void *ctx, struct http_client *c,
  1521. enum http_client_event event)
  1522. {
  1523. struct wps_er_ap *ap = ctx;
  1524. struct wpabuf *reply;
  1525. char *dev_info = NULL;
  1526. switch (event) {
  1527. case HTTP_CLIENT_OK:
  1528. wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo OK");
  1529. reply = http_client_get_body(c);
  1530. if (reply == NULL)
  1531. break;
  1532. dev_info = os_zalloc(wpabuf_len(reply) + 1);
  1533. if (dev_info == NULL)
  1534. break;
  1535. os_memcpy(dev_info, wpabuf_head(reply), wpabuf_len(reply));
  1536. break;
  1537. case HTTP_CLIENT_FAILED:
  1538. case HTTP_CLIENT_INVALID_REPLY:
  1539. case HTTP_CLIENT_TIMEOUT:
  1540. wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo failed");
  1541. break;
  1542. }
  1543. http_client_free(ap->http);
  1544. ap->http = NULL;
  1545. if (dev_info) {
  1546. wps_er_ap_learn(ap, dev_info);
  1547. os_free(dev_info);
  1548. }
  1549. }
  1550. static int wps_er_send_get_device_info(struct wps_er_ap *ap,
  1551. void (*m1_handler)(struct wps_er_ap *ap,
  1552. struct wpabuf *m1))
  1553. {
  1554. struct wpabuf *buf;
  1555. char *len_ptr, *body_ptr;
  1556. struct sockaddr_in dst;
  1557. char *url, *path;
  1558. if (ap->http) {
  1559. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
  1560. "with the AP - cannot get device info");
  1561. return -1;
  1562. }
  1563. if (ap->control_url == NULL) {
  1564. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  1565. return -1;
  1566. }
  1567. url = http_client_url_parse(ap->control_url, &dst, &path);
  1568. if (url == NULL) {
  1569. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
  1570. return -1;
  1571. }
  1572. buf = wps_er_soap_hdr(NULL, "GetDeviceInfo", NULL, path, &dst,
  1573. &len_ptr, &body_ptr);
  1574. os_free(url);
  1575. if (buf == NULL)
  1576. return -1;
  1577. wps_er_soap_end(buf, "GetDeviceInfo", len_ptr, body_ptr);
  1578. ap->http = http_client_addr(&dst, buf, 10000,
  1579. wps_er_http_get_dev_info_cb, ap);
  1580. if (ap->http == NULL) {
  1581. wpabuf_free(buf);
  1582. return -1;
  1583. }
  1584. ap->m1_handler = m1_handler;
  1585. return 0;
  1586. }
  1587. int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *addr,
  1588. const u8 *pin, size_t pin_len)
  1589. {
  1590. struct wps_er_ap *ap;
  1591. if (er == NULL)
  1592. return -1;
  1593. ap = wps_er_ap_get(er, NULL, uuid, addr);
  1594. if (ap == NULL) {
  1595. wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
  1596. "request");
  1597. return -1;
  1598. }
  1599. if (uuid == NULL)
  1600. uuid = ap->uuid;
  1601. if (ap->wps) {
  1602. wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
  1603. "with the AP - cannot start learn");
  1604. return -1;
  1605. }
  1606. if (wps_er_send_get_device_info(ap, wps_er_ap_learn_m1) < 0)
  1607. return -1;
  1608. er->skip_set_sel_reg = 1;
  1609. wps_registrar_add_pin(er->wps->registrar, NULL, uuid, pin, pin_len, 0);
  1610. er->skip_set_sel_reg = 0;
  1611. return 0;
  1612. }
  1613. int wps_er_set_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
  1614. const struct wps_credential *cred)
  1615. {
  1616. struct wps_er_ap *ap;
  1617. if (er == NULL)
  1618. return -1;
  1619. ap = wps_er_ap_get(er, NULL, uuid, addr);
  1620. if (ap == NULL) {
  1621. wpa_printf(MSG_DEBUG, "WPS ER: AP not found for set config "
  1622. "request");
  1623. return -1;
  1624. }
  1625. os_free(ap->ap_settings);
  1626. ap->ap_settings = os_malloc(sizeof(*cred));
  1627. if (ap->ap_settings == NULL)
  1628. return -1;
  1629. os_memcpy(ap->ap_settings, cred, sizeof(*cred));
  1630. ap->ap_settings->cred_attr = NULL;
  1631. wpa_printf(MSG_DEBUG, "WPS ER: Updated local AP settings based set "
  1632. "config request");
  1633. return 0;
  1634. }
  1635. static void wps_er_ap_config_m1(struct wps_er_ap *ap, struct wpabuf *m1)
  1636. {
  1637. struct wps_config cfg;
  1638. if (ap->wps) {
  1639. wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in "
  1640. "progress with this AP");
  1641. return;
  1642. }
  1643. os_memset(&cfg, 0, sizeof(cfg));
  1644. cfg.wps = ap->er->wps;
  1645. cfg.registrar = 1;
  1646. cfg.new_ap_settings = ap->ap_settings;
  1647. ap->wps = wps_init(&cfg);
  1648. if (ap->wps == NULL)
  1649. return;
  1650. ap->wps->ap_settings_cb = NULL;
  1651. ap->wps->ap_settings_cb_ctx = NULL;
  1652. wps_er_ap_process(ap, m1);
  1653. }
  1654. int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
  1655. const u8 *pin, size_t pin_len,
  1656. const struct wps_credential *cred)
  1657. {
  1658. struct wps_er_ap *ap;
  1659. if (er == NULL)
  1660. return -1;
  1661. ap = wps_er_ap_get(er, NULL, uuid, addr);
  1662. if (ap == NULL) {
  1663. wpa_printf(MSG_DEBUG, "WPS ER: AP not found for config "
  1664. "request");
  1665. return -1;
  1666. }
  1667. if (uuid == NULL)
  1668. uuid = ap->uuid;
  1669. if (ap->wps) {
  1670. wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
  1671. "with the AP - cannot start config");
  1672. return -1;
  1673. }
  1674. os_free(ap->ap_settings);
  1675. ap->ap_settings = os_malloc(sizeof(*cred));
  1676. if (ap->ap_settings == NULL)
  1677. return -1;
  1678. os_memcpy(ap->ap_settings, cred, sizeof(*cred));
  1679. ap->ap_settings->cred_attr = NULL;
  1680. if (wps_er_send_get_device_info(ap, wps_er_ap_config_m1) < 0)
  1681. return -1;
  1682. er->skip_set_sel_reg = 1;
  1683. wps_registrar_add_pin(er->wps->registrar, NULL, uuid, pin, pin_len, 0);
  1684. er->skip_set_sel_reg = 0;
  1685. return 0;
  1686. }
  1687. #ifdef CONFIG_WPS_NFC
  1688. struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
  1689. struct wps_credential *cred)
  1690. {
  1691. struct wpabuf *ret;
  1692. struct wps_data data;
  1693. ret = wpabuf_alloc(500);
  1694. if (ret == NULL)
  1695. return NULL;
  1696. os_memset(&data, 0, sizeof(data));
  1697. data.wps = wps;
  1698. data.use_cred = cred;
  1699. if (wps_build_cred(&data, ret) ||
  1700. wps_build_wfa_ext(ret, 0, NULL, 0)) {
  1701. wpabuf_free(ret);
  1702. return NULL;
  1703. }
  1704. return ret;
  1705. }
  1706. struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
  1707. const u8 *addr)
  1708. {
  1709. struct wps_er_ap *ap;
  1710. if (er == NULL)
  1711. return NULL;
  1712. ap = wps_er_ap_get(er, NULL, uuid, addr);
  1713. if (ap == NULL)
  1714. return NULL;
  1715. if (ap->ap_settings == NULL) {
  1716. wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
  1717. "selected AP");
  1718. return NULL;
  1719. }
  1720. return wps_er_config_token_from_cred(er->wps, ap->ap_settings);
  1721. }
  1722. struct wpabuf * wps_er_nfc_handover_sel(struct wps_er *er,
  1723. struct wps_context *wps, const u8 *uuid,
  1724. const u8 *addr, struct wpabuf *pubkey)
  1725. {
  1726. struct wps_er_ap *ap;
  1727. if (er == NULL)
  1728. return NULL;
  1729. ap = wps_er_ap_get(er, NULL, uuid, addr);
  1730. if (ap == NULL)
  1731. return NULL;
  1732. if (ap->ap_settings == NULL) {
  1733. wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
  1734. "selected AP");
  1735. return NULL;
  1736. }
  1737. os_memcpy(wps->ssid, ap->ap_settings->ssid, ap->ap_settings->ssid_len);
  1738. wps->ssid_len = ap->ap_settings->ssid_len;
  1739. return wps_build_nfc_handover_sel(wps, pubkey);
  1740. }
  1741. #endif /* CONFIG_WPS_NFC */