Imported Upstream version 0.3.4
[anytun.git] / src / win32 / winService.cpp
index 8c17420..084fa85 100644 (file)
-/*\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-2009 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 as published by\r
- *  the Free Software Foundation, either version 3 of the License, or\r
- *  any later version.\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
-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
-int real_main(int argc, char* argv[], WinService& service);\r
-\r
-VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)\r
-{\r
-  WinService service;\r
-\r
-  service.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);\r
-  if(!service.status_handle_) { \r
-    cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());\r
-    return;\r
-  }\r
-  service.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; \r
-  service.status_.dwServiceSpecificExitCode = 0;    \r
-  service.reportStatus(SERVICE_START_PENDING, NO_ERROR);\r
-  \r
-  real_main(dwArgc, lpszArgv, service);\r
-  \r
-  service.reportStatus(SERVICE_STOPPED, NO_ERROR);\r
-}\r
-\r
-VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)\r
-{\r
-  gSignalController.inject(dwCtrl);\r
-}\r
-\r
-int WinService::handleCtrlSignal(int sig, const std::string& msg)\r
-{\r
-  switch(sig) {\r
-    case SERVICE_CONTROL_STOP: {\r
-      reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
-      cLog.msg(Log::PRIO_NOTICE) << "received service stop signal, exitting";\r
-      return 1;\r
-    }\r
-    case SERVICE_CONTROL_INTERROGATE: break;\r
-    default: break;\r
-  }\r
-  reportStatus(status_.dwCurrentState, NO_ERROR);\r
-\r
-  return 0;\r
-}\r
-\r
-void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode)\r
-{\r
-  static DWORD dwCheckPoint = 1;\r
-\r
-  status_.dwCurrentState = dwCurrentState;\r
-  status_.dwWin32ExitCode = dwWin32ExitCode;\r
-  status_.dwWaitHint = 0;\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
-void WinService::initPrivs(std::string const& username, std::string const& groupname)\r
-{\r
-// nothing here\r
-}\r
-\r
-void WinService::dropPrivs()\r
-{\r
-// nothing here\r
-}\r
-\r
-void WinService::chroot(std::string const& dir)\r
-{\r
-// nothing here\r
-}\r
-\r
-void WinService::daemonize()\r
-{\r
-// nothing here\r
-}\r
-\r
-bool WinService::isDaemonized()\r
-{\r
-  return true;\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 methodes 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-2009 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/>.
+ */
+
+#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