4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methods used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
24 * Anytun is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with Anytun. If not, see <http://www.gnu.org/licenses/>.
32 * In addition, as a special exception, the copyright holders give
33 * permission to link the code of portions of this program with the
34 * OpenSSL library under certain conditions as described in each
35 * individual source file, and distribute linked combinations
37 * You must obey the GNU General Public License in all respects
38 * for all of the code used other than OpenSSL. If you modify
39 * file(s) with this exception, you may extend this exception to your
40 * version of the file(s), but you are not obligated to do so. If you
41 * do not wish to do so, delete this exception statement from your
42 * version. If you delete this exception statement from all source
43 * files in the program, then also delete it here.
52 #include "winService.h"
54 #include "../anytunError.h"
55 #include "../threadUtils.hpp"
57 void WinService::install()
59 SC_HANDLE schSCManager;
61 char szPath[MAX_PATH];
63 if(!GetModuleFileNameA(NULL, szPath, MAX_PATH)) {
64 AnytunError::throwErr() << "Error on GetModuleFileName: " << AnytunErrno(GetLastError());
67 schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
68 if(NULL == schSCManager) {
69 AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
72 schService = CreateServiceA(schSCManager, SVC_NAME, SVC_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
73 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);
74 if(schService == NULL) {
75 CloseServiceHandle(schSCManager);
76 AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
79 std::cout << "Service installed successfully" << std::endl;
81 CloseServiceHandle(schService);
82 CloseServiceHandle(schSCManager);
85 void WinService::uninstall()
87 SC_HANDLE schSCManager;
90 schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
91 if(NULL == schSCManager) {
92 AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
95 schService = OpenServiceA(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS);
96 if(schService == NULL) {
97 CloseServiceHandle(schSCManager);
98 AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
101 if(!DeleteService(schService)) {
102 CloseServiceHandle(schService);
103 CloseServiceHandle(schSCManager);
104 AnytunError::throwErr() << "Error on DeleteService: " << AnytunErrno(GetLastError());
107 std::cout << "Service uninstalled successfully" << std::endl;
109 CloseServiceHandle(schService);
110 CloseServiceHandle(schSCManager);
113 void WinService::start()
115 SERVICE_TABLE_ENTRY DispatchTable[] = {
116 {SVC_NAME, (LPSERVICE_MAIN_FUNCTION)WinService::main },
120 if(!StartServiceCtrlDispatcherA(DispatchTable)) {
121 AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError());
125 int real_main(int argc, char* argv[], WinService& service);
127 VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR* lpszArgv)
131 service.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);
132 if(!service.status_handle_) {
133 cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());
136 service.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
137 service.status_.dwServiceSpecificExitCode = 0;
138 service.reportStatus(SERVICE_START_PENDING, NO_ERROR);
140 real_main(dwArgc, lpszArgv, service);
142 service.reportStatus(SERVICE_STOPPED, NO_ERROR);
145 VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)
147 gSignalController.inject(dwCtrl);
150 int WinService::handleCtrlSignal(int sig, const std::string& msg)
153 case SERVICE_CONTROL_STOP: {
154 reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
155 cLog.msg(Log::PRIO_NOTICE) << "received service stop signal, exitting";
158 case SERVICE_CONTROL_INTERROGATE:
163 reportStatus(status_.dwCurrentState, NO_ERROR);
168 void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode)
170 static DWORD dwCheckPoint = 1;
172 status_.dwCurrentState = dwCurrentState;
173 status_.dwWin32ExitCode = dwWin32ExitCode;
174 status_.dwWaitHint = 0;
176 if((dwCurrentState == SERVICE_START_PENDING) ||
177 (dwCurrentState == SERVICE_STOP_PENDING)) {
178 status_.dwControlsAccepted = 0;
180 status_.dwControlsAccepted = SERVICE_ACCEPT_STOP;
183 if((dwCurrentState == SERVICE_RUNNING) ||
184 (dwCurrentState == SERVICE_STOPPED)) {
185 status_.dwCheckPoint = 0;
187 status_.dwCheckPoint = dwCheckPoint++;
190 SetServiceStatus(status_handle_, &status_);
193 void WinService::initPrivs(std::string const& username, std::string const& groupname)
198 void WinService::dropPrivs()
203 void WinService::chroot(std::string const& dir)
208 void WinService::daemonize()
213 bool WinService::isDaemonized()