-/*\r
- * anytun\r
- *\r
- * The secure anycast tunneling protocol (satp) defines a protocol used\r
- * for communication between any combination of unicast and anycast\r
- * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel\r
- * mode and allows tunneling of every ETHER TYPE protocol (e.g.\r
- * ethernet, ip, arp ...). satp directly includes cryptography and\r
- * message authentication based on the methodes used by SRTP. It is\r
- * intended to deliver a generic, scaleable and secure solution for\r
- * tunneling and relaying of packets of any protocol.\r
- *\r
- *\r
- * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, \r
- * Christian Pointner <satp@wirdorange.org>\r
- *\r
- * This file is part of Anytun.\r
- *\r
- * Anytun is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License version 3 as\r
- * published by the Free Software Foundation.\r
- *\r
- * Anytun is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with anytun. If not, see <http://www.gnu.org/licenses/>.\r
- */\r
-\r
-#ifdef WIN_SERVICE\r
-\r
-#include <iostream>\r
-\r
-#include <windows.h>\r
-\r
-#include "winService.h"\r
-#include "../log.h"\r
-#include "../anytunError.h"\r
-#include "../threadUtils.hpp"\r
-\r
-WinService* WinService::inst = NULL;\r
-Mutex WinService::instMutex;\r
-WinService& gWinService = WinService::instance();\r
-\r
-WinService& WinService::instance()\r
-{\r
- Lock lock(instMutex);\r
- static instanceCleaner c;\r
- if(!inst)\r
- inst = new WinService();\r
- \r
- return *inst;\r
-}\r
-\r
-WinService::~WinService()\r
-{\r
- if(started_)\r
- CloseHandle(stop_event_);\r
-}\r
-\r
-void WinService::install()\r
-{\r
- SC_HANDLE schSCManager;\r
- SC_HANDLE schService;\r
- char szPath[MAX_PATH];\r
-\r
- if(!GetModuleFileNameA(NULL, szPath, MAX_PATH))\r
- AnytunError::throwErr() << "Error on GetModuleFileName: " << AnytunErrno(GetLastError());\r
-\r
- schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
- if(NULL == schSCManager)\r
- AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());\r
-\r
- schService = CreateServiceA(schSCManager, SVC_NAME, SVC_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, \r
- SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);\r
- if(schService == NULL) {\r
- CloseServiceHandle(schSCManager);\r
- AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());\r
- }\r
-\r
- std::cout << "Service installed successfully" << std::endl; \r
-\r
- CloseServiceHandle(schService); \r
- CloseServiceHandle(schSCManager);\r
-}\r
-\r
-void WinService::uninstall()\r
-{\r
- SC_HANDLE schSCManager;\r
- SC_HANDLE schService;\r
-\r
- schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
- if(NULL == schSCManager)\r
- AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());\r
-\r
- schService = OpenServiceA(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS);\r
- if(schService == NULL) {\r
- CloseServiceHandle(schSCManager);\r
- AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());\r
- }\r
-\r
- if(!DeleteService(schService)) {\r
- CloseServiceHandle(schService); \r
- CloseServiceHandle(schSCManager);\r
- AnytunError::throwErr() << "Error on DeleteService: " << AnytunErrno(GetLastError());\r
- }\r
-\r
- std::cout << "Service uninstalled successfully" << std::endl; \r
-\r
- CloseServiceHandle(schService); \r
- CloseServiceHandle(schSCManager);\r
-}\r
-\r
-void WinService::start()\r
-{\r
- SERVICE_TABLE_ENTRY DispatchTable[] = {\r
- {SVC_NAME, (LPSERVICE_MAIN_FUNCTION)WinService::main },\r
- {NULL, NULL}\r
- };\r
-\r
- if(!StartServiceCtrlDispatcherA(DispatchTable))\r
- AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError());\r
-}\r
-\r
-void WinService::waitForStop()\r
-{\r
- if(!started_)\r
- AnytunError::throwErr() << "Service not started correctly";\r
- \r
- reportStatus(SERVICE_RUNNING, NO_ERROR);\r
- WaitForSingleObject(stop_event_, INFINITE);\r
- reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
- cLog.msg(Log::PRIO_NOTICE) << "WinService received stop signal, exitting";\r
-}\r
-\r
-void WinService::stop()\r
-{\r
- if(!started_)\r
- AnytunError::throwErr() << "Service not started correctly";\r
-\r
- reportStatus(SERVICE_STOPPED, NO_ERROR);\r
-}\r
-\r
-int real_main(int argc, char* argv[]);\r
-\r
-VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)\r
-{\r
- if(gWinService.started_) {\r
- cLog.msg(Log::PRIO_ERROR) << "Service is already running";\r
- return;\r
- }\r
-\r
- gWinService.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);\r
- if(!gWinService.status_handle_) { \r
- cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());\r
- return;\r
- }\r
- gWinService.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; \r
- gWinService.status_.dwServiceSpecificExitCode = 0; \r
- gWinService.reportStatus(SERVICE_START_PENDING, NO_ERROR);\r
- gWinService.started_ = true;\r
- \r
- gWinService.stop_event_ = CreateEvent(NULL, true, false, NULL);\r
- if(!gWinService.stop_event_) {\r
- cLog.msg(Log::PRIO_ERROR) << "WinService Error on CreateEvent: " << AnytunErrno(GetLastError());\r
- gWinService.reportStatus(SERVICE_STOPPED, -1);\r
- return;\r
- }\r
-\r
- real_main(dwArgc, lpszArgv);\r
-}\r
-\r
-VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)\r
-{\r
- switch(dwCtrl) {\r
- case SERVICE_CONTROL_STOP: {\r
- gWinService.reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
- SetEvent(gWinService.stop_event_);\r
- return;\r
- }\r
- case SERVICE_CONTROL_INTERROGATE: break;\r
- default: break;\r
- }\r
- gWinService.reportStatus(gWinService.status_.dwCurrentState, NO_ERROR);\r
-}\r
-\r
-void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)\r
-{\r
- static DWORD dwCheckPoint = 1;\r
-\r
- status_.dwCurrentState = dwCurrentState;\r
- status_.dwWin32ExitCode = dwWin32ExitCode;\r
- status_.dwWaitHint = dwWaitHint;\r
-\r
- if((dwCurrentState == SERVICE_START_PENDING) ||\r
- (dwCurrentState == SERVICE_STOP_PENDING))\r
- status_.dwControlsAccepted = 0;\r
- else \r
- status_.dwControlsAccepted = SERVICE_ACCEPT_STOP;\r
-\r
- if((dwCurrentState == SERVICE_RUNNING) ||\r
- (dwCurrentState == SERVICE_STOPPED))\r
- status_.dwCheckPoint = 0;\r
- else\r
- status_.dwCheckPoint = dwCheckPoint++;\r
-\r
- SetServiceStatus(status_handle_, &status_);\r
-}\r
-\r
-#endif\r
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methods used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
+ * Christian Pointner <satp@wirdorange.org>
+ *
+ * This file is part of Anytun.
+ *
+ * Anytun is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * Anytun is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Anytun. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifdef WIN_SERVICE
+
+#include <iostream>
+
+#include <windows.h>
+
+#include "winService.h"
+#include "../log.h"
+#include "../anytunError.h"
+#include "../threadUtils.hpp"
+
+void WinService::install()
+{
+ SC_HANDLE schSCManager;
+ SC_HANDLE schService;
+ char szPath[MAX_PATH];
+
+ if(!GetModuleFileNameA(NULL, szPath, MAX_PATH)) {
+ AnytunError::throwErr() << "Error on GetModuleFileName: " << AnytunErrno(GetLastError());
+ }
+
+ schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if(NULL == schSCManager) {
+ AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
+ }
+
+ schService = CreateServiceA(schSCManager, SVC_NAME, SVC_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
+ SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);
+ if(schService == NULL) {
+ CloseServiceHandle(schSCManager);
+ AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
+ }
+
+ std::cout << "Service installed successfully" << std::endl;
+
+ CloseServiceHandle(schService);
+ CloseServiceHandle(schSCManager);
+}
+
+void WinService::uninstall()
+{
+ SC_HANDLE schSCManager;
+ SC_HANDLE schService;
+
+ schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if(NULL == schSCManager) {
+ AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
+ }
+
+ schService = OpenServiceA(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS);
+ if(schService == NULL) {
+ CloseServiceHandle(schSCManager);
+ AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
+ }
+
+ if(!DeleteService(schService)) {
+ CloseServiceHandle(schService);
+ CloseServiceHandle(schSCManager);
+ AnytunError::throwErr() << "Error on DeleteService: " << AnytunErrno(GetLastError());
+ }
+
+ std::cout << "Service uninstalled successfully" << std::endl;
+
+ CloseServiceHandle(schService);
+ CloseServiceHandle(schSCManager);
+}
+
+void WinService::start()
+{
+ SERVICE_TABLE_ENTRY DispatchTable[] = {
+ {SVC_NAME, (LPSERVICE_MAIN_FUNCTION)WinService::main },
+ {NULL, NULL}
+ };
+
+ if(!StartServiceCtrlDispatcherA(DispatchTable)) {
+ AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError());
+ }
+}
+
+int real_main(int argc, char* argv[], WinService& service);
+
+VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR* lpszArgv)
+{
+ WinService service;
+
+ service.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);
+ if(!service.status_handle_) {
+ cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());
+ return;
+ }
+ service.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ service.status_.dwServiceSpecificExitCode = 0;
+ service.reportStatus(SERVICE_START_PENDING, NO_ERROR);
+
+ real_main(dwArgc, lpszArgv, service);
+
+ service.reportStatus(SERVICE_STOPPED, NO_ERROR);
+}
+
+VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)
+{
+ gSignalController.inject(dwCtrl);
+}
+
+int WinService::handleCtrlSignal(int sig, const std::string& msg)
+{
+ switch(sig) {
+ case SERVICE_CONTROL_STOP: {
+ reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
+ cLog.msg(Log::PRIO_NOTICE) << "received service stop signal, exitting";
+ return 1;
+ }
+ case SERVICE_CONTROL_INTERROGATE:
+ break;
+ default:
+ break;
+ }
+ reportStatus(status_.dwCurrentState, NO_ERROR);
+
+ return 0;
+}
+
+void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode)
+{
+ static DWORD dwCheckPoint = 1;
+
+ status_.dwCurrentState = dwCurrentState;
+ status_.dwWin32ExitCode = dwWin32ExitCode;
+ status_.dwWaitHint = 0;
+
+ if((dwCurrentState == SERVICE_START_PENDING) ||
+ (dwCurrentState == SERVICE_STOP_PENDING)) {
+ status_.dwControlsAccepted = 0;
+ } else {
+ status_.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ }
+
+ if((dwCurrentState == SERVICE_RUNNING) ||
+ (dwCurrentState == SERVICE_STOPPED)) {
+ status_.dwCheckPoint = 0;
+ } else {
+ status_.dwCheckPoint = dwCheckPoint++;
+ }
+
+ SetServiceStatus(status_handle_, &status_);
+}
+
+void WinService::initPrivs(std::string const& username, std::string const& groupname)
+{
+ // nothing here
+}
+
+void WinService::dropPrivs()
+{
+ // nothing here
+}
+
+void WinService::chroot(std::string const& dir)
+{
+ // nothing here
+}
+
+void WinService::daemonize()
+{
+ // nothing here
+}
+
+bool WinService::isDaemonized()
+{
+ return true;
+}
+
+#endif