Home | History | Annotate | Download | only in server
      1 /*
      2  * Hotspot 2.0 SPP server - standalone version
      3  * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 #include <time.h>
     11 #include <sqlite3.h>
     12 
     13 #include "common.h"
     14 #include "xml-utils.h"
     15 #include "spp_server.h"
     16 
     17 
     18 static void write_timestamp(FILE *f)
     19 {
     20 	time_t t;
     21 	struct tm *tm;
     22 
     23 	time(&t);
     24 	tm = localtime(&t);
     25 
     26 	fprintf(f, "%04u-%02u-%02u %02u:%02u:%02u ",
     27 		tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
     28 		tm->tm_hour, tm->tm_min, tm->tm_sec);
     29 }
     30 
     31 
     32 void debug_print(struct hs20_svc *ctx, int print, const char *fmt, ...)
     33 {
     34 	va_list ap;
     35 
     36 	if (ctx->debug_log == NULL)
     37 		return;
     38 
     39 	write_timestamp(ctx->debug_log);
     40 	va_start(ap, fmt);
     41 	vfprintf(ctx->debug_log, fmt, ap);
     42 	va_end(ap);
     43 
     44 	fprintf(ctx->debug_log, "\n");
     45 }
     46 
     47 
     48 void debug_dump_node(struct hs20_svc *ctx, const char *title, xml_node_t *node)
     49 {
     50 	char *str;
     51 
     52 	if (ctx->debug_log == NULL)
     53 		return;
     54 	str = xml_node_to_str(ctx->xml, node);
     55 	if (str == NULL)
     56 		return;
     57 
     58 	write_timestamp(ctx->debug_log);
     59 	fprintf(ctx->debug_log, "%s: '%s'\n", title, str);
     60 	os_free(str);
     61 }
     62 
     63 
     64 static int process(struct hs20_svc *ctx)
     65 {
     66 	int dmacc = 0;
     67 	xml_node_t *soap, *spp, *resp;
     68 	char *user, *realm, *post, *str;
     69 
     70 	ctx->addr = getenv("HS20ADDR");
     71 	if (ctx->addr)
     72 		debug_print(ctx, 1, "Connection from %s", ctx->addr);
     73 
     74 	user = getenv("HS20USER");
     75 	if (user && strlen(user) == 0)
     76 		user = NULL;
     77 	realm = getenv("HS20REALM");
     78 	if (realm == NULL) {
     79 		debug_print(ctx, 1, "HS20REALM not set");
     80 		return -1;
     81 	}
     82 	post = getenv("HS20POST");
     83 	if (post == NULL) {
     84 		debug_print(ctx, 1, "HS20POST not set");
     85 		return -1;
     86 	}
     87 
     88 	soap = xml_node_from_buf(ctx->xml, post);
     89 	if (soap == NULL) {
     90 		debug_print(ctx, 1, "Could not parse SOAP data");
     91 		return -1;
     92 	}
     93 	debug_dump_node(ctx, "Received SOAP message", soap);
     94 	spp = soap_get_body(ctx->xml, soap);
     95 	if (spp == NULL) {
     96 		debug_print(ctx, 1, "Could not get SPP message");
     97 		xml_node_free(ctx->xml, soap);
     98 		return -1;
     99 	}
    100 	debug_dump_node(ctx, "Received SPP message", spp);
    101 
    102 	resp = hs20_spp_server_process(ctx, spp, user, realm, dmacc);
    103 	xml_node_free(ctx->xml, soap);
    104 	if (resp == NULL && user == NULL) {
    105 		debug_print(ctx, 1, "Request HTTP authentication");
    106 		return 2; /* Request authentication */
    107 	}
    108 	if (resp == NULL) {
    109 		debug_print(ctx, 1, "No response");
    110 		return -1;
    111 	}
    112 
    113 	soap = soap_build_envelope(ctx->xml, resp);
    114 	if (soap == NULL) {
    115 		debug_print(ctx, 1, "SOAP envelope building failed");
    116 		return -1;
    117 	}
    118 	str = xml_node_to_str(ctx->xml, soap);
    119 	xml_node_free(ctx->xml, soap);
    120 	if (str == NULL) {
    121 		debug_print(ctx, 1, "Could not get node string");
    122 		return -1;
    123 	}
    124 	printf("%s", str);
    125 	free(str);
    126 
    127 	return 0;
    128 }
    129 
    130 
    131 static void usage(void)
    132 {
    133 	printf("usage:\n"
    134 	       "hs20_spp_server -r<root directory> [-f<debug log>]\n");
    135 }
    136 
    137 
    138 int main(int argc, char *argv[])
    139 {
    140 	struct hs20_svc ctx;
    141 	int ret;
    142 
    143 	os_memset(&ctx, 0, sizeof(ctx));
    144 	for (;;) {
    145 		int c = getopt(argc, argv, "f:r:");
    146 		if (c < 0)
    147 			break;
    148 		switch (c) {
    149 		case 'f':
    150 			if (ctx.debug_log)
    151 				break;
    152 			ctx.debug_log = fopen(optarg, "a");
    153 			if (ctx.debug_log == NULL) {
    154 				printf("Could not write to %s\n", optarg);
    155 				return -1;
    156 			}
    157 			break;
    158 		case 'r':
    159 			ctx.root_dir = optarg;
    160 			break;
    161 		default:
    162 			usage();
    163 			return -1;
    164 		}
    165 	}
    166 	if (ctx.root_dir == NULL) {
    167 		usage();
    168 		return -1;
    169 	}
    170 	ctx.xml = xml_node_init_ctx(&ctx, NULL);
    171 	if (ctx.xml == NULL)
    172 		return -1;
    173 	if (hs20_spp_server_init(&ctx) < 0) {
    174 		xml_node_deinit_ctx(ctx.xml);
    175 		return -1;
    176 	}
    177 
    178 	ret = process(&ctx);
    179 	debug_print(&ctx, 1, "process() --> %d", ret);
    180 
    181 	xml_node_deinit_ctx(ctx.xml);
    182 	hs20_spp_server_deinit(&ctx);
    183 	if (ctx.debug_log)
    184 		fclose(ctx.debug_log);
    185 
    186 	return ret;
    187 }
    188