hs20_spp_server.c 3.7 KB

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