wps_er.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644
  1. /*
  2. * Wi-Fi Protected Setup - External Registrar
  3. * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #include "common.h"
  16. #include "base64.h"
  17. #include "uuid.h"
  18. #include "eloop.h"
  19. #include "httpread.h"
  20. #include "http_client.h"
  21. #include "http_server.h"
  22. #include "upnp_xml.h"
  23. #include "wps_i.h"
  24. #include "wps_upnp.h"
  25. #include "wps_upnp_i.h"
  26. #include "wps_er.h"
  27. static void wps_er_deinit_finish(void *eloop_data, void *user_ctx);
  28. static void wps_er_ap_timeout(void *eloop_data, void *user_ctx);
  29. static void wps_er_sta_timeout(void *eloop_data, void *user_ctx);
  30. static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg);
  31. static int wps_er_send_get_device_info(struct wps_er_ap *ap,
  32. void (*m1_handler)(struct wps_er_ap *ap,
  33. struct wpabuf *m1));
  34. static void wps_er_sta_event(struct wps_context *wps, struct wps_er_sta *sta,
  35. enum wps_event event)
  36. {
  37. union wps_event_data data;
  38. struct wps_event_er_enrollee *ev = &data.enrollee;
  39. if (wps->event_cb == NULL)
  40. return;
  41. os_memset(&data, 0, sizeof(data));
  42. ev->uuid = sta->uuid;
  43. ev->mac_addr = sta->addr;
  44. ev->m1_received = sta->m1_received;
  45. ev->config_methods = sta->config_methods;
  46. ev->dev_passwd_id = sta->dev_passwd_id;
  47. ev->pri_dev_type = sta->pri_dev_type;
  48. ev->dev_name = sta->dev_name;
  49. ev->manufacturer = sta->manufacturer;
  50. ev->model_name = sta->model_name;
  51. ev->model_number = sta->model_number;
  52. ev->serial_number = sta->serial_number;
  53. wps->event_cb(wps->cb_ctx, event, &data);
  54. }
  55. static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr)
  56. {
  57. struct wps_er_sta *sta;
  58. dl_list_for_each(sta, &ap->sta, struct wps_er_sta, list) {
  59. if (os_memcmp(sta->addr, addr, ETH_ALEN) == 0)
  60. return sta;
  61. }
  62. return NULL;
  63. }
  64. static void wps_er_sta_free(struct wps_er_sta *sta)
  65. {
  66. wps_er_sta_event(sta->ap->er->wps, sta, WPS_EV_ER_ENROLLEE_REMOVE);
  67. if (sta->wps)
  68. wps_deinit(sta->wps);
  69. os_free(sta->manufacturer);
  70. os_free(sta->model_name);
  71. os_free(sta->model_number);
  72. os_free(sta->serial_number);
  73. os_free(sta->dev_name);
  74. http_client_free(sta->http);
  75. eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
  76. os_free(sta);
  77. }
  78. static void wps_er_sta_remove_all(struct wps_er_ap *ap)
  79. {
  80. struct wps_er_sta *prev, *sta;
  81. dl_list_for_each_safe(sta, prev, &ap->sta, struct wps_er_sta, list)
  82. wps_er_sta_free(sta);
  83. }
  84. static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
  85. struct in_addr *addr, const u8 *uuid)
  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. return ap;
  93. }
  94. return NULL;
  95. }
  96. static struct wps_er_ap * wps_er_ap_get_id(struct wps_er *er, unsigned int id)
  97. {
  98. struct wps_er_ap *ap;
  99. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  100. if (ap->id == id)
  101. return ap;
  102. }
  103. return NULL;
  104. }
  105. static void wps_er_ap_event(struct wps_context *wps, struct wps_er_ap *ap,
  106. enum wps_event event)
  107. {
  108. union wps_event_data data;
  109. struct wps_event_er_ap *evap = &data.ap;
  110. if (wps->event_cb == NULL)
  111. return;
  112. os_memset(&data, 0, sizeof(data));
  113. evap->uuid = ap->uuid;
  114. evap->friendly_name = ap->friendly_name;
  115. evap->manufacturer = ap->manufacturer;
  116. evap->manufacturer_url = ap->manufacturer_url;
  117. evap->model_description = ap->model_description;
  118. evap->model_name = ap->model_name;
  119. evap->model_number = ap->model_number;
  120. evap->model_url = ap->model_url;
  121. evap->serial_number = ap->serial_number;
  122. evap->upc = ap->upc;
  123. evap->pri_dev_type = ap->pri_dev_type;
  124. evap->wps_state = ap->wps_state;
  125. evap->mac_addr = ap->mac_addr;
  126. wps->event_cb(wps->cb_ctx, event, &data);
  127. }
  128. static void wps_er_ap_free(struct wps_er_ap *ap)
  129. {
  130. http_client_free(ap->http);
  131. ap->http = NULL;
  132. os_free(ap->location);
  133. os_free(ap->friendly_name);
  134. os_free(ap->manufacturer);
  135. os_free(ap->manufacturer_url);
  136. os_free(ap->model_description);
  137. os_free(ap->model_name);
  138. os_free(ap->model_number);
  139. os_free(ap->model_url);
  140. os_free(ap->serial_number);
  141. os_free(ap->udn);
  142. os_free(ap->upc);
  143. os_free(ap->scpd_url);
  144. os_free(ap->control_url);
  145. os_free(ap->event_sub_url);
  146. os_free(ap->ap_settings);
  147. os_free(ap);
  148. }
  149. static void wps_er_ap_unsubscribed(struct wps_er *er, struct wps_er_ap *ap)
  150. {
  151. wpa_printf(MSG_DEBUG, "WPS ER: Unsubscribed from AP %s (%s)",
  152. inet_ntoa(ap->addr), ap->location);
  153. dl_list_del(&ap->list);
  154. wps_er_ap_free(ap);
  155. if (er->deinitializing && dl_list_empty(&er->ap_unsubscribing)) {
  156. eloop_cancel_timeout(wps_er_deinit_finish, er, NULL);
  157. wps_er_deinit_finish(er, NULL);
  158. }
  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 void wps_er_ap_remove_entry(struct wps_er *er, struct wps_er_ap *ap)
  235. {
  236. wpa_printf(MSG_DEBUG, "WPS ER: Removing AP entry for %s (%s)",
  237. inet_ntoa(ap->addr), ap->location);
  238. eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
  239. wps_er_sta_remove_all(ap);
  240. wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_REMOVE);
  241. http_client_free(ap->http);
  242. ap->http = NULL;
  243. if (ap->wps) {
  244. wps_deinit(ap->wps);
  245. ap->wps = NULL;
  246. }
  247. dl_list_del(&ap->list);
  248. if (ap->subscribed) {
  249. dl_list_add(&er->ap_unsubscribing, &ap->list);
  250. wps_er_ap_unsubscribe(er, ap);
  251. } else
  252. wps_er_ap_free(ap);
  253. }
  254. static void wps_er_ap_timeout(void *eloop_data, void *user_ctx)
  255. {
  256. struct wps_er *er = eloop_data;
  257. struct wps_er_ap *ap = user_ctx;
  258. wpa_printf(MSG_DEBUG, "WPS ER: AP advertisement timed out");
  259. wps_er_ap_remove_entry(er, ap);
  260. }
  261. static int wps_er_get_sid(struct wps_er_ap *ap, char *sid)
  262. {
  263. char *pos;
  264. char txt[100];
  265. if (!sid) {
  266. wpa_printf(MSG_DEBUG, "WPS ER: No SID received from %s (%s)",
  267. inet_ntoa(ap->addr), ap->location);
  268. return -1;
  269. }
  270. pos = os_strstr(sid, "uuid:");
  271. if (!pos) {
  272. wpa_printf(MSG_DEBUG, "WPS ER: Invalid SID received from "
  273. "%s (%s): '%s'", inet_ntoa(ap->addr), ap->location,
  274. sid);
  275. return -1;
  276. }
  277. pos += 5;
  278. if (uuid_str2bin(pos, ap->sid) < 0) {
  279. wpa_printf(MSG_DEBUG, "WPS ER: Invalid SID received from "
  280. "%s (%s): '%s'", inet_ntoa(ap->addr), ap->location,
  281. sid);
  282. return -1;
  283. }
  284. uuid_bin2str(ap->sid, txt, sizeof(txt));
  285. wpa_printf(MSG_DEBUG, "WPS ER: SID for subscription with %s (%s): %s",
  286. inet_ntoa(ap->addr), ap->location, txt);
  287. return 0;
  288. }
  289. static void wps_er_http_subscribe_cb(void *ctx, struct http_client *c,
  290. enum http_client_event event)
  291. {
  292. struct wps_er_ap *ap = ctx;
  293. switch (event) {
  294. case HTTP_CLIENT_OK:
  295. wpa_printf(MSG_DEBUG, "WPS ER: Subscribed to events");
  296. ap->subscribed = 1;
  297. wps_er_get_sid(ap, http_client_get_hdr_line(c, "SID"));
  298. wps_er_ap_event(ap->er->wps, ap, WPS_EV_ER_AP_ADD);
  299. break;
  300. case HTTP_CLIENT_FAILED:
  301. case HTTP_CLIENT_INVALID_REPLY:
  302. case HTTP_CLIENT_TIMEOUT:
  303. wpa_printf(MSG_DEBUG, "WPS ER: Failed to subscribe to events");
  304. break;
  305. }
  306. http_client_free(ap->http);
  307. ap->http = NULL;
  308. }
  309. static void wps_er_subscribe(struct wps_er_ap *ap)
  310. {
  311. struct wpabuf *req;
  312. struct sockaddr_in dst;
  313. char *url, *path;
  314. if (ap->event_sub_url == NULL) {
  315. wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot "
  316. "subscribe");
  317. return;
  318. }
  319. if (ap->http) {
  320. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot "
  321. "send subscribe request");
  322. return;
  323. }
  324. url = http_client_url_parse(ap->event_sub_url, &dst, &path);
  325. if (url == NULL) {
  326. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
  327. return;
  328. }
  329. req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000);
  330. if (req == NULL) {
  331. os_free(url);
  332. return;
  333. }
  334. wpabuf_printf(req,
  335. "SUBSCRIBE %s HTTP/1.1\r\n"
  336. "HOST: %s:%d\r\n"
  337. "CALLBACK: <http://%s:%d/event/%u/%u>\r\n"
  338. "NT: upnp:event\r\n"
  339. "TIMEOUT: Second-%d\r\n"
  340. "\r\n",
  341. path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port),
  342. ap->er->ip_addr_text, ap->er->http_port,
  343. ap->er->event_id, ap->id, 1800);
  344. os_free(url);
  345. wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Subscription request",
  346. wpabuf_head(req), wpabuf_len(req));
  347. ap->http = http_client_addr(&dst, req, 1000, wps_er_http_subscribe_cb,
  348. ap);
  349. if (ap->http == NULL)
  350. wpabuf_free(req);
  351. }
  352. static void wps_er_ap_get_m1(struct wps_er_ap *ap, struct wpabuf *m1)
  353. {
  354. struct wps_parse_attr attr;
  355. if (wps_parse_msg(m1, &attr) < 0) {
  356. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse M1");
  357. return;
  358. }
  359. if (attr.primary_dev_type)
  360. os_memcpy(ap->pri_dev_type, attr.primary_dev_type, 8);
  361. if (attr.wps_state)
  362. ap->wps_state = *attr.wps_state;
  363. if (attr.mac_addr)
  364. os_memcpy(ap->mac_addr, attr.mac_addr, ETH_ALEN);
  365. wps_er_subscribe(ap);
  366. }
  367. static void wps_er_get_device_info(struct wps_er_ap *ap)
  368. {
  369. wps_er_send_get_device_info(ap, wps_er_ap_get_m1);
  370. }
  371. static void wps_er_parse_device_description(struct wps_er_ap *ap,
  372. struct wpabuf *reply)
  373. {
  374. /* Note: reply includes null termination after the buffer data */
  375. const char *data = wpabuf_head(reply);
  376. char *pos;
  377. wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Device info",
  378. wpabuf_head(reply), wpabuf_len(reply));
  379. ap->friendly_name = xml_get_first_item(data, "friendlyName");
  380. wpa_printf(MSG_DEBUG, "WPS ER: friendlyName='%s'", ap->friendly_name);
  381. ap->manufacturer = xml_get_first_item(data, "manufacturer");
  382. wpa_printf(MSG_DEBUG, "WPS ER: manufacturer='%s'", ap->manufacturer);
  383. ap->manufacturer_url = xml_get_first_item(data, "manufacturerURL");
  384. wpa_printf(MSG_DEBUG, "WPS ER: manufacturerURL='%s'",
  385. ap->manufacturer_url);
  386. ap->model_description = xml_get_first_item(data, "modelDescription");
  387. wpa_printf(MSG_DEBUG, "WPS ER: modelDescription='%s'",
  388. ap->model_description);
  389. ap->model_name = xml_get_first_item(data, "modelName");
  390. wpa_printf(MSG_DEBUG, "WPS ER: modelName='%s'", ap->model_name);
  391. ap->model_number = xml_get_first_item(data, "modelNumber");
  392. wpa_printf(MSG_DEBUG, "WPS ER: modelNumber='%s'", ap->model_number);
  393. ap->model_url = xml_get_first_item(data, "modelURL");
  394. wpa_printf(MSG_DEBUG, "WPS ER: modelURL='%s'", ap->model_url);
  395. ap->serial_number = xml_get_first_item(data, "serialNumber");
  396. wpa_printf(MSG_DEBUG, "WPS ER: serialNumber='%s'", ap->serial_number);
  397. ap->udn = xml_get_first_item(data, "UDN");
  398. wpa_printf(MSG_DEBUG, "WPS ER: UDN='%s'", ap->udn);
  399. pos = os_strstr(ap->udn, "uuid:");
  400. if (pos) {
  401. pos += 5;
  402. uuid_str2bin(pos, ap->uuid);
  403. }
  404. ap->upc = xml_get_first_item(data, "UPC");
  405. wpa_printf(MSG_DEBUG, "WPS ER: UPC='%s'", ap->upc);
  406. ap->scpd_url = http_link_update(
  407. xml_get_first_item(data, "SCPDURL"), ap->location);
  408. wpa_printf(MSG_DEBUG, "WPS ER: SCPDURL='%s'", ap->scpd_url);
  409. ap->control_url = http_link_update(
  410. xml_get_first_item(data, "controlURL"), ap->location);
  411. wpa_printf(MSG_DEBUG, "WPS ER: controlURL='%s'", ap->control_url);
  412. ap->event_sub_url = http_link_update(
  413. xml_get_first_item(data, "eventSubURL"), ap->location);
  414. wpa_printf(MSG_DEBUG, "WPS ER: eventSubURL='%s'", ap->event_sub_url);
  415. }
  416. static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c,
  417. enum http_client_event event)
  418. {
  419. struct wps_er_ap *ap = ctx;
  420. struct wpabuf *reply;
  421. int ok = 0;
  422. switch (event) {
  423. case HTTP_CLIENT_OK:
  424. reply = http_client_get_body(c);
  425. if (reply == NULL)
  426. break;
  427. wps_er_parse_device_description(ap, reply);
  428. ok = 1;
  429. break;
  430. case HTTP_CLIENT_FAILED:
  431. case HTTP_CLIENT_INVALID_REPLY:
  432. case HTTP_CLIENT_TIMEOUT:
  433. wpa_printf(MSG_DEBUG, "WPS ER: Failed to fetch device info");
  434. break;
  435. }
  436. http_client_free(ap->http);
  437. ap->http = NULL;
  438. if (ok)
  439. wps_er_get_device_info(ap);
  440. }
  441. void wps_er_ap_add(struct wps_er *er, const u8 *uuid, struct in_addr *addr,
  442. const char *location, int max_age)
  443. {
  444. struct wps_er_ap *ap;
  445. ap = wps_er_ap_get(er, addr, uuid);
  446. if (ap) {
  447. /* Update advertisement timeout */
  448. eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
  449. eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap);
  450. return;
  451. }
  452. ap = os_zalloc(sizeof(*ap));
  453. if (ap == NULL)
  454. return;
  455. dl_list_init(&ap->sta);
  456. ap->er = er;
  457. ap->id = ++er->next_ap_id;
  458. ap->location = os_strdup(location);
  459. if (ap->location == NULL) {
  460. os_free(ap);
  461. return;
  462. }
  463. dl_list_add(&er->ap, &ap->list);
  464. ap->addr.s_addr = addr->s_addr;
  465. os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
  466. eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap);
  467. wpa_printf(MSG_DEBUG, "WPS ER: Added AP entry for %s (%s)",
  468. inet_ntoa(ap->addr), ap->location);
  469. /* Fetch device description */
  470. ap->http = http_client_url(ap->location, NULL, 10000,
  471. wps_er_http_dev_desc_cb, ap);
  472. }
  473. void wps_er_ap_remove(struct wps_er *er, struct in_addr *addr)
  474. {
  475. struct wps_er_ap *ap;
  476. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  477. if (ap->addr.s_addr == addr->s_addr) {
  478. wps_er_ap_remove_entry(er, ap);
  479. return;
  480. }
  481. }
  482. }
  483. static void wps_er_ap_remove_all(struct wps_er *er)
  484. {
  485. struct wps_er_ap *prev, *ap;
  486. dl_list_for_each_safe(ap, prev, &er->ap, struct wps_er_ap, list)
  487. wps_er_ap_remove_entry(er, ap);
  488. }
  489. static void http_put_date(struct wpabuf *buf)
  490. {
  491. wpabuf_put_str(buf, "Date: ");
  492. format_date(buf);
  493. wpabuf_put_str(buf, "\r\n");
  494. }
  495. static void wps_er_http_resp_not_found(struct http_request *req)
  496. {
  497. struct wpabuf *buf;
  498. buf = wpabuf_alloc(200);
  499. if (buf == NULL) {
  500. http_request_deinit(req);
  501. return;
  502. }
  503. wpabuf_put_str(buf,
  504. "HTTP/1.1 404 Not Found\r\n"
  505. "Server: unspecified, UPnP/1.0, unspecified\r\n"
  506. "Connection: close\r\n");
  507. http_put_date(buf);
  508. wpabuf_put_str(buf, "\r\n");
  509. http_request_send_and_deinit(req, buf);
  510. }
  511. static void wps_er_http_resp_ok(struct http_request *req)
  512. {
  513. struct wpabuf *buf;
  514. buf = wpabuf_alloc(200);
  515. if (buf == NULL) {
  516. http_request_deinit(req);
  517. return;
  518. }
  519. wpabuf_put_str(buf,
  520. "HTTP/1.1 200 OK\r\n"
  521. "Server: unspecified, UPnP/1.0, unspecified\r\n"
  522. "Connection: close\r\n"
  523. "Content-Length: 0\r\n");
  524. http_put_date(buf);
  525. wpabuf_put_str(buf, "\r\n");
  526. http_request_send_and_deinit(req, buf);
  527. }
  528. static void wps_er_sta_timeout(void *eloop_data, void *user_ctx)
  529. {
  530. struct wps_er_sta *sta = eloop_data;
  531. wpa_printf(MSG_DEBUG, "WPS ER: STA entry timed out");
  532. dl_list_del(&sta->list);
  533. wps_er_sta_free(sta);
  534. }
  535. static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
  536. const u8 *addr,
  537. struct wps_parse_attr *attr,
  538. int probe_req)
  539. {
  540. struct wps_er_sta *sta = wps_er_sta_get(ap, addr);
  541. int new_sta = 0;
  542. int m1;
  543. m1 = !probe_req && attr->msg_type && *attr->msg_type == WPS_M1;
  544. if (sta == NULL) {
  545. /*
  546. * Only allow new STA entry to be added based on Probe Request
  547. * or M1. This will filter out bogus events and anything that
  548. * may have been ongoing at the time ER subscribed for events.
  549. */
  550. if (!probe_req && !m1)
  551. return NULL;
  552. sta = os_zalloc(sizeof(*sta));
  553. if (sta == NULL)
  554. return NULL;
  555. os_memcpy(sta->addr, addr, ETH_ALEN);
  556. sta->ap = ap;
  557. dl_list_add(&ap->sta, &sta->list);
  558. new_sta = 1;
  559. }
  560. if (m1)
  561. sta->m1_received = 1;
  562. if (attr->config_methods && (!probe_req || !sta->m1_received))
  563. sta->config_methods = WPA_GET_BE16(attr->config_methods);
  564. if (attr->uuid_e && (!probe_req || !sta->m1_received))
  565. os_memcpy(sta->uuid, attr->uuid_e, WPS_UUID_LEN);
  566. if (attr->primary_dev_type && (!probe_req || !sta->m1_received))
  567. os_memcpy(sta->pri_dev_type, attr->primary_dev_type, 8);
  568. if (attr->dev_password_id && (!probe_req || !sta->m1_received))
  569. sta->dev_passwd_id = WPA_GET_BE16(attr->dev_password_id);
  570. if (attr->manufacturer) {
  571. os_free(sta->manufacturer);
  572. sta->manufacturer = os_malloc(attr->manufacturer_len + 1);
  573. if (sta->manufacturer) {
  574. os_memcpy(sta->manufacturer, attr->manufacturer,
  575. attr->manufacturer_len);
  576. sta->manufacturer[attr->manufacturer_len] = '\0';
  577. }
  578. }
  579. if (attr->model_name) {
  580. os_free(sta->model_name);
  581. sta->model_name = os_malloc(attr->model_name_len + 1);
  582. if (sta->model_name) {
  583. os_memcpy(sta->model_name, attr->model_name,
  584. attr->model_name_len);
  585. sta->model_name[attr->model_name_len] = '\0';
  586. }
  587. }
  588. if (attr->model_number) {
  589. os_free(sta->model_number);
  590. sta->model_number = os_malloc(attr->model_number_len + 1);
  591. if (sta->model_number) {
  592. os_memcpy(sta->model_number, attr->model_number,
  593. attr->model_number_len);
  594. sta->model_number[attr->model_number_len] = '\0';
  595. }
  596. }
  597. if (attr->serial_number) {
  598. os_free(sta->serial_number);
  599. sta->serial_number = os_malloc(attr->serial_number_len + 1);
  600. if (sta->serial_number) {
  601. os_memcpy(sta->serial_number, attr->serial_number,
  602. attr->serial_number_len);
  603. sta->serial_number[attr->serial_number_len] = '\0';
  604. }
  605. }
  606. if (attr->dev_name) {
  607. os_free(sta->dev_name);
  608. sta->dev_name = os_malloc(attr->dev_name_len + 1);
  609. if (sta->dev_name) {
  610. os_memcpy(sta->dev_name, attr->dev_name,
  611. attr->dev_name_len);
  612. sta->dev_name[attr->dev_name_len] = '\0';
  613. }
  614. }
  615. eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
  616. eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL);
  617. if (m1 || new_sta)
  618. wps_er_sta_event(ap->er->wps, sta, WPS_EV_ER_ENROLLEE_ADD);
  619. return sta;
  620. }
  621. static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
  622. const u8 *addr,
  623. struct wpabuf *msg)
  624. {
  625. struct wps_parse_attr attr;
  626. wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - Probe Request - from "
  627. MACSTR, MAC2STR(addr));
  628. wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
  629. "(TLVs from Probe Request)", msg);
  630. if (wps_parse_msg(msg, &attr) < 0) {
  631. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
  632. "WLANEvent message");
  633. return;
  634. }
  635. wps_er_add_sta_data(ap, addr, &attr, 1);
  636. }
  637. static void wps_er_http_put_wlan_response_cb(void *ctx, struct http_client *c,
  638. enum http_client_event event)
  639. {
  640. struct wps_er_sta *sta = ctx;
  641. switch (event) {
  642. case HTTP_CLIENT_OK:
  643. wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse OK");
  644. break;
  645. case HTTP_CLIENT_FAILED:
  646. case HTTP_CLIENT_INVALID_REPLY:
  647. case HTTP_CLIENT_TIMEOUT:
  648. wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse failed");
  649. break;
  650. }
  651. http_client_free(sta->http);
  652. sta->http = NULL;
  653. }
  654. static const char *soap_prefix =
  655. "<?xml version=\"1.0\"?>\n"
  656. "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
  657. "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
  658. "<s:Body>\n";
  659. static const char *soap_postfix =
  660. "</s:Body>\n</s:Envelope>\n";
  661. static const char *urn_wfawlanconfig =
  662. "urn:schemas-wifialliance-org:service:WFAWLANConfig:1";
  663. static struct wpabuf * wps_er_soap_hdr(const struct wpabuf *msg,
  664. const char *name, const char *arg_name,
  665. const char *path,
  666. const struct sockaddr_in *dst,
  667. char **len_ptr, char **body_ptr)
  668. {
  669. unsigned char *encoded;
  670. size_t encoded_len;
  671. struct wpabuf *buf;
  672. if (msg) {
  673. encoded = base64_encode(wpabuf_head(msg), wpabuf_len(msg),
  674. &encoded_len);
  675. if (encoded == NULL)
  676. return NULL;
  677. } else {
  678. encoded = NULL;
  679. encoded_len = 0;
  680. }
  681. buf = wpabuf_alloc(1000 + encoded_len);
  682. if (buf == NULL) {
  683. os_free(encoded);
  684. return NULL;
  685. }
  686. wpabuf_printf(buf,
  687. "POST %s HTTP/1.1\r\n"
  688. "Host: %s:%d\r\n"
  689. "Content-Type: text/xml; charset=\"utf-8\"\r\n"
  690. "Content-Length: ",
  691. path, inet_ntoa(dst->sin_addr), ntohs(dst->sin_port));
  692. *len_ptr = wpabuf_put(buf, 0);
  693. wpabuf_printf(buf,
  694. " \r\n"
  695. "SOAPACTION: \"%s#%s\"\r\n"
  696. "\r\n",
  697. urn_wfawlanconfig, name);
  698. *body_ptr = wpabuf_put(buf, 0);
  699. wpabuf_put_str(buf, soap_prefix);
  700. wpabuf_printf(buf, "<u:%s xmlns:u=\"", name);
  701. wpabuf_put_str(buf, urn_wfawlanconfig);
  702. wpabuf_put_str(buf, "\">\n");
  703. if (encoded) {
  704. wpabuf_printf(buf, "<%s>%s</%s>\n",
  705. arg_name, (char *) encoded, arg_name);
  706. os_free(encoded);
  707. }
  708. return buf;
  709. }
  710. static void wps_er_soap_end(struct wpabuf *buf, const char *name,
  711. char *len_ptr, char *body_ptr)
  712. {
  713. char len_buf[10];
  714. wpabuf_printf(buf, "</u:%s>\n", name);
  715. wpabuf_put_str(buf, soap_postfix);
  716. os_snprintf(len_buf, sizeof(len_buf), "%d",
  717. (int) ((char *) wpabuf_put(buf, 0) - body_ptr));
  718. os_memcpy(len_ptr, len_buf, os_strlen(len_buf));
  719. }
  720. static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
  721. {
  722. struct wpabuf *buf;
  723. char *len_ptr, *body_ptr;
  724. struct sockaddr_in dst;
  725. char *url, *path;
  726. if (sta->http) {
  727. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for STA - "
  728. "ignore new request");
  729. wpabuf_free(msg);
  730. return;
  731. }
  732. if (sta->ap->control_url == NULL) {
  733. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  734. wpabuf_free(msg);
  735. return;
  736. }
  737. url = http_client_url_parse(sta->ap->control_url, &dst, &path);
  738. if (url == NULL) {
  739. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
  740. wpabuf_free(msg);
  741. return;
  742. }
  743. buf = wps_er_soap_hdr(msg, "PutWLANResponse", "NewMessage", path, &dst,
  744. &len_ptr, &body_ptr);
  745. wpabuf_free(msg);
  746. os_free(url);
  747. if (buf == NULL)
  748. return;
  749. wpabuf_printf(buf, "<NewWLANEventType>%d</NewWLANEventType>\n",
  750. UPNP_WPS_WLANEVENT_TYPE_EAP);
  751. wpabuf_printf(buf, "<NewWLANEventMAC>" MACSTR "</NewWLANEventMAC>\n",
  752. MAC2STR(sta->addr));
  753. wps_er_soap_end(buf, "PutWLANResponse", len_ptr, body_ptr);
  754. sta->http = http_client_addr(&dst, buf, 1000,
  755. wps_er_http_put_wlan_response_cb, sta);
  756. if (sta->http == NULL)
  757. wpabuf_free(buf);
  758. }
  759. static void wps_er_sta_process(struct wps_er_sta *sta, struct wpabuf *msg,
  760. enum wsc_op_code op_code)
  761. {
  762. enum wps_process_res res;
  763. res = wps_process_msg(sta->wps, op_code, msg);
  764. if (res == WPS_CONTINUE) {
  765. struct wpabuf *next = wps_get_msg(sta->wps, &op_code);
  766. if (next)
  767. wps_er_sta_send_msg(sta, next);
  768. } else {
  769. wpa_printf(MSG_DEBUG, "WPS ER: Protocol run %s with the "
  770. "enrollee (res=%d)",
  771. res == WPS_DONE ? "succeeded" : "failed", res);
  772. wps_deinit(sta->wps);
  773. sta->wps = NULL;
  774. if (res == WPS_DONE) {
  775. /* Remove the STA entry after short timeout */
  776. eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
  777. eloop_register_timeout(10, 0, wps_er_sta_timeout, sta,
  778. NULL);
  779. }
  780. }
  781. }
  782. static void wps_er_sta_start(struct wps_er_sta *sta, struct wpabuf *msg)
  783. {
  784. struct wps_config cfg;
  785. if (sta->wps)
  786. wps_deinit(sta->wps);
  787. os_memset(&cfg, 0, sizeof(cfg));
  788. cfg.wps = sta->ap->er->wps;
  789. cfg.registrar = 1;
  790. cfg.peer_addr = sta->addr;
  791. sta->wps = wps_init(&cfg);
  792. if (sta->wps == NULL)
  793. return;
  794. sta->wps->er = 1;
  795. sta->wps->use_cred = sta->ap->ap_settings;
  796. wps_er_sta_process(sta, msg, WSC_MSG);
  797. }
  798. static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr,
  799. struct wpabuf *msg)
  800. {
  801. struct wps_parse_attr attr;
  802. struct wps_er_sta *sta;
  803. wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR,
  804. MAC2STR(addr));
  805. wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
  806. "(TLVs from EAP-WSC)", msg);
  807. if (wps_parse_msg(msg, &attr) < 0) {
  808. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
  809. "WLANEvent message");
  810. return;
  811. }
  812. sta = wps_er_add_sta_data(ap, addr, &attr, 0);
  813. if (sta == NULL)
  814. return;
  815. if (attr.msg_type && *attr.msg_type == WPS_M1)
  816. wps_er_sta_start(sta, msg);
  817. else if (sta->wps) {
  818. enum wsc_op_code op_code = WSC_MSG;
  819. if (attr.msg_type) {
  820. switch (*attr.msg_type) {
  821. case WPS_WSC_ACK:
  822. op_code = WSC_ACK;
  823. break;
  824. case WPS_WSC_NACK:
  825. op_code = WSC_NACK;
  826. break;
  827. case WPS_WSC_DONE:
  828. op_code = WSC_Done;
  829. break;
  830. }
  831. }
  832. wps_er_sta_process(sta, msg, op_code);
  833. }
  834. }
  835. static void wps_er_process_wlanevent(struct wps_er_ap *ap,
  836. struct wpabuf *event)
  837. {
  838. u8 *data;
  839. u8 wlan_event_type;
  840. u8 wlan_event_mac[ETH_ALEN];
  841. struct wpabuf msg;
  842. wpa_hexdump(MSG_MSGDUMP, "WPS ER: Received WLANEvent",
  843. wpabuf_head(event), wpabuf_len(event));
  844. if (wpabuf_len(event) < 1 + 17) {
  845. wpa_printf(MSG_DEBUG, "WPS ER: Too short WLANEvent");
  846. return;
  847. }
  848. data = wpabuf_mhead(event);
  849. wlan_event_type = data[0];
  850. if (hwaddr_aton((char *) data + 1, wlan_event_mac) < 0) {
  851. wpa_printf(MSG_DEBUG, "WPS ER: Invalid WLANEventMAC in "
  852. "WLANEvent");
  853. return;
  854. }
  855. wpabuf_set(&msg, data + 1 + 17, wpabuf_len(event) - (1 + 17));
  856. switch (wlan_event_type) {
  857. case 1:
  858. wps_er_process_wlanevent_probe_req(ap, wlan_event_mac, &msg);
  859. break;
  860. case 2:
  861. wps_er_process_wlanevent_eap(ap, wlan_event_mac, &msg);
  862. break;
  863. default:
  864. wpa_printf(MSG_DEBUG, "WPS ER: Unknown WLANEventType %d",
  865. wlan_event_type);
  866. break;
  867. }
  868. }
  869. static void wps_er_http_event(struct wps_er *er, struct http_request *req,
  870. unsigned int ap_id)
  871. {
  872. struct wps_er_ap *ap = wps_er_ap_get_id(er, ap_id);
  873. struct wpabuf *event;
  874. enum http_reply_code ret;
  875. if (ap == NULL) {
  876. wpa_printf(MSG_DEBUG, "WPS ER: HTTP event from unknown AP id "
  877. "%u", ap_id);
  878. wps_er_http_resp_not_found(req);
  879. return;
  880. }
  881. wpa_printf(MSG_MSGDUMP, "WPS ER: HTTP event from AP id %u: %s",
  882. ap_id, http_request_get_data(req));
  883. event = xml_get_base64_item(http_request_get_data(req), "WLANEvent",
  884. &ret);
  885. if (event == NULL) {
  886. wpa_printf(MSG_DEBUG, "WPS ER: Could not extract WLANEvent "
  887. "from the event notification");
  888. /*
  889. * Reply with OK anyway to avoid getting unregistered from
  890. * events.
  891. */
  892. wps_er_http_resp_ok(req);
  893. return;
  894. }
  895. wps_er_process_wlanevent(ap, event);
  896. wpabuf_free(event);
  897. wps_er_http_resp_ok(req);
  898. }
  899. static void wps_er_http_notify(struct wps_er *er, struct http_request *req)
  900. {
  901. char *uri = http_request_get_uri(req);
  902. if (os_strncmp(uri, "/event/", 7) == 0) {
  903. unsigned int event_id;
  904. char *pos;
  905. event_id = atoi(uri + 7);
  906. if (event_id != er->event_id) {
  907. wpa_printf(MSG_DEBUG, "WPS ER: HTTP event for an "
  908. "unknown event id %u", event_id);
  909. return;
  910. }
  911. pos = os_strchr(uri + 7, '/');
  912. if (pos == NULL)
  913. return;
  914. pos++;
  915. wps_er_http_event(er, req, atoi(pos));
  916. } else {
  917. wpa_printf(MSG_DEBUG, "WPS ER: Unknown HTTP NOTIFY for '%s'",
  918. uri);
  919. wps_er_http_resp_not_found(req);
  920. }
  921. }
  922. static void wps_er_http_req(void *ctx, struct http_request *req)
  923. {
  924. struct wps_er *er = ctx;
  925. struct sockaddr_in *cli = http_request_get_cli_addr(req);
  926. enum httpread_hdr_type type = http_request_get_type(req);
  927. struct wpabuf *buf;
  928. wpa_printf(MSG_DEBUG, "WPS ER: HTTP request: '%s' (type %d) from "
  929. "%s:%d",
  930. http_request_get_uri(req), type,
  931. inet_ntoa(cli->sin_addr), ntohs(cli->sin_port));
  932. switch (type) {
  933. case HTTPREAD_HDR_TYPE_NOTIFY:
  934. wps_er_http_notify(er, req);
  935. break;
  936. default:
  937. wpa_printf(MSG_DEBUG, "WPS ER: Unsupported HTTP request type "
  938. "%d", type);
  939. buf = wpabuf_alloc(200);
  940. if (buf == NULL) {
  941. http_request_deinit(req);
  942. return;
  943. }
  944. wpabuf_put_str(buf,
  945. "HTTP/1.1 501 Unimplemented\r\n"
  946. "Connection: close\r\n");
  947. http_put_date(buf);
  948. wpabuf_put_str(buf, "\r\n");
  949. http_request_send_and_deinit(req, buf);
  950. break;
  951. }
  952. }
  953. struct wps_er *
  954. wps_er_init(struct wps_context *wps, const char *ifname)
  955. {
  956. struct wps_er *er;
  957. struct in_addr addr;
  958. er = os_zalloc(sizeof(*er));
  959. if (er == NULL)
  960. return NULL;
  961. dl_list_init(&er->ap);
  962. dl_list_init(&er->ap_unsubscribing);
  963. er->multicast_sd = -1;
  964. er->ssdp_sd = -1;
  965. os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
  966. er->wps = wps;
  967. os_get_random((unsigned char *) &er->event_id, sizeof(er->event_id));
  968. if (get_netif_info(ifname, &er->ip_addr, &er->ip_addr_text,
  969. er->mac_addr)) {
  970. wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
  971. "for %s. Does it have IP address?", ifname);
  972. wps_er_deinit(er, NULL, NULL);
  973. return NULL;
  974. }
  975. if (wps_er_ssdp_init(er) < 0) {
  976. wps_er_deinit(er, NULL, NULL);
  977. return NULL;
  978. }
  979. addr.s_addr = er->ip_addr;
  980. er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er);
  981. if (er->http_srv == NULL) {
  982. wps_er_deinit(er, NULL, NULL);
  983. return NULL;
  984. }
  985. er->http_port = http_server_get_port(er->http_srv);
  986. wpa_printf(MSG_DEBUG, "WPS ER: Start (ifname=%s ip_addr=%s)",
  987. er->ifname, er->ip_addr_text);
  988. return er;
  989. }
  990. void wps_er_refresh(struct wps_er *er)
  991. {
  992. struct wps_er_ap *ap;
  993. struct wps_er_sta *sta;
  994. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
  995. wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_ADD);
  996. dl_list_for_each(sta, &ap->sta, struct wps_er_sta, list)
  997. wps_er_sta_event(er->wps, sta, WPS_EV_ER_ENROLLEE_ADD);
  998. }
  999. wps_er_send_ssdp_msearch(er);
  1000. }
  1001. static void wps_er_deinit_finish(void *eloop_data, void *user_ctx)
  1002. {
  1003. struct wps_er *er = eloop_data;
  1004. void (*deinit_done_cb)(void *ctx);
  1005. void *deinit_done_ctx;
  1006. wpa_printf(MSG_DEBUG, "WPS ER: Finishing deinit");
  1007. deinit_done_cb = er->deinit_done_cb;
  1008. deinit_done_ctx = er->deinit_done_ctx;
  1009. os_free(er->ip_addr_text);
  1010. os_free(er);
  1011. if (deinit_done_cb)
  1012. deinit_done_cb(deinit_done_ctx);
  1013. }
  1014. void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx)
  1015. {
  1016. if (er == NULL)
  1017. return;
  1018. http_server_deinit(er->http_srv);
  1019. wps_er_ap_remove_all(er);
  1020. wps_er_ssdp_deinit(er);
  1021. eloop_register_timeout(dl_list_empty(&er->ap_unsubscribing) ? 0 : 5, 0,
  1022. wps_er_deinit_finish, er, NULL);
  1023. wpa_printf(MSG_DEBUG, "WPS ER: Finish deinit from timeout");
  1024. er->deinitializing = 1;
  1025. er->deinit_done_cb = cb;
  1026. er->deinit_done_ctx = ctx;
  1027. }
  1028. static void wps_er_http_set_sel_reg_cb(void *ctx, struct http_client *c,
  1029. enum http_client_event event)
  1030. {
  1031. struct wps_er_ap *ap = ctx;
  1032. switch (event) {
  1033. case HTTP_CLIENT_OK:
  1034. wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar OK");
  1035. break;
  1036. case HTTP_CLIENT_FAILED:
  1037. case HTTP_CLIENT_INVALID_REPLY:
  1038. case HTTP_CLIENT_TIMEOUT:
  1039. wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar failed");
  1040. break;
  1041. }
  1042. http_client_free(ap->http);
  1043. ap->http = NULL;
  1044. }
  1045. static void wps_er_send_set_sel_reg(struct wps_er_ap *ap, struct wpabuf *msg)
  1046. {
  1047. struct wpabuf *buf;
  1048. char *len_ptr, *body_ptr;
  1049. struct sockaddr_in dst;
  1050. char *url, *path;
  1051. if (ap->control_url == NULL) {
  1052. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  1053. return;
  1054. }
  1055. if (ap->http) {
  1056. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for AP - "
  1057. "ignore new request");
  1058. return;
  1059. }
  1060. url = http_client_url_parse(ap->control_url, &dst, &path);
  1061. if (url == NULL) {
  1062. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
  1063. return;
  1064. }
  1065. buf = wps_er_soap_hdr(msg, "SetSelectedRegistrar", "NewMessage", path,
  1066. &dst, &len_ptr, &body_ptr);
  1067. os_free(url);
  1068. if (buf == NULL)
  1069. return;
  1070. wps_er_soap_end(buf, "SetSelectedRegistrar", len_ptr, body_ptr);
  1071. ap->http = http_client_addr(&dst, buf, 1000,
  1072. wps_er_http_set_sel_reg_cb, ap);
  1073. if (ap->http == NULL)
  1074. wpabuf_free(buf);
  1075. }
  1076. static int wps_er_build_selected_registrar(struct wpabuf *msg, int sel_reg)
  1077. {
  1078. wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
  1079. wpabuf_put_be16(msg, 1);
  1080. wpabuf_put_u8(msg, !!sel_reg);
  1081. return 0;
  1082. }
  1083. static int wps_er_build_dev_password_id(struct wpabuf *msg, u16 dev_passwd_id)
  1084. {
  1085. wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
  1086. wpabuf_put_be16(msg, 2);
  1087. wpabuf_put_be16(msg, dev_passwd_id);
  1088. return 0;
  1089. }
  1090. static int wps_er_build_sel_reg_config_methods(struct wpabuf *msg,
  1091. u16 sel_reg_config_methods)
  1092. {
  1093. wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
  1094. wpabuf_put_be16(msg, 2);
  1095. wpabuf_put_be16(msg, sel_reg_config_methods);
  1096. return 0;
  1097. }
  1098. void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
  1099. u16 sel_reg_config_methods)
  1100. {
  1101. struct wpabuf *msg;
  1102. struct wps_er_ap *ap;
  1103. msg = wpabuf_alloc(500);
  1104. if (msg == NULL)
  1105. return;
  1106. if (wps_build_version(msg) ||
  1107. wps_er_build_selected_registrar(msg, sel_reg) ||
  1108. wps_er_build_dev_password_id(msg, dev_passwd_id) ||
  1109. wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods)) {
  1110. wpabuf_free(msg);
  1111. return;
  1112. }
  1113. dl_list_for_each(ap, &er->ap, struct wps_er_ap, list)
  1114. wps_er_send_set_sel_reg(ap, msg);
  1115. wpabuf_free(msg);
  1116. }
  1117. int wps_er_pbc(struct wps_er *er, const u8 *uuid)
  1118. {
  1119. if (er == NULL || er->wps == NULL)
  1120. return -1;
  1121. /*
  1122. * TODO: Should enable PBC mode only in a single AP based on which AP
  1123. * the Enrollee (uuid) is using. Now, we may end up enabling multiple
  1124. * APs in PBC mode which could result in session overlap at the
  1125. * Enrollee.
  1126. */
  1127. if (wps_registrar_button_pushed(er->wps->registrar))
  1128. return -1;
  1129. return 0;
  1130. }
  1131. static void wps_er_ap_settings_cb(void *ctx, const struct wps_credential *cred)
  1132. {
  1133. struct wps_er_ap *ap = ctx;
  1134. wpa_printf(MSG_DEBUG, "WPS ER: AP Settings received");
  1135. os_free(ap->ap_settings);
  1136. ap->ap_settings = os_malloc(sizeof(*cred));
  1137. if (ap->ap_settings) {
  1138. os_memcpy(ap->ap_settings, cred, sizeof(*cred));
  1139. ap->ap_settings->cred_attr = NULL;
  1140. }
  1141. /* TODO: send info through ctrl_iface */
  1142. }
  1143. static void wps_er_http_put_message_cb(void *ctx, struct http_client *c,
  1144. enum http_client_event event)
  1145. {
  1146. struct wps_er_ap *ap = ctx;
  1147. struct wpabuf *reply;
  1148. char *msg = NULL;
  1149. switch (event) {
  1150. case HTTP_CLIENT_OK:
  1151. wpa_printf(MSG_DEBUG, "WPS ER: PutMessage OK");
  1152. reply = http_client_get_body(c);
  1153. if (reply == NULL)
  1154. break;
  1155. msg = os_zalloc(wpabuf_len(reply) + 1);
  1156. if (msg == NULL)
  1157. break;
  1158. os_memcpy(msg, wpabuf_head(reply), wpabuf_len(reply));
  1159. break;
  1160. case HTTP_CLIENT_FAILED:
  1161. case HTTP_CLIENT_INVALID_REPLY:
  1162. case HTTP_CLIENT_TIMEOUT:
  1163. wpa_printf(MSG_DEBUG, "WPS ER: PutMessage failed");
  1164. if (ap->wps) {
  1165. wps_deinit(ap->wps);
  1166. ap->wps = NULL;
  1167. }
  1168. break;
  1169. }
  1170. http_client_free(ap->http);
  1171. ap->http = NULL;
  1172. if (msg) {
  1173. struct wpabuf *buf;
  1174. enum http_reply_code ret;
  1175. buf = xml_get_base64_item(msg, "NewOutMessage", &ret);
  1176. os_free(msg);
  1177. if (buf == NULL) {
  1178. wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
  1179. "NewOutMessage from PutMessage response");
  1180. return;
  1181. }
  1182. wps_er_ap_process(ap, buf);
  1183. wpabuf_free(buf);
  1184. }
  1185. }
  1186. static void wps_er_ap_put_message(struct wps_er_ap *ap,
  1187. const struct wpabuf *msg)
  1188. {
  1189. struct wpabuf *buf;
  1190. char *len_ptr, *body_ptr;
  1191. struct sockaddr_in dst;
  1192. char *url, *path;
  1193. if (ap->http) {
  1194. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
  1195. "with the AP - cannot continue learn");
  1196. return;
  1197. }
  1198. if (ap->control_url == NULL) {
  1199. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  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, "PutMessage", "NewInMessage", path, &dst,
  1208. &len_ptr, &body_ptr);
  1209. os_free(url);
  1210. if (buf == NULL)
  1211. return;
  1212. wps_er_soap_end(buf, "PutMessage", len_ptr, body_ptr);
  1213. ap->http = http_client_addr(&dst, buf, 10000,
  1214. wps_er_http_put_message_cb, ap);
  1215. if (ap->http == NULL)
  1216. wpabuf_free(buf);
  1217. }
  1218. static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg)
  1219. {
  1220. enum wps_process_res res;
  1221. res = wps_process_msg(ap->wps, WSC_MSG, msg);
  1222. if (res == WPS_CONTINUE) {
  1223. enum wsc_op_code op_code;
  1224. struct wpabuf *next = wps_get_msg(ap->wps, &op_code);
  1225. if (next) {
  1226. wps_er_ap_put_message(ap, next);
  1227. wpabuf_free(next);
  1228. } else {
  1229. wpa_printf(MSG_DEBUG, "WPS ER: Failed to build "
  1230. "message");
  1231. wps_deinit(ap->wps);
  1232. ap->wps = NULL;
  1233. }
  1234. } else {
  1235. wpa_printf(MSG_DEBUG, "WPS ER: Failed to process message from "
  1236. "AP (res=%d)", res);
  1237. wps_deinit(ap->wps);
  1238. ap->wps = NULL;
  1239. }
  1240. }
  1241. static void wps_er_ap_learn_m1(struct wps_er_ap *ap, struct wpabuf *m1)
  1242. {
  1243. struct wps_config cfg;
  1244. if (ap->wps) {
  1245. wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in "
  1246. "progress with this AP");
  1247. return;
  1248. }
  1249. os_memset(&cfg, 0, sizeof(cfg));
  1250. cfg.wps = ap->er->wps;
  1251. cfg.registrar = 1;
  1252. ap->wps = wps_init(&cfg);
  1253. if (ap->wps == NULL)
  1254. return;
  1255. ap->wps->ap_settings_cb = wps_er_ap_settings_cb;
  1256. ap->wps->ap_settings_cb_ctx = ap;
  1257. wps_er_ap_process(ap, m1);
  1258. }
  1259. static void wps_er_ap_learn(struct wps_er_ap *ap, const char *dev_info)
  1260. {
  1261. struct wpabuf *info;
  1262. enum http_reply_code ret;
  1263. wpa_printf(MSG_DEBUG, "WPS ER: Received GetDeviceInfo response (M1) "
  1264. "from the AP");
  1265. info = xml_get_base64_item(dev_info, "NewDeviceInfo", &ret);
  1266. if (info == NULL) {
  1267. wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
  1268. "NewDeviceInfo from GetDeviceInfo response");
  1269. return;
  1270. }
  1271. ap->m1_handler(ap, info);
  1272. wpabuf_free(info);
  1273. }
  1274. static void wps_er_http_get_dev_info_cb(void *ctx, struct http_client *c,
  1275. enum http_client_event event)
  1276. {
  1277. struct wps_er_ap *ap = ctx;
  1278. struct wpabuf *reply;
  1279. char *dev_info = NULL;
  1280. switch (event) {
  1281. case HTTP_CLIENT_OK:
  1282. wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo OK");
  1283. reply = http_client_get_body(c);
  1284. if (reply == NULL)
  1285. break;
  1286. dev_info = os_zalloc(wpabuf_len(reply) + 1);
  1287. if (dev_info == NULL)
  1288. break;
  1289. os_memcpy(dev_info, wpabuf_head(reply), wpabuf_len(reply));
  1290. break;
  1291. case HTTP_CLIENT_FAILED:
  1292. case HTTP_CLIENT_INVALID_REPLY:
  1293. case HTTP_CLIENT_TIMEOUT:
  1294. wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo failed");
  1295. break;
  1296. }
  1297. http_client_free(ap->http);
  1298. ap->http = NULL;
  1299. if (dev_info) {
  1300. wps_er_ap_learn(ap, dev_info);
  1301. os_free(dev_info);
  1302. }
  1303. }
  1304. static int wps_er_send_get_device_info(struct wps_er_ap *ap,
  1305. void (*m1_handler)(struct wps_er_ap *ap,
  1306. struct wpabuf *m1))
  1307. {
  1308. struct wpabuf *buf;
  1309. char *len_ptr, *body_ptr;
  1310. struct sockaddr_in dst;
  1311. char *url, *path;
  1312. if (ap->http) {
  1313. wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
  1314. "with the AP - cannot get device info");
  1315. return -1;
  1316. }
  1317. if (ap->control_url == NULL) {
  1318. wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
  1319. return -1;
  1320. }
  1321. url = http_client_url_parse(ap->control_url, &dst, &path);
  1322. if (url == NULL) {
  1323. wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
  1324. return -1;
  1325. }
  1326. buf = wps_er_soap_hdr(NULL, "GetDeviceInfo", NULL, path, &dst,
  1327. &len_ptr, &body_ptr);
  1328. os_free(url);
  1329. if (buf == NULL)
  1330. return -1;
  1331. wps_er_soap_end(buf, "GetDeviceInfo", len_ptr, body_ptr);
  1332. ap->http = http_client_addr(&dst, buf, 10000,
  1333. wps_er_http_get_dev_info_cb, ap);
  1334. if (ap->http == NULL) {
  1335. wpabuf_free(buf);
  1336. return -1;
  1337. }
  1338. ap->m1_handler = m1_handler;
  1339. return 0;
  1340. }
  1341. int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
  1342. size_t pin_len)
  1343. {
  1344. struct wps_er_ap *ap;
  1345. if (er == NULL)
  1346. return -1;
  1347. ap = wps_er_ap_get(er, NULL, uuid);
  1348. if (ap == NULL) {
  1349. wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
  1350. "request");
  1351. return -1;
  1352. }
  1353. if (ap->wps) {
  1354. wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
  1355. "with the AP - cannot start learn");
  1356. return -1;
  1357. }
  1358. if (wps_er_send_get_device_info(ap, wps_er_ap_learn_m1) < 0)
  1359. return -1;
  1360. /* TODO: add PIN without SetSelectedRegistrar trigger to all APs */
  1361. wps_registrar_add_pin(er->wps->registrar, uuid, pin, pin_len, 0);
  1362. return 0;
  1363. }