/* * Hotspot 2.0 SPP server - standalone version * Copyright (c) 2012-2013, Qualcomm Atheros, Inc. * * This software may be distributed under the terms of the BSD license. * See README for more details. */ #include "includes.h" #include #include #include "common.h" #include "xml-utils.h" #include "spp_server.h" static void write_timestamp(FILE *f) { time_t t; struct tm *tm; time(&t); tm = localtime(&t); fprintf(f, "%04u-%02u-%02u %02u:%02u:%02u ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } void debug_print(struct hs20_svc *ctx, int print, const char *fmt, ...) { va_list ap; if (ctx->debug_log == NULL) return; write_timestamp(ctx->debug_log); va_start(ap, fmt); vfprintf(ctx->debug_log, fmt, ap); va_end(ap); fprintf(ctx->debug_log, "\n"); } void debug_dump_node(struct hs20_svc *ctx, const char *title, xml_node_t *node) { char *str; if (ctx->debug_log == NULL) return; str = xml_node_to_str(ctx->xml, node); if (str == NULL) return; write_timestamp(ctx->debug_log); fprintf(ctx->debug_log, "%s: '%s'\n", title, str); os_free(str); } static int process(struct hs20_svc *ctx) { int dmacc = 0; xml_node_t *soap, *spp, *resp; char *user, *realm, *post, *str; ctx->addr = getenv("HS20ADDR"); if (ctx->addr) debug_print(ctx, 1, "Connection from %s", ctx->addr); user = getenv("HS20USER"); if (user && strlen(user) == 0) user = NULL; realm = getenv("HS20REALM"); if (realm == NULL) { debug_print(ctx, 1, "HS20REALM not set"); return -1; } post = getenv("HS20POST"); if (post == NULL) { debug_print(ctx, 1, "HS20POST not set"); return -1; } soap = xml_node_from_buf(ctx->xml, post); if (soap == NULL) { debug_print(ctx, 1, "Could not parse SOAP data"); return -1; } debug_dump_node(ctx, "Received SOAP message", soap); spp = soap_get_body(ctx->xml, soap); if (spp == NULL) { debug_print(ctx, 1, "Could not get SPP message"); xml_node_free(ctx->xml, soap); return -1; } debug_dump_node(ctx, "Received SPP message", spp); resp = hs20_spp_server_process(ctx, spp, user, realm, dmacc); xml_node_free(ctx->xml, soap); if (resp == NULL && user == NULL) { debug_print(ctx, 1, "Request HTTP authentication"); return 2; /* Request authentication */ } if (resp == NULL) { debug_print(ctx, 1, "No response"); return -1; } soap = soap_build_envelope(ctx->xml, resp); if (soap == NULL) { debug_print(ctx, 1, "SOAP envelope building failed"); return -1; } str = xml_node_to_str(ctx->xml, soap); xml_node_free(ctx->xml, soap); if (str == NULL) { debug_print(ctx, 1, "Could not get node string"); return -1; } printf("%s", str); free(str); return 0; } static void usage(void) { printf("usage:\n" "hs20_spp_server -r [-f]\n"); } int main(int argc, char *argv[]) { struct hs20_svc ctx; int ret; os_memset(&ctx, 0, sizeof(ctx)); for (;;) { int c = getopt(argc, argv, "f:r:"); if (c < 0) break; switch (c) { case 'f': if (ctx.debug_log) break; ctx.debug_log = fopen(optarg, "a"); if (ctx.debug_log == NULL) { printf("Could not write to %s\n", optarg); return -1; } break; case 'r': ctx.root_dir = optarg; break; default: usage(); return -1; } } if (ctx.root_dir == NULL) { usage(); return -1; } ctx.xml = xml_node_init_ctx(&ctx, NULL); if (ctx.xml == NULL) return -1; if (hs20_spp_server_init(&ctx) < 0) { xml_node_deinit_ctx(ctx.xml); return -1; } ret = process(&ctx); debug_print(&ctx, 1, "process() --> %d", ret); xml_node_deinit_ctx(ctx.xml); hs20_spp_server_deinit(&ctx); if (ctx.debug_log) fclose(ctx.debug_log); return ret; }