bb_http.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:13k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * bb_http.c : bearerbox http adminstration commands
  3.  *
  4.  * NOTE: this is a special bearerbox module - it does call
  5.  *   functions from core module! (other modules are fully
  6.  *    encapsulated, and only called outside)
  7.  *
  8.  * Kalle Marjola <rpr@wapit.com> 2000 for project Kannel
  9.  */
  10. #include <errno.h>
  11. #include <signal.h>
  12. #include <unistd.h>
  13. #include "gwlib/gwlib.h"
  14. #include "bearerbox.h"
  15. /* passed from bearerbox core */
  16. extern volatile sig_atomic_t bb_status;
  17. /* our own thingies */
  18. static volatile sig_atomic_t httpadmin_running;
  19. static long ha_port;
  20. static Octstr *ha_password;
  21. static Octstr *ha_status_pw;
  22. static Octstr *ha_allow_ip;
  23. static Octstr *ha_deny_ip;
  24. /*---------------------------------------------------------
  25.  * static functions
  26.  */
  27. /*
  28.  * check if the password matches. Return NULL if
  29.  * it does (or is not required)
  30.  */
  31. static Octstr *httpd_check_authorization(List *cgivars, int status)
  32. {
  33.     Octstr *password;
  34.     static double sleep = 0.01;
  35.     password = http_cgi_variable(cgivars, "password");
  36.     if (status) {
  37. if (ha_status_pw == NULL)
  38.     return NULL;
  39. if (password == NULL)
  40.     goto denied;
  41. if (octstr_compare(password, ha_password)!=0
  42.     && octstr_compare(password, ha_status_pw)!=0)
  43.     goto denied;
  44.     }
  45.     else {
  46. if (password == NULL || octstr_compare(password, ha_password)!=0)
  47.     goto denied;
  48.     }
  49.     sleep = 0.0;
  50.     return NULL; /* allowed */
  51. denied:
  52.     gwthread_sleep(sleep);
  53.     sleep += 1.0; /* little protection against brute force
  54.  * password cracking */
  55.     return octstr_create("Denied");
  56. }
  57. /*
  58.  * check if we still have time to do things
  59.  */
  60. static Octstr *httpd_check_status(void)
  61. {
  62.     if (bb_status == BB_SHUTDOWN || bb_status == BB_DEAD)
  63. return octstr_create("Avalanche has already started, too late to "
  64.                "save the sheeps");
  65.     return NULL;
  66. }
  67.     
  68. static Octstr *httpd_status(List *cgivars, int status_type)
  69. {
  70.     Octstr *reply;
  71.     if ((reply = httpd_check_authorization(cgivars, 1))!= NULL) return reply;
  72.     return bb_print_status(status_type);
  73. }
  74. static Octstr *httpd_store_status(List *cgivars, int status_type)
  75. {
  76.     Octstr *reply;
  77.     if ((reply = httpd_check_authorization(cgivars, 1))!= NULL) return reply;
  78.     return store_status(status_type);
  79. }
  80. static Octstr *httpd_shutdown(List *cgivars)
  81. {
  82.     Octstr *reply;
  83.     if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
  84.     if (bb_status == BB_SHUTDOWN)
  85. bb_status = BB_DEAD;
  86.     else
  87. bb_shutdown();
  88.     return octstr_create("Bringing system down");
  89. }
  90. static Octstr *httpd_isolate(List *cgivars)
  91. {
  92.     Octstr *reply;
  93.     if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
  94.     if ((reply = httpd_check_status())!= NULL) return reply;
  95.     if (bb_isolate() == -1)
  96. return octstr_create("Already isolated");
  97.     else
  98. return octstr_create(GW_NAME " isolated from message providers");
  99. }
  100. static Octstr *httpd_suspend(List *cgivars)
  101. {
  102.     Octstr *reply;
  103.     if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
  104.     if ((reply = httpd_check_status())!= NULL) return reply;
  105.     if (bb_suspend() == -1)
  106. return octstr_create("Already suspended");
  107.     else
  108. return octstr_create(GW_NAME " suspended");
  109. }
  110. static Octstr *httpd_resume(List *cgivars)
  111. {
  112.     Octstr *reply;
  113.     if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
  114.     if ((reply = httpd_check_status())!= NULL) return reply;
  115.  
  116.     if (bb_resume() == -1)
  117. return octstr_create("Already running");
  118.     else
  119. return octstr_create("Running resumed");
  120. }
  121. static Octstr *httpd_flush_dlr(List *cgivars)
  122. {
  123.     Octstr *reply;
  124.     if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
  125.     if ((reply = httpd_check_status())!= NULL) return reply;
  126.     if (bb_flush_dlr() == -1)
  127. return octstr_create("Suspend " GW_NAME " before trying to flush DLR queue");
  128.     else
  129. return octstr_create("DLR queue flushed");
  130. }
  131. static Octstr *httpd_stop_smsc(List *cgivars)
  132. {
  133.     Octstr *reply;
  134.     Octstr *smsc;
  135.     if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
  136.     if ((reply = httpd_check_status())!= NULL) return reply;
  137.     /* check if the smsc id is given */
  138.     smsc = http_cgi_variable(cgivars, "smsc");
  139.     if (smsc) {
  140.         if (bb_stop_smsc(smsc) == -1)
  141.             return octstr_format("Could not shut down smsc-id `%s'", octstr_get_cstr(smsc));
  142.         else
  143.             return octstr_format("SMSC `%s' shut down", octstr_get_cstr(smsc));
  144.     } else
  145.         return octstr_create("SMSC id not given");
  146. }
  147. static Octstr *httpd_restart_smsc(List *cgivars)
  148. {
  149.     Octstr *reply;
  150.     Octstr *smsc;
  151.     if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
  152.     if ((reply = httpd_check_status())!= NULL) return reply;
  153.     /* check if the smsc id is given */
  154.     smsc = http_cgi_variable(cgivars, "smsc");
  155.     if (smsc) {
  156.         if (bb_restart_smsc(smsc) == -1)
  157.             return octstr_format("Could not re-start smsc-id `%s'", octstr_get_cstr(smsc));
  158.         else
  159.             return octstr_format("SMSC `%s' re-started", octstr_get_cstr(smsc));
  160.     } else
  161.         return octstr_create("SMSC id not given");
  162. }
  163. static void httpd_serve(HTTPClient *client, Octstr *url, List *headers, 
  164.                Octstr *body, List *cgivars)
  165. {
  166.     Octstr *reply, *final_reply;
  167.     char *content_type;
  168.     char *header, *footer;
  169.     int status_type;
  170.     /* Set default reply format according to client
  171.      * Accept: header */
  172.     
  173.     if (http_type_accepted(headers, "text/vnd.wap.wml")) {
  174. status_type = BBSTATUS_WML;
  175. content_type = "text/vnd.wap.wml";
  176.     }
  177.     else if (http_type_accepted(headers, "text/html")) {
  178. status_type = BBSTATUS_HTML;
  179. content_type = "text/html";
  180.     }
  181.     else if (http_type_accepted(headers, "text/xml")) {
  182. status_type = BBSTATUS_XML;
  183. content_type = "text/xml";
  184.     } else {
  185. status_type = BBSTATUS_TEXT;
  186. content_type = "text/plain";
  187.     }    
  188.     if (octstr_str_compare(url, "/cgi-bin/status")==0
  189. || octstr_str_compare(url, "/status")==0) {
  190. reply = httpd_status(cgivars, status_type);
  191.     } else if (octstr_str_compare(url, "/cgi-bin/status.html")==0
  192.        || octstr_str_compare(url, "/status.html")==0) {
  193. status_type = BBSTATUS_HTML;
  194. reply = httpd_status(cgivars, status_type);
  195.     } else if (octstr_str_compare(url, "/cgi-bin/status.wml")==0
  196.        || octstr_str_compare(url, "/status.wml")==0) {
  197. status_type = BBSTATUS_WML;
  198. reply = httpd_status(cgivars, status_type);
  199.     } else if (octstr_str_compare(url, "/cgi-bin/status.txt")==0
  200.        || octstr_str_compare(url, "/status.txt")==0) {
  201. status_type = BBSTATUS_TEXT;
  202. reply = httpd_status(cgivars, status_type);
  203.     } else if (octstr_str_compare(url, "/cgi-bin/status.xml")==0
  204.        || octstr_str_compare(url, "/status.xml")==0) {
  205. status_type = BBSTATUS_XML;
  206. reply = httpd_status(cgivars, status_type);
  207. /* content_type = "text/x-kannelstatus"; */
  208.     } else if (octstr_str_compare(url, "/store-status") == 0) {
  209.         status_type = BBSTATUS_TEXT;
  210.         reply = httpd_store_status(cgivars, status_type);
  211.     } else if (octstr_str_compare(url, "/store-status.html") == 0) {
  212.         status_type = BBSTATUS_HTML;
  213.         reply = httpd_store_status(cgivars, status_type);
  214.     } else if (octstr_str_compare(url, "/store-status.xml") == 0) {
  215.         status_type = BBSTATUS_XML;
  216.         reply = httpd_store_status(cgivars, status_type);
  217.     } else if (octstr_str_compare(url, "/cgi-bin/shutdown")==0
  218.        || octstr_str_compare(url, "/shutdown")==0) {
  219. reply = httpd_shutdown(cgivars);
  220.     } else if (octstr_str_compare(url, "/cgi-bin/suspend")==0
  221.        || octstr_str_compare(url, "/suspend")==0) {
  222. reply = httpd_suspend(cgivars);
  223.     } else if (octstr_str_compare(url, "/cgi-bin/isolate")==0
  224.        || octstr_str_compare(url, "/isolate")==0) {
  225. reply = httpd_isolate(cgivars);
  226.     } else if (octstr_str_compare(url, "/cgi-bin/resume")==0
  227.        || octstr_str_compare(url, "/resume")==0) {
  228. reply = httpd_resume(cgivars);
  229.     } else if (octstr_str_compare(url, "/cgi-bin/flush-dlr")==0
  230.        || octstr_str_compare(url, "/flush-dlr")==0) {
  231. reply = httpd_flush_dlr(cgivars);
  232.     } else if (octstr_str_compare(url, "/cgi-bin/stop-smsc")==0
  233.        || octstr_str_compare(url, "/stop-smsc")==0) {
  234. reply = httpd_stop_smsc(cgivars);
  235.     } else if (octstr_str_compare(url, "/cgi-bin/start-smsc")==0
  236.        || octstr_str_compare(url, "/start-smsc")==0) {
  237. reply = httpd_restart_smsc(cgivars);
  238.     /*
  239.      * reconfig? restart?
  240.      */
  241.     } else  {
  242. reply = octstr_format("Unknown command %S", url);
  243.     }
  244.     gw_assert(reply != NULL);
  245.     if (status_type == BBSTATUS_HTML) {
  246. header = "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">n"
  247.       "<html>n<title>" GW_NAME "</title>n<body>n<p>";
  248. footer = "</p>n</body></html>n";
  249. content_type = "text/html";
  250.     } else if (status_type == BBSTATUS_WML) {
  251. header = "<?xml version="1.0"?>n"
  252.             "<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "
  253.             ""http://www.wapforum.org/DTD/wml_1.1.xml">n"
  254.             "n<wml>n <card>n  <p>";
  255. footer = "  </p>n </card>n</wml>n";
  256. content_type = "text/vnd.wap.wml";
  257.     } else if (status_type == BBSTATUS_XML) {
  258. header = "<?xml version="1.0"?>n"
  259.             "<gateway>n";
  260.         footer = "</gateway>n";
  261.     } else {
  262. header = "";
  263. footer = "";
  264. content_type = "text/plain";
  265.     }
  266.     final_reply = octstr_create(header);
  267.     octstr_append(final_reply, reply);
  268.     octstr_append_cstr(final_reply, footer);
  269.     
  270.     /* debug("bb.http", 0, "Result: '%s'", octstr_get_cstr(final_reply));
  271.      */
  272.     http_destroy_headers(headers);
  273.     headers = list_create();
  274.     http_header_add(headers, "Content-Type", content_type);
  275.     http_send_reply(client, HTTP_OK, headers, final_reply);
  276.     octstr_destroy(url);
  277.     octstr_destroy(body);
  278.     octstr_destroy(reply);
  279.     octstr_destroy(final_reply);
  280.     http_destroy_headers(headers);
  281.     http_destroy_cgiargs(cgivars);
  282. }
  283. static void httpadmin_run(void *arg)
  284. {
  285.     HTTPClient *client;
  286.     Octstr *ip, *url, *body;
  287.     List *headers, *cgivars;
  288.     while(bb_status != BB_DEAD) {
  289. if (bb_status == BB_SHUTDOWN)
  290.     bb_shutdown();
  291.      client = http_accept_request(ha_port, &ip, &url, &headers, &body, 
  292.                     &cgivars);
  293. if (client == NULL)
  294.     break;
  295. if (is_allowed_ip(ha_allow_ip, ha_deny_ip, ip) == 0) {
  296.     info(0, "HTTP admin tried from denied host <%s>, disconnected",
  297.  octstr_get_cstr(ip));
  298.     http_close_client(client);
  299.     continue;
  300. }
  301.         httpd_serve(client, url, headers, body, cgivars);
  302. octstr_destroy(ip);
  303.     }
  304.     httpadmin_running = 0;
  305. }
  306. /*-------------------------------------------------------------
  307.  * public functions
  308.  *
  309.  */
  310. int httpadmin_start(Cfg *cfg)
  311. {
  312.     CfgGroup *grp;
  313.     int ssl = 0; 
  314. #ifdef HAVE_LIBSSL
  315.     Octstr *ssl_server_cert_file;
  316.     Octstr *ssl_server_key_file;
  317. #endif /* HAVE_LIBSSL */
  318.     
  319.     if (httpadmin_running) return -1;
  320.     grp = cfg_get_single_group(cfg, octstr_imm("core"));
  321.     if (cfg_get_integer(&ha_port, grp, octstr_imm("admin-port")) == -1)
  322. panic(0, "Missing admin-port variable, cannot start HTTP admin");
  323.     ha_password = cfg_get(grp, octstr_imm("admin-password"));
  324.     if (ha_password == NULL)
  325. panic(0, "You MUST set HTTP admin-password");
  326.     
  327.     ha_status_pw = cfg_get(grp, octstr_imm("status-password"));
  328.     ha_allow_ip = cfg_get(grp, octstr_imm("admin-allow-ip"));
  329.     ha_deny_ip = cfg_get(grp, octstr_imm("admin-deny-ip"));
  330. #ifdef HAVE_LIBSSL
  331.     cfg_get_bool(&ssl, grp, octstr_imm("admin-port-ssl"));
  332.     
  333.     /*
  334.      * check if SSL is desired for HTTP servers and then
  335.      * load SSL client and SSL server public certificates 
  336.      * and private keys
  337.      */    
  338.     ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file"));
  339.     ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file"));
  340.     if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
  341.         /* we are fine here, the following call is now in conn_config_ssl(),
  342.          * so there is no reason to do this twice.
  343.         use_global_server_certkey_file(ssl_server_cert_file, 
  344.             ssl_server_key_file);
  345.         */
  346.     } else if (ssl) {
  347.    panic(0, "You MUST specify cert and key files within core group for SSL-enabled HTTP servers!");
  348.     }
  349.     octstr_destroy(ssl_server_cert_file);
  350.     octstr_destroy(ssl_server_key_file);
  351. #endif /* HAVE_LIBSSL */
  352.     http_open_port(ha_port, ssl);
  353.     if (gwthread_create(httpadmin_run, NULL) == -1)
  354. panic(0, "Failed to start a new thread for HTTP admin");
  355.     httpadmin_running = 1;
  356.     return 0;
  357. }
  358. void httpadmin_stop(void)
  359. {
  360.     http_close_all_ports();
  361.     gwthread_join_every(httpadmin_run);
  362.     octstr_destroy(ha_password);
  363.     octstr_destroy(ha_status_pw);
  364.     octstr_destroy(ha_allow_ip);
  365.     octstr_destroy(ha_deny_ip);
  366.     ha_password = NULL;
  367.     ha_status_pw = NULL;
  368.     ha_allow_ip = NULL;
  369.     ha_deny_ip = NULL;
  370. }