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 methodes 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-2009 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/>.
39 #include "winService.h"
41 #include "../anytunError.h"
42 #include "../threadUtils.hpp"
44 void WinService::install()
46 SC_HANDLE schSCManager;
48 char szPath[MAX_PATH];
50 if(!GetModuleFileNameA(NULL, szPath, MAX_PATH)) {
51 AnytunError::throwErr() << "Error on GetModuleFileName: " << AnytunErrno(GetLastError());
54 schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
55 if(NULL == schSCManager) {
56 AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
59 schService = CreateServiceA(schSCManager, SVC_NAME, SVC_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
60 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);
61 if(schService == NULL) {
62 CloseServiceHandle(schSCManager);
63 AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
66 std::cout << "Service installed successfully" << std::endl;
68 CloseServiceHandle(schService);
69 CloseServiceHandle(schSCManager);
72 void WinService::uninstall()
74 SC_HANDLE schSCManager;
77 schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
78 if(NULL == schSCManager) {
79 AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
82 schService = OpenServiceA(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS);
83 if(schService == NULL) {
84 CloseServiceHandle(schSCManager);
85 AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
88 if(!DeleteService(schService)) {
89 CloseServiceHandle(schService);
90 CloseServiceHandle(schSCManager);
91 AnytunError::throwErr() << "Error on DeleteService: " << AnytunErrno(GetLastError());
94 std::cout << "Service uninstalled successfully" << std::endl;
96 CloseServiceHandle(schService);
97 CloseServiceHandle(schSCManager);
100 void WinService::start()
102 SERVICE_TABLE_ENTRY DispatchTable[] = {
103 {SVC_NAME, (LPSERVICE_MAIN_FUNCTION)WinService::main },
107 if(!StartServiceCtrlDispatcherA(DispatchTable)) {
108 AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError());
112 int real_main(int argc, char* argv[], WinService& service);
114 VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR* lpszArgv)
118 service.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);
119 if(!service.status_handle_) {
120 cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());
123 service.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
124 service.status_.dwServiceSpecificExitCode = 0;
125 service.reportStatus(SERVICE_START_PENDING, NO_ERROR);
127 real_main(dwArgc, lpszArgv, service);
129 service.reportStatus(SERVICE_STOPPED, NO_ERROR);
132 VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)
134 gSignalController.inject(dwCtrl);
137 int WinService::handleCtrlSignal(int sig, const std::string& msg)
140 case SERVICE_CONTROL_STOP: {
141 reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
142 cLog.msg(Log::PRIO_NOTICE) << "received service stop signal, exitting";
145 case SERVICE_CONTROL_INTERROGATE:
150 reportStatus(status_.dwCurrentState, NO_ERROR);
155 void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode)
157 static DWORD dwCheckPoint = 1;
159 status_.dwCurrentState = dwCurrentState;
160 status_.dwWin32ExitCode = dwWin32ExitCode;
161 status_.dwWaitHint = 0;
163 if((dwCurrentState == SERVICE_START_PENDING) ||
164 (dwCurrentState == SERVICE_STOP_PENDING)) {
165 status_.dwControlsAccepted = 0;
167 status_.dwControlsAccepted = SERVICE_ACCEPT_STOP;
170 if((dwCurrentState == SERVICE_RUNNING) ||
171 (dwCurrentState == SERVICE_STOPPED)) {
172 status_.dwCheckPoint = 0;
174 status_.dwCheckPoint = dwCheckPoint++;
177 SetServiceStatus(status_handle_, &status_);
180 void WinService::initPrivs(std::string const& username, std::string const& groupname)
185 void WinService::dropPrivs()
190 void WinService::chroot(std::string const& dir)
195 void WinService::daemonize()
200 bool WinService::isDaemonized()