1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * Hotspot 2.0 client - Web browser using system browser 3e5b75505Sopenharmony_ci * Copyright (c) 2013, Qualcomm Atheros, Inc. 4e5b75505Sopenharmony_ci * 5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 6e5b75505Sopenharmony_ci * See README for more details. 7e5b75505Sopenharmony_ci */ 8e5b75505Sopenharmony_ci 9e5b75505Sopenharmony_ci#include "includes.h" 10e5b75505Sopenharmony_ci 11e5b75505Sopenharmony_ci#include "common.h" 12e5b75505Sopenharmony_ci#include "utils/eloop.h" 13e5b75505Sopenharmony_ci#include "wps/http_server.h" 14e5b75505Sopenharmony_ci#include "browser.h" 15e5b75505Sopenharmony_ci 16e5b75505Sopenharmony_ci 17e5b75505Sopenharmony_cistruct browser_data { 18e5b75505Sopenharmony_ci int success; 19e5b75505Sopenharmony_ci}; 20e5b75505Sopenharmony_ci 21e5b75505Sopenharmony_ci 22e5b75505Sopenharmony_cistatic void browser_timeout(void *eloop_data, void *user_ctx) 23e5b75505Sopenharmony_ci{ 24e5b75505Sopenharmony_ci wpa_printf(MSG_INFO, "Timeout on waiting browser interaction to " 25e5b75505Sopenharmony_ci "complete"); 26e5b75505Sopenharmony_ci eloop_terminate(); 27e5b75505Sopenharmony_ci} 28e5b75505Sopenharmony_ci 29e5b75505Sopenharmony_ci 30e5b75505Sopenharmony_cistatic void http_req(void *ctx, struct http_request *req) 31e5b75505Sopenharmony_ci{ 32e5b75505Sopenharmony_ci struct browser_data *data = ctx; 33e5b75505Sopenharmony_ci struct wpabuf *resp; 34e5b75505Sopenharmony_ci const char *url; 35e5b75505Sopenharmony_ci int done = 0; 36e5b75505Sopenharmony_ci 37e5b75505Sopenharmony_ci url = http_request_get_uri(req); 38e5b75505Sopenharmony_ci wpa_printf(MSG_INFO, "Browser response received: %s", url); 39e5b75505Sopenharmony_ci 40e5b75505Sopenharmony_ci if (os_strcmp(url, "/") == 0) { 41e5b75505Sopenharmony_ci data->success = 1; 42e5b75505Sopenharmony_ci done = 1; 43e5b75505Sopenharmony_ci } else if (os_strncmp(url, "/osu/", 5) == 0) { 44e5b75505Sopenharmony_ci data->success = atoi(url + 5); 45e5b75505Sopenharmony_ci done = 1; 46e5b75505Sopenharmony_ci } 47e5b75505Sopenharmony_ci 48e5b75505Sopenharmony_ci resp = wpabuf_alloc(1); 49e5b75505Sopenharmony_ci if (resp == NULL) { 50e5b75505Sopenharmony_ci http_request_deinit(req); 51e5b75505Sopenharmony_ci if (done) 52e5b75505Sopenharmony_ci eloop_terminate(); 53e5b75505Sopenharmony_ci return; 54e5b75505Sopenharmony_ci } 55e5b75505Sopenharmony_ci 56e5b75505Sopenharmony_ci if (done) { 57e5b75505Sopenharmony_ci eloop_cancel_timeout(browser_timeout, NULL, NULL); 58e5b75505Sopenharmony_ci eloop_register_timeout(0, 500000, browser_timeout, &data, NULL); 59e5b75505Sopenharmony_ci } 60e5b75505Sopenharmony_ci 61e5b75505Sopenharmony_ci http_request_send_and_deinit(req, resp); 62e5b75505Sopenharmony_ci} 63e5b75505Sopenharmony_ci 64e5b75505Sopenharmony_ci 65e5b75505Sopenharmony_ciint hs20_web_browser(const char *url, int ignore_tls) 66e5b75505Sopenharmony_ci{ 67e5b75505Sopenharmony_ci struct http_server *http; 68e5b75505Sopenharmony_ci struct in_addr addr; 69e5b75505Sopenharmony_ci struct browser_data data; 70e5b75505Sopenharmony_ci pid_t pid; 71e5b75505Sopenharmony_ci 72e5b75505Sopenharmony_ci wpa_printf(MSG_INFO, "Launching system browser to %s", url); 73e5b75505Sopenharmony_ci 74e5b75505Sopenharmony_ci os_memset(&data, 0, sizeof(data)); 75e5b75505Sopenharmony_ci 76e5b75505Sopenharmony_ci if (eloop_init() < 0) { 77e5b75505Sopenharmony_ci wpa_printf(MSG_ERROR, "eloop_init failed"); 78e5b75505Sopenharmony_ci return -1; 79e5b75505Sopenharmony_ci } 80e5b75505Sopenharmony_ci addr.s_addr = htonl((127 << 24) | 1); 81e5b75505Sopenharmony_ci http = http_server_init(&addr, 12345, http_req, &data); 82e5b75505Sopenharmony_ci if (http == NULL) { 83e5b75505Sopenharmony_ci wpa_printf(MSG_ERROR, "http_server_init failed"); 84e5b75505Sopenharmony_ci eloop_destroy(); 85e5b75505Sopenharmony_ci return -1; 86e5b75505Sopenharmony_ci } 87e5b75505Sopenharmony_ci 88e5b75505Sopenharmony_ci pid = fork(); 89e5b75505Sopenharmony_ci if (pid < 0) { 90e5b75505Sopenharmony_ci wpa_printf(MSG_ERROR, "fork: %s", strerror(errno)); 91e5b75505Sopenharmony_ci http_server_deinit(http); 92e5b75505Sopenharmony_ci eloop_destroy(); 93e5b75505Sopenharmony_ci return -1; 94e5b75505Sopenharmony_ci } 95e5b75505Sopenharmony_ci 96e5b75505Sopenharmony_ci if (pid == 0) { 97e5b75505Sopenharmony_ci /* run the external command in the child process */ 98e5b75505Sopenharmony_ci char *argv[3]; 99e5b75505Sopenharmony_ci 100e5b75505Sopenharmony_ci argv[0] = "browser-system"; 101e5b75505Sopenharmony_ci argv[1] = (void *) url; 102e5b75505Sopenharmony_ci argv[2] = NULL; 103e5b75505Sopenharmony_ci 104e5b75505Sopenharmony_ci execv("/usr/bin/x-www-browser", argv); 105e5b75505Sopenharmony_ci wpa_printf(MSG_ERROR, "execv: %s", strerror(errno)); 106e5b75505Sopenharmony_ci exit(0); 107e5b75505Sopenharmony_ci return -1; 108e5b75505Sopenharmony_ci } 109e5b75505Sopenharmony_ci 110e5b75505Sopenharmony_ci eloop_register_timeout(120, 0, browser_timeout, &data, NULL); 111e5b75505Sopenharmony_ci eloop_run(); 112e5b75505Sopenharmony_ci eloop_cancel_timeout(browser_timeout, &data, NULL); 113e5b75505Sopenharmony_ci http_server_deinit(http); 114e5b75505Sopenharmony_ci eloop_destroy(); 115e5b75505Sopenharmony_ci 116e5b75505Sopenharmony_ci /* TODO: Close browser */ 117e5b75505Sopenharmony_ci 118e5b75505Sopenharmony_ci return data.success; 119e5b75505Sopenharmony_ci} 120