1 #pragma once 2 3 #include <boost/asio.hpp> 4 #include <boost/function.hpp> 5 #include <boost/thread.hpp> 6 #include "server.hpp" 7 #include "session_store.hpp" 8 9 namespace http { 10 namespace server { 11 enum _eUserRights 12 { 13 URIGHTS_VIEWER=0, 14 URIGHTS_SWITCHER, 15 URIGHTS_ADMIN 16 }; 17 enum _eAuthenticationMethod 18 { 19 AUTH_LOGIN=0, 20 AUTH_BASIC, 21 }; 22 enum _eWebCompressionMode 23 { 24 WWW_USE_GZIP=0, 25 WWW_USE_STATIC_GZ_FILES, 26 WWW_FORCE_NO_GZIP_SUPPORT 27 }; 28 typedef struct _tWebUserPassword 29 { 30 unsigned long ID; 31 std::string Username; 32 std::string Password; 33 _eUserRights userrights; 34 int TotSensors; 35 int ActiveTabs; 36 } WebUserPassword; 37 38 typedef struct _tWebEmSession 39 { 40 std::string id; 41 std::string remote_host; 42 std::string auth_token; 43 std::string username; 44 int reply_status; 45 time_t timeout; 46 time_t expires; 47 int rights; 48 bool rememberme; 49 bool isnew; 50 bool forcelogin; 51 } WebEmSession; 52 53 typedef struct _tIPNetwork 54 { 55 uint32_t network; 56 uint32_t mask; 57 std::string hostname; 58 } IPNetwork; 59 60 // Parsed Authorization header 61 struct ah { 62 std::string method; 63 std::string user; 64 std::string response; 65 std::string uri; 66 std::string cnonce; 67 std::string qop; 68 std::string nc; 69 std::string nonce; 70 std::string ha1; 71 }; 72 73 /** 74 75 The link between the embedded web server and the application code 76 77 78 * Copyright (c) 2008 by James Bremner 79 * All rights reserved. 80 * 81 * Use license: Modified from standard BSD license. 82 * 83 * Redistribution and use in source and binary forms are permitted 84 * provided that the above copyright notice and this paragraph are 85 * duplicated in all such forms and that any documentation, advertising 86 * materials, Web server pages, and other materials related to such 87 * distribution and use acknowledge that the software was developed 88 * by James Bremner. The name "James Bremner" may not be used to 89 * endorse or promote products derived from this software without 90 * specific prior written permission. 91 * 92 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 93 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 94 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 95 96 97 98 */ 99 class cWebem; 100 typedef boost::function< void( std::string & content_part ) > webem_include_function; 101 typedef boost::function< void( std::wstring & content_part_w ) > webem_include_function_w; 102 typedef boost::function< void( WebEmSession & session, const request& req, std::string & redirecturi ) > webem_action_function; 103 typedef boost::function< void( WebEmSession & session, const request & req, reply & rep ) > webem_page_function; 104 105 106 /** 107 108 The webem request handler. 109 110 A specialization of the boost::asio request handler 111 112 Application code should not use this class. 113 114 */ 115 class cWebemRequestHandler : public request_handler 116 { 117 public: 118 /// Construct with a directory containing files to be served. cWebemRequestHandler(const std::string & doc_root,cWebem * webem)119 cWebemRequestHandler( const std::string& doc_root, cWebem* webem ) : 120 request_handler( doc_root, webem ) 121 {} 122 123 /// Handle a request and produce a reply. 124 virtual void handle_request(const request& req, reply& rep) override; 125 private: 126 char *strftime_t(const char *format, const time_t rawtime); 127 bool CompressWebOutput(const request& req, reply& rep); 128 /// Websocket methods 129 bool is_upgrade_request(WebEmSession & session, const request& req, reply& rep); 130 std::string compute_accept_header(const std::string &websocket_key); 131 bool CheckAuthentication(WebEmSession & session, const request& req, reply& rep); 132 void send_authorization_request(reply& rep); 133 void send_remove_cookie(reply& rep); 134 std::string generateSessionID(); 135 void send_cookie(reply& rep, const WebEmSession & session); 136 bool AreWeInLocalNetwork(const std::string &sHost, const request& req); 137 int authorize(WebEmSession & session, const request& req, reply& rep); 138 void Logout(); 139 int parse_auth_header(const request& req, struct ah *ah); 140 std::string generateAuthToken(const WebEmSession & session, const request & req); 141 bool checkAuthToken(WebEmSession & session); 142 void removeAuthToken(const std::string & sessionId); 143 }; 144 // forward declaration for friend declaration 145 class CProxyClient; 146 /** 147 148 The webem embedded web server. 149 150 */ 151 class cWebem 152 { 153 friend class CProxyClient; 154 public: 155 cWebem( 156 const server_settings & settings, 157 const std::string& doc_root); 158 ~cWebem(); 159 void Run(); 160 void Stop(); 161 162 void RegisterIncludeCode( 163 const char* idname, 164 webem_include_function fun ); 165 166 void RegisterIncludeCodeW( 167 const char* idname, 168 webem_include_function_w fun ); 169 170 void RegisterPageCode( 171 const char* pageurl, 172 webem_page_function fun, 173 bool bypassAuthentication = false 174 ); 175 void RegisterPageCodeW( 176 const char* pageurl, 177 webem_page_function fun, 178 bool bypassAuthentication = false 179 ); 180 181 bool Include( std::string& reply ); 182 183 void RegisterActionCode( 184 const char* idname, 185 webem_action_function fun ); 186 187 void RegisterWhitelistURLString(const char* idname); 188 void RegisterWhitelistCommandsString(const char* idname); 189 190 bool IsAction(const request& req); 191 bool CheckForAction(WebEmSession & session, request& req); 192 193 bool IsPageOverride(const request& req, reply& rep); 194 bool CheckForPageOverride(WebEmSession & session, request& req, reply& rep); 195 196 void SetAuthenticationMethod(const _eAuthenticationMethod amethod); 197 void SetWebTheme(const std::string &themename); 198 void SetWebRoot(const std::string &webRoot); 199 void AddUserPassword(const unsigned long ID, const std::string &username, const std::string &password, const _eUserRights userrights, const int activetabs); 200 std::string ExtractRequestPath(const std::string& original_request_path); 201 bool IsBadRequestPath(const std::string& original_request_path); 202 203 void ClearUserPasswords(); 204 std::vector<_tWebUserPassword> m_userpasswords; 205 void AddLocalNetworks(std::string network); 206 void ClearLocalNetworks(); 207 std::vector<_tIPNetwork> m_localnetworks; 208 void SetDigistRealm(const std::string &realm); 209 std::string m_DigistRealm; 210 void SetZipPassword(const std::string &password); 211 212 //IPs that are allowed to pass proxy headers 213 std::vector < std::string > myRemoteProxyIPs; 214 void AddRemoteProxyIPs(const std::string &ipaddr); 215 void ClearRemoteProxyIPs(); 216 217 // Session store manager 218 void SetSessionStore(session_store_impl_ptr sessionStore); 219 session_store_impl_ptr GetSessionStore(); 220 221 std::string m_zippassword; 222 const std::string GetPort(); 223 const std::string GetWebRoot(); 224 WebEmSession * GetSession(const std::string & ssid); 225 void AddSession(const WebEmSession & session); 226 void RemoveSession(const WebEmSession & session); 227 void RemoveSession(const std::string & ssid); 228 int CountSessions(); 229 _eAuthenticationMethod m_authmethod; 230 //Whitelist url strings that bypass authentication checks (not used by basic-auth authentication) 231 std::vector < std::string > myWhitelistURLs; 232 std::vector < std::string > myWhitelistCommands; 233 std::map<std::string, WebEmSession> m_sessions; 234 server_settings m_settings; 235 // actual theme selected 236 std::string m_actTheme; 237 238 void SetWebCompressionMode(const _eWebCompressionMode gzmode); 239 _eWebCompressionMode m_gzipmode; 240 private: 241 /// store map between include codes and application functions 242 std::map < std::string, webem_include_function > myIncludes; 243 /// store map between include codes and application functions returning UTF-16 strings 244 std::map < std::string, webem_include_function_w > myIncludes_w; 245 /// store map between action codes and application functions 246 std::map < std::string, webem_action_function > myActions; 247 /// store name walue pairs for form submit action 248 std::map < std::string, webem_page_function > myPages; 249 /// store map between pages and application functions 250 std::map < std::string, webem_page_function > myPages_w; 251 void CleanSessions(); 252 session_store_impl_ptr mySessionStore; /// session store 253 /// request handler specialized to handle webem requests 254 /// Rene: Beware: myRequestHandler should be declared BEFORE myServer 255 cWebemRequestHandler myRequestHandler; 256 /// boost::asio web server (RK: plain or secure) 257 std::shared_ptr<server_base> myServer; 258 // root of url for reverse proxy servers 259 std::string m_webRoot; 260 /// sessions management 261 std::mutex m_sessionsMutex; 262 boost::asio::io_service m_io_service; 263 boost::asio::deadline_timer m_session_clean_timer; 264 std::shared_ptr<std::thread> m_io_service_thread; 265 }; 266 267 } 268 } 269