wps_er.c 39 KB

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