5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <gweb/gweb.h>
33 #define DEFAULT_URL "http://www.connman.net/online/status.html"
37 static GMainLoop *main_loop;
39 static void web_debug(const char *str, void *data)
41 g_print("%s: %s\n", (const char *) data, str);
44 static void sig_term(int sig)
46 g_main_loop_quit(main_loop);
49 static const char *message_type_to_string(int message_type)
51 switch (message_type) {
53 return "Initial redirect message";
55 return "Proxy notification";
57 return "Authentication notification";
59 return "Logoff notification";
61 return "Response to Authentication Poll";
63 return "Response to Abort Login";
69 static const char *response_code_to_string(int response_code)
71 switch (response_code) {
75 return "Login succeeded";
77 return "Login failed";
79 return "RADIUS server error/timeout";
81 return "RADIUS server not enabled";
83 return "Logoff succeeded";
85 return "Login aborted";
87 return "Proxy detection/repeat operation";
89 return "Authentication pending";
91 return "Access gateway internal error";
99 const char *current_element;
104 char *access_procedure;
105 char *access_location;
109 static inline void wispr_msg_init(struct wispr_msg *msg)
111 msg->has_error = FALSE;
112 msg->current_element = NULL;
114 msg->message_type = -1;
115 msg->response_code = -1;
117 g_free(msg->login_url);
118 msg->login_url = NULL;
120 g_free(msg->logoff_url);
121 msg->logoff_url = NULL;
123 g_free(msg->access_procedure);
124 msg->access_procedure = NULL;
126 g_free(msg->access_location);
127 msg->access_location = NULL;
129 g_free(msg->location_name);
130 msg->location_name = NULL;
133 struct wispr_session {
137 struct wispr_msg msg;
138 const char *username;
139 const char *password;
140 const char *originurl;
148 WISPR_ELEMENT_ACCESS_PROCEDURE,
149 WISPR_ELEMENT_ACCESS_LOCATION,
150 WISPR_ELEMENT_LOCATION_NAME,
151 WISPR_ELEMENT_LOGIN_URL,
152 WISPR_ELEMENT_ABORT_LOGIN_URL,
153 WISPR_ELEMENT_MESSAGE_TYPE,
154 WISPR_ELEMENT_RESPONSE_CODE,
155 WISPR_ELEMENT_NEXT_URL,
157 WISPR_ELEMENT_REPLY_MESSAGE,
158 WISPR_ELEMENT_LOGIN_RESULTS_URL,
159 WISPR_ELEMENT_LOGOFF_URL,
161 } wispr_element_map[] = {
162 { "AccessProcedure", WISPR_ELEMENT_ACCESS_PROCEDURE },
163 { "AccessLocation", WISPR_ELEMENT_ACCESS_LOCATION },
164 { "LocationName", WISPR_ELEMENT_LOCATION_NAME },
165 { "LoginURL", WISPR_ELEMENT_LOGIN_URL },
166 { "AbortLoginURL", WISPR_ELEMENT_ABORT_LOGIN_URL },
167 { "MessageType", WISPR_ELEMENT_MESSAGE_TYPE },
168 { "ResponseCode", WISPR_ELEMENT_RESPONSE_CODE },
169 { "NextURL", WISPR_ELEMENT_NEXT_URL },
170 { "Delay", WISPR_ELEMENT_DELAY },
171 { "ReplyMessage", WISPR_ELEMENT_REPLY_MESSAGE },
172 { "LoginResultsURL", WISPR_ELEMENT_LOGIN_RESULTS_URL },
173 { "LogoffURL", WISPR_ELEMENT_LOGOFF_URL },
174 { NULL, WISPR_ELEMENT_NONE },
177 static void start_element_handler(GMarkupParseContext *context,
178 const gchar *element_name,
179 const gchar **attribute_names,
180 const gchar **attribute_values,
181 gpointer user_data, GError **error)
183 struct wispr_msg *msg = user_data;
185 msg->current_element = element_name;
188 static void end_element_handler(GMarkupParseContext *context,
189 const gchar *element_name,
190 gpointer user_data, GError **error)
192 struct wispr_msg *msg = user_data;
194 msg->current_element = NULL;
197 static void text_handler(GMarkupParseContext *context,
198 const gchar *text, gsize text_len,
199 gpointer user_data, GError **error)
201 struct wispr_msg *msg = user_data;
204 if (msg->current_element == NULL)
207 for (i = 0; wispr_element_map[i].str; i++) {
208 if (g_str_equal(wispr_element_map[i].str,
209 msg->current_element) == FALSE)
212 switch (wispr_element_map[i].element) {
213 case WISPR_ELEMENT_NONE:
214 case WISPR_ELEMENT_ACCESS_PROCEDURE:
215 g_free(msg->access_procedure);
216 msg->access_procedure = g_strdup(text);
217 case WISPR_ELEMENT_ACCESS_LOCATION:
218 g_free(msg->access_location);
219 msg->access_location = g_strdup(text);
220 case WISPR_ELEMENT_LOCATION_NAME:
221 g_free(msg->location_name);
222 msg->location_name = g_strdup(text);
224 case WISPR_ELEMENT_LOGIN_URL:
225 g_free(msg->login_url);
226 msg->login_url = g_strdup(text);
228 case WISPR_ELEMENT_ABORT_LOGIN_URL:
230 case WISPR_ELEMENT_MESSAGE_TYPE:
231 msg->message_type = atoi(text);
233 case WISPR_ELEMENT_RESPONSE_CODE:
234 msg->response_code = atoi(text);
236 case WISPR_ELEMENT_NEXT_URL:
237 case WISPR_ELEMENT_DELAY:
238 case WISPR_ELEMENT_REPLY_MESSAGE:
239 case WISPR_ELEMENT_LOGIN_RESULTS_URL:
241 case WISPR_ELEMENT_LOGOFF_URL:
242 g_free(msg->logoff_url);
243 msg->logoff_url = g_strdup(text);
249 static void error_handler(GMarkupParseContext *context,
250 GError *error, gpointer user_data)
252 struct wispr_msg *msg = user_data;
254 msg->has_error = TRUE;
257 static const GMarkupParser wispr_parser = {
258 start_element_handler,
265 static void parser_callback(const char *str, gpointer user_data)
267 struct wispr_session *wispr = user_data;
268 GMarkupParseContext *context;
271 //printf("%s\n", str);
273 context = g_markup_parse_context_new(&wispr_parser,
274 G_MARKUP_TREAT_CDATA_AS_TEXT, &wispr->msg, NULL);
276 result = g_markup_parse_context_parse(context, str, strlen(str), NULL);
278 result = g_markup_parse_context_end_parse(context, NULL);
280 g_markup_parse_context_free(context);
283 static gboolean wispr_input(const guint8 **data, gsize *length,
286 struct wispr_session *wispr = user_data;
288 g_free(wispr->formdata);
289 wispr->formdata = g_strdup_printf("button=Login&UserName=%s&"
290 "Password=%s&FNAME=0&OriginatingServer=%s",
291 wispr->username, wispr->password, wispr->originurl);
293 *data = (guint8 *) wispr->formdata;
294 *length = strlen(wispr->formdata);
299 static gboolean wispr_result(GWebResult *result, gpointer user_data)
301 struct wispr_session *wispr = user_data;
307 g_web_result_get_chunk(result, &chunk, &length);
310 //printf("%s\n", (char *) chunk);
311 g_web_parser_feed_data(wispr->parser, chunk, length);
315 g_web_parser_end_data(wispr->parser);
317 status = g_web_result_get_status(result);
319 g_print("status: %03u\n", status);
321 elapsed = g_timer_elapsed(timer, NULL);
323 g_print("elapse: %f seconds\n", elapsed);
325 if (wispr->msg.message_type < 0)
328 printf("Message type: %s (%d)\n",
329 message_type_to_string(wispr->msg.message_type),
330 wispr->msg.message_type);
331 printf("Response code: %s (%d)\n",
332 response_code_to_string(wispr->msg.response_code),
333 wispr->msg.response_code);
334 if (wispr->msg.access_procedure != NULL)
335 printf("Access procedure: %s\n", wispr->msg.access_procedure);
336 if (wispr->msg.access_location != NULL)
337 printf("Access location: %s\n", wispr->msg.access_location);
338 if (wispr->msg.location_name != NULL)
339 printf("Location name: %s\n", wispr->msg.location_name);
340 if (wispr->msg.login_url != NULL)
341 printf("Login URL: %s\n", wispr->msg.login_url);
342 if (wispr->msg.logoff_url != NULL)
343 printf("Logoff URL: %s\n", wispr->msg.logoff_url);
346 if (status == 302 && wispr->msg.message_type == 100) {
347 wispr->request = g_web_request_post(wispr->web,
348 wispr->msg.login_url,
349 "application/x-www-form-urlencoded",
350 wispr_input, wispr_result, wispr);
352 wispr_msg_init(&wispr->msg);
355 } else if (status == 200 && wispr->msg.message_type == 120) {
356 int code = wispr->msg.response_code;
357 printf("Login process: %s\n",
358 code == 50 ? "SUCCESS" : "FAILURE");
362 g_main_loop_quit(main_loop);
367 static gboolean option_debug = FALSE;
368 static gchar *option_nameserver = NULL;
369 static gchar *option_username = NULL;
370 static gchar *option_password = NULL;
371 static gchar *option_url = NULL;
373 static GOptionEntry options[] = {
374 { "debug", 'd', 0, G_OPTION_ARG_NONE, &option_debug,
375 "Enable debug output" },
376 { "nameserver", 'n', 0, G_OPTION_ARG_STRING, &option_nameserver,
377 "Specify nameserver", "ADDRESS" },
378 { "username", 'u', 0, G_OPTION_ARG_STRING, &option_username,
379 "Specify username", "USERNAME" },
380 { "password", 'p', 0, G_OPTION_ARG_STRING, &option_password,
381 "Specify password", "PASSWORD" },
382 { "url", 'U', 0, G_OPTION_ARG_STRING, &option_url,
383 "Specify arbitrary request", "URL" },
387 int main(int argc, char *argv[])
389 GOptionContext *context;
390 GError *error = NULL;
392 struct wispr_session wispr;
395 context = g_option_context_new(NULL);
396 g_option_context_add_main_entries(context, options, NULL);
398 if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) {
400 g_printerr("%s\n", error->message);
403 g_printerr("An unknown error occurred\n");
407 g_option_context_free(context);
409 memset(&wispr, 0, sizeof(wispr));
410 wispr_msg_init(&wispr.msg);
412 wispr.web = g_web_new(index);
413 if (wispr.web == NULL) {
414 fprintf(stderr, "Failed to create web service\n");
418 if (option_debug == TRUE)
419 g_web_set_debug(wispr.web, web_debug, "WEB");
421 main_loop = g_main_loop_new(NULL, FALSE);
423 if (option_nameserver != NULL) {
424 g_web_add_nameserver(wispr.web, option_nameserver);
425 g_free(option_nameserver);
428 g_web_set_accept(wispr.web, NULL);
429 g_web_set_user_agent(wispr.web, "SmartClient/%s wispr", VERSION);
430 g_web_set_close_connection(wispr.web, TRUE);
432 if (option_url == NULL)
433 option_url = g_strdup(DEFAULT_URL);
435 wispr.username = option_username;
436 wispr.password = option_password;
437 wispr.originurl = option_url;
439 timer = g_timer_new();
441 wispr.parser = g_web_parser_new("<WISPAccessGatewayParam",
442 "WISPAccessGatewayParam>",
443 parser_callback, &wispr);
445 wispr.request = g_web_request_get(wispr.web, option_url,
446 wispr_result, &wispr);
448 if (wispr.request == 0) {
449 fprintf(stderr, "Failed to start request\n");
453 memset(&sa, 0, sizeof(sa));
454 sa.sa_handler = sig_term;
455 sigaction(SIGINT, &sa, NULL);
456 sigaction(SIGTERM, &sa, NULL);
458 g_main_loop_run(main_loop);
460 g_timer_destroy(timer);
462 if (wispr.request > 0)
463 g_web_cancel_request(wispr.web, wispr.request);
465 g_web_parser_unref(wispr.parser);
466 g_web_unref(wispr.web);
468 g_main_loop_unref(main_loop);
470 g_free(option_username);
471 g_free(option_password);