diff options
Diffstat (limited to 'src/win32')
-rw-r--r-- | src/win32/registryKey.cpp | 27 | ||||
-rw-r--r-- | src/win32/registryKey.h | 8 | ||||
-rw-r--r-- | src/win32/signalHandler.hpp | 5 | ||||
-rw-r--r-- | src/win32/signalServiceHandler.hpp | 2 | ||||
-rw-r--r-- | src/win32/sysExec.hpp | 322 | ||||
-rw-r--r-- | src/win32/tunDevice.cpp | 95 | ||||
-rw-r--r-- | src/win32/winService.cpp | 402 | ||||
-rw-r--r-- | src/win32/winService.h | 10 |
8 files changed, 450 insertions, 421 deletions
diff --git a/src/win32/registryKey.cpp b/src/win32/registryKey.cpp index a9a0959..4c6240c 100644 --- a/src/win32/registryKey.cpp +++ b/src/win32/registryKey.cpp @@ -11,7 +11,7 @@ * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, * Christian Pointner <satp@wirdorange.org> * * This file is part of Anytun. @@ -64,14 +64,16 @@ std::string RegistryKey::getName() const DWORD RegistryKey::open(HKEY hkey, std::string subKey, REGSAM samDesired) { - if(opened_) + if(opened_) { RegCloseKey(key_); + } opened_ = false; name_ = ""; LONG err = RegOpenKeyExA(hkey, subKey.c_str(), 0, samDesired, &key_); - if(err != ERROR_SUCCESS) + if(err != ERROR_SUCCESS) { return err; + } name_ = subKey; opened_ = true; @@ -80,28 +82,32 @@ DWORD RegistryKey::open(HKEY hkey, std::string subKey, REGSAM samDesired) void RegistryKey::close() { - if(opened_) + if(opened_) { RegCloseKey(key_); + } opened_ = false; } std::string RegistryKey::operator[](std::string const& name) const { - if(!opened_) + if(!opened_) { throw AnytunErrno(ERROR_INVALID_HANDLE); + } char value[STRING_VALUE_LENGTH]; DWORD len = sizeof(value); LONG err = RegQueryValueExA(key_, name.c_str(), NULL, NULL, (LPBYTE)value, &len); - if(err != ERROR_SUCCESS) + if(err != ERROR_SUCCESS) { throw AnytunErrno(err); + } if(value[len-1] != 0) { - if(len < sizeof(value)) + if(len < sizeof(value)) { value[len++] = 0; - else + } else { throw AnytunErrno(ERROR_INSUFFICIENT_BUFFER); - } + } + } return std::string(value); } @@ -110,8 +116,9 @@ DWORD RegistryKey::getSubKey(DWORD index, RegistryKey& subKey, REGSAM sam) const char subkeyname[NAME_LENGTH]; DWORD len = sizeof(subkeyname); DWORD err = RegEnumKeyExA(key_, index, subkeyname, &len, NULL, NULL, NULL, NULL); - if(err != ERROR_SUCCESS) + if(err != ERROR_SUCCESS) { return err; + } return subKey.open(key_, subkeyname, sam); } diff --git a/src/win32/registryKey.h b/src/win32/registryKey.h index 6aceba0..9e42e29 100644 --- a/src/win32/registryKey.h +++ b/src/win32/registryKey.h @@ -11,7 +11,7 @@ * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, * Christian Pointner <satp@wirdorange.org> * * This file is part of Anytun. @@ -37,9 +37,9 @@ class RegistryKey { -public: - #define NAME_LENGTH 256 - #define STRING_VALUE_LENGTH 256 +public: +#define NAME_LENGTH 256 +#define STRING_VALUE_LENGTH 256 RegistryKey(); RegistryKey(HKEY hkey, std::string subKey, REGSAM samDesired); diff --git a/src/win32/signalHandler.hpp b/src/win32/signalHandler.hpp index 23872a6..6bcea18 100644 --- a/src/win32/signalHandler.hpp +++ b/src/win32/signalHandler.hpp @@ -11,7 +11,7 @@ * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, * Christian Pointner <satp@wirdorange.org> * * This file is part of Anytun. @@ -73,8 +73,9 @@ bool handleSignal(DWORD ctrlType) void registerSignalHandler(SignalController& ctrl, DaemonService& /*service*/) { - if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)handleSignal, true)) + if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)handleSignal, true)) { AnytunError::throwErr() << "Error on SetConsoleCtrlhandler: " << AnytunErrno(GetLastError()); + } ctrl.handler[CTRL_C_EVENT] = boost::bind(CtrlCHandler, _1, _2); ctrl.handler[CTRL_BREAK_EVENT] = boost::bind(CtrlBreakHandler, _1, _2); diff --git a/src/win32/signalServiceHandler.hpp b/src/win32/signalServiceHandler.hpp index da16de5..c897aa2 100644 --- a/src/win32/signalServiceHandler.hpp +++ b/src/win32/signalServiceHandler.hpp @@ -11,7 +11,7 @@ * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, * Christian Pointner <satp@wirdorange.org> * * This file is part of Anytun. diff --git a/src/win32/sysExec.hpp b/src/win32/sysExec.hpp index ed5be01..3807a63 100644 --- a/src/win32/sysExec.hpp +++ b/src/win32/sysExec.hpp @@ -1,160 +1,162 @@ -/*
- * 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/>.
- */
-#pragma once
-#ifndef ANYTUN_sysexec_hpp_INCLUDED
-#define ANYTUN_sysexec_hpp_INCLUDED
-
-#include <algorithm>
-#include <iostream> // todo remove
-#include <windows.h>
-
-SysExec::~SysExec()
-{
- if(!closed_) {
- CloseHandle(process_info_.hProcess);
- CloseHandle(process_info_.hThread);
- }
-}
-
-STARTUPINFOA getStartupInfo() {
- STARTUPINFOA startup_info;
- startup_info.cb = sizeof(STARTUPINFOA);
- GetStartupInfoA(&startup_info);
-
- //startup_info.dwFlags = STARTF_USESTDHANDLES;
- //startup_info.hStdInput = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE;
- //startup_info.hStdOutput = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE;
- //startup_info.hStdError = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE;
- startup_info.dwFlags |= STARTF_USESHOWWINDOW;
- startup_info.wShowWindow = SW_HIDE;
-
- return startup_info;
-}
-
-char const * const BATCH_FILE_EXTS[] = { ".bat", ".cmd" };
-int const BATCH_FILE_EXTS_COUNT = sizeof(BATCH_FILE_EXTS) / sizeof(BATCH_FILE_EXTS[0]);
-
-bool endsWith(std::string const& string, std::string const& suffix) {
- return string.find(suffix, string.size() - suffix.size()) != std::string::npos;
-}
-
-void SysExec::doExec(StringVector args, StringList env)
-{
- std::vector<char> arguments;
-
- bool isBatchFile = false;
- for(int i = 0; i < BATCH_FILE_EXTS_COUNT; ++i) {
- if(endsWith(script_, BATCH_FILE_EXTS[i])) {
- isBatchFile = true;
- break;
- }
- }
-
- if(isBatchFile) {
- std::string const BATCH_INTERPRETER = "cmd /c \"";
- arguments.insert(arguments.end(), BATCH_INTERPRETER.begin(), BATCH_INTERPRETER.end());
- }
- arguments.push_back('\"');
- arguments.insert(arguments.end(), script_.begin(), script_.end());
- arguments.push_back('\"');
- arguments.push_back(' ');
-
- for(StringVector::const_iterator it = args.begin(); it != args.end(); ++it) {
- arguments.push_back('\"');
- arguments.insert(arguments.end(), it->begin(), it->end());
- arguments.push_back('\"');
- arguments.push_back(' ');
- }
-
- if(isBatchFile) {
- arguments.push_back('\"');
- }
- arguments.push_back(0);
-
- STARTUPINFOA startup_info = getStartupInfo();
-
- std::map<std::string, std::string> envDict;
- for(StringList::const_iterator it = env.begin(); it != env.begin(); ++it) {
- size_t delimiter_pos = it->find('=');
- envDict.insert(std::make_pair(it->substr(0, delimiter_pos), it->substr(delimiter_pos + 1)));
- }
- std::vector<char> env;
- for(std::map<std::string, std::string>::iterator it = envDict.begin(); it != envDict.end(); ++it) {
- env.insert(env.end(), it->first.begin(), it->first.end());
- env.push_back(0);
- }
- env.push_back(0);
-
- if(!CreateProcessA(NULL,
- &arguments[0],
- NULL,
- NULL,
- false,
- NULL,
- &env[0],
- NULL,
- &startup_info,
- &process_info_
- ))
- {
- cLog.msg(Log::PRIO_ERROR) << "executing script '" << script_ << "' CreateProcess() error: " << GetLastError();
- return;
- }
-}
-
-int SysExec::waitForScript()
-{
- DWORD result = WaitForSingleObject(process_info_.hProcess, INFINITE);
- assert(WAIT_OBJECT_0 == result); // WAIT_FAILED, WAIT_TIMEOUT ... ???
- bool success = GetExitCodeProcess(process_info_.hProcess, &return_code_) != 0;
- assert(true == success); // false -> HU?
-
- CloseHandle(process_info_.hProcess);
- CloseHandle(process_info_.hThread);
- closed_ = true;
-
- return static_cast<int>(return_code_);
-}
-
-void SysExec::waitAndDestroy(SysExec*& s)
-{
- if(!s)
- return;
-
- s->waitForScript();
- cLog.msg(Log::PRIO_NOTICE) << "script '" << s->script_ << "' returned " << s->return_code_;
-
- delete(s);
- s = NULL;
-}
-
-#endif // ANYTUN_sysexec_hpp_INCLUDED
+/* + * 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/>. + */ +#pragma once +#ifndef ANYTUN_sysexec_hpp_INCLUDED +#define ANYTUN_sysexec_hpp_INCLUDED + +#include <algorithm> +#include <iostream> // todo remove +#include <windows.h> + +SysExec::~SysExec() +{ + if(!closed_) { + CloseHandle(process_info_.hProcess); + CloseHandle(process_info_.hThread); + } +} + +STARTUPINFOA getStartupInfo() +{ + STARTUPINFOA startup_info; + startup_info.cb = sizeof(STARTUPINFOA); + GetStartupInfoA(&startup_info); + + //startup_info.dwFlags = STARTF_USESTDHANDLES; + //startup_info.hStdInput = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE; + //startup_info.hStdOutput = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE; + //startup_info.hStdError = CreateFile("NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0, 0, 0); // INVALID_HANDLE_VALUE; + startup_info.dwFlags |= STARTF_USESHOWWINDOW; + startup_info.wShowWindow = SW_HIDE; + + return startup_info; +} + +char const* const BATCH_FILE_EXTS[] = { ".bat", ".cmd" }; +int const BATCH_FILE_EXTS_COUNT = sizeof(BATCH_FILE_EXTS) / sizeof(BATCH_FILE_EXTS[0]); + +bool endsWith(std::string const& string, std::string const& suffix) +{ + return string.find(suffix, string.size() - suffix.size()) != std::string::npos; +} + +void SysExec::doExec(StringVector args, StringList env) +{ + std::vector<char> arguments; + + bool isBatchFile = false; + for(int i = 0; i < BATCH_FILE_EXTS_COUNT; ++i) { + if(endsWith(script_, BATCH_FILE_EXTS[i])) { + isBatchFile = true; + break; + } + } + + if(isBatchFile) { + std::string const BATCH_INTERPRETER = "cmd /c \""; + arguments.insert(arguments.end(), BATCH_INTERPRETER.begin(), BATCH_INTERPRETER.end()); + } + arguments.push_back('\"'); + arguments.insert(arguments.end(), script_.begin(), script_.end()); + arguments.push_back('\"'); + arguments.push_back(' '); + + for(StringVector::const_iterator it = args.begin(); it != args.end(); ++it) { + arguments.push_back('\"'); + arguments.insert(arguments.end(), it->begin(), it->end()); + arguments.push_back('\"'); + arguments.push_back(' '); + } + + if(isBatchFile) { + arguments.push_back('\"'); + } + arguments.push_back(0); + + STARTUPINFOA startup_info = getStartupInfo(); + + std::map<std::string, std::string> envDict; + for(StringList::const_iterator it = env.begin(); it != env.begin(); ++it) { + size_t delimiter_pos = it->find('='); + envDict.insert(std::make_pair(it->substr(0, delimiter_pos), it->substr(delimiter_pos + 1))); + } + std::vector<char> env; + for(std::map<std::string, std::string>::iterator it = envDict.begin(); it != envDict.end(); ++it) { + env.insert(env.end(), it->first.begin(), it->first.end()); + env.push_back(0); + } + env.push_back(0); + + if(!CreateProcessA(NULL, + &arguments[0], + NULL, + NULL, + false, + NULL, + &env[0], + NULL, + &startup_info, + &process_info_ + )) { + cLog.msg(Log::PRIO_ERROR) << "executing script '" << script_ << "' CreateProcess() error: " << GetLastError(); + return; + } +} + +int SysExec::waitForScript() +{ + DWORD result = WaitForSingleObject(process_info_.hProcess, INFINITE); + assert(WAIT_OBJECT_0 == result); // WAIT_FAILED, WAIT_TIMEOUT ... ??? + bool success = GetExitCodeProcess(process_info_.hProcess, &return_code_) != 0; + assert(true == success); // false -> HU? + + CloseHandle(process_info_.hProcess); + CloseHandle(process_info_.hThread); + closed_ = true; + + return static_cast<int>(return_code_); +} + +void SysExec::waitAndDestroy(SysExec*& s) +{ + if(!s) { + return; + } + + s->waitForScript(); + cLog.msg(Log::PRIO_NOTICE) << "script '" << s->script_ << "' returned " << s->return_code_; + + delete(s); + s = NULL; +} + +#endif // ANYTUN_sysexec_hpp_INCLUDED diff --git a/src/win32/tunDevice.cpp b/src/win32/tunDevice.cpp index 6e6c83d..810e094 100644 --- a/src/win32/tunDevice.cpp +++ b/src/win32/tunDevice.cpp @@ -11,7 +11,7 @@ * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, * Christian Pointner <satp@wirdorange.org> * * This file is part of Anytun. @@ -49,19 +49,22 @@ TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, u_int16_t ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400) { - if(conf_.type_ != TYPE_TUN && conf_.type_ != TYPE_TAP) + if(conf_.type_ != TYPE_TUN && conf_.type_ != TYPE_TAP) { AnytunError::throwErr() << "unable to recognize type of device (tun or tap)"; + } handle_ = INVALID_HANDLE_VALUE; - if(!getAdapter(dev_name)) + if(!getAdapter(dev_name)) { AnytunError::throwErr() << "can't find any suitable device"; + } if(handle_ == INVALID_HANDLE_VALUE) { std::stringstream tapname; - tapname << USERMODEDEVICEDIR << actual_node_ << TAPSUFFIX; + tapname << USERMODEDEVICEDIR << actual_node_ << TAPSUFFIX; handle_ = CreateFileA(tapname.str().c_str(), GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - if(handle_ == INVALID_HANDLE_VALUE) + if(handle_ == INVALID_HANDLE_VALUE) { AnytunError::throwErr() << "Unable to open device: " << actual_node_ << " (" << actual_name_ << "): " << AnytunErrno(GetLastError()); + } } DWORD err; @@ -90,15 +93,16 @@ TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifc } } - if(ifcfg_addr != "") + if(ifcfg_addr != "") { do_ifconfig(); + } int status = true; err = performIoControl(TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status)); if(err != ERROR_SUCCESS) { CloseHandle(handle_); AnytunError::throwErr() << "Unable to set device media status: " << AnytunErrno(err); - } + } roverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); woverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -108,45 +112,50 @@ bool TunDevice::getAdapter(std::string const& dev_name) { RegistryKey akey; DWORD err = akey.open(HKEY_LOCAL_MACHINE, ADAPTER_KEY, KEY_ENUMERATE_SUB_KEYS); - if(err != ERROR_SUCCESS) + if(err != ERROR_SUCCESS) { AnytunError::throwErr() << "Unable to open registry key (HKLM\\" << ADAPTER_KEY << "): " << AnytunErrno(err); - + } + bool found = false; for(int i=0; ; ++i) { RegistryKey ckey; DWORD err = akey.getSubKey(i, ckey, KEY_QUERY_VALUE); - if(err == ERROR_NO_MORE_ITEMS) + if(err == ERROR_NO_MORE_ITEMS) { break; - if(err != ERROR_SUCCESS) + } + if(err != ERROR_SUCCESS) { continue; + } try { - if(ckey["ComponentId"] != TAP_COMPONENT_ID) + if(ckey["ComponentId"] != TAP_COMPONENT_ID) { continue; + } actual_node_ = ckey["NetCfgInstanceId"]; RegistryKey nkey; std::stringstream keyname; keyname << NETWORK_CONNECTIONS_KEY << "\\" << actual_node_ << "\\Connection"; err = nkey.open(HKEY_LOCAL_MACHINE, keyname.str().c_str(), KEY_QUERY_VALUE);; - if(err != ERROR_SUCCESS) + if(err != ERROR_SUCCESS) { continue; - - actual_name_ = nkey["Name"]; - } catch(AnytunErrno&) { continue; } + } + + actual_name_ = nkey["Name"]; + } catch(AnytunErrno&) { continue; } if(dev_name != "") { if(dev_name == actual_name_) { found = true; break; } - } - else { + } else { std::stringstream tapname; tapname << USERMODEDEVICEDIR << actual_node_ << TAPSUFFIX; handle_ = CreateFileA(tapname.str().c_str(), GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - if(handle_ == INVALID_HANDLE_VALUE) + if(handle_ == INVALID_HANDLE_VALUE) { continue; + } found = true; break; } @@ -163,18 +172,19 @@ DWORD TunDevice::performIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inBu OVERLAPPED overlapped; overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); overlapped.Offset = 0; - overlapped.OffsetHigh = 0; - + overlapped.OffsetHigh = 0; + DWORD len; if(!DeviceIoControl(handle_, controlCode, inBuffer, inBufferSize, outBuffer, outBufferSize, &len, &overlapped)) { DWORD err = GetLastError(); if(err == ERROR_IO_PENDING) { WaitForSingleObject(overlapped.hEvent, INFINITE); - if(!GetOverlappedResult(handle_, &overlapped, &len, FALSE)) + if(!GetOverlappedResult(handle_, &overlapped, &len, FALSE)) { return GetLastError(); - } - else + } + } else { return GetLastError(); + } } return ERROR_SUCCESS; } @@ -182,27 +192,30 @@ DWORD TunDevice::performIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inBu TunDevice::~TunDevice() { - if(handle_ != INVALID_HANDLE_VALUE) + if(handle_ != INVALID_HANDLE_VALUE) { CloseHandle(handle_); - if(roverlapped_.hEvent != INVALID_HANDLE_VALUE) + } + if(roverlapped_.hEvent != INVALID_HANDLE_VALUE) { CloseHandle(roverlapped_.hEvent); - if(woverlapped_.hEvent != INVALID_HANDLE_VALUE) + } + if(woverlapped_.hEvent != INVALID_HANDLE_VALUE) { CloseHandle(woverlapped_.hEvent); + } } int TunDevice::fix_return(int ret, size_t pi_length) const { -// nothing to be done here - return 0; + // nothing to be done here + return 0; } int TunDevice::read(u_int8_t* buf, u_int32_t len) { DWORD lenout; roverlapped_.Offset = 0; - roverlapped_.OffsetHigh = 0; + roverlapped_.OffsetHigh = 0; ResetEvent(roverlapped_.hEvent); - + if(!ReadFile(handle_, buf, len, &lenout, &roverlapped_)) { DWORD err = GetLastError(); if(err == ERROR_IO_PENDING) { @@ -211,8 +224,7 @@ int TunDevice::read(u_int8_t* buf, u_int32_t len) cLog.msg(Log::PRIO_ERROR) << "Error while trying to get overlapped result: " << AnytunErrno(GetLastError()); return -1; } - } - else { + } else { cLog.msg(Log::PRIO_ERROR) << "Error while reading from device: " << AnytunErrno(GetLastError()); return -1; } @@ -224,10 +236,10 @@ int TunDevice::write(u_int8_t* buf, u_int32_t len) { DWORD lenout; woverlapped_.Offset = 0; - woverlapped_.OffsetHigh = 0; + woverlapped_.OffsetHigh = 0; ResetEvent(woverlapped_.hEvent); - if(!WriteFile(handle_, buf, len, &lenout, &woverlapped_)) { + if(!WriteFile(handle_, buf, len, &lenout, &woverlapped_)) { DWORD err = GetLastError(); if(err == ERROR_IO_PENDING) { WaitForSingleObject(woverlapped_.hEvent, INFINITE); @@ -235,18 +247,17 @@ int TunDevice::write(u_int8_t* buf, u_int32_t len) cLog.msg(Log::PRIO_ERROR) << "Error while trying to get overlapped result: " << AnytunErrno(GetLastError()); return -1; } - } - else { + } else { cLog.msg(Log::PRIO_ERROR) << "Error while writing to device: " << AnytunErrno(GetLastError()); return -1; } } - return lenout; + return lenout; } void TunDevice::init_post() { -// nothing to be done here + // nothing to be done here } void TunDevice::do_ifconfig() @@ -260,18 +271,18 @@ void TunDevice::do_ifconfig() if(err != ERROR_SUCCESS) { CloseHandle(handle_); AnytunError::throwErr() << "Unable to set device dhcp masq mode: " << AnytunErrno(err); - } + } u_long mtu; err = performIoControl(TAP_IOCTL_GET_MTU, &mtu, sizeof(mtu), &mtu, sizeof(mtu)); if(err != ERROR_SUCCESS) { CloseHandle(handle_); AnytunError::throwErr() << "Unable to get device mtu: " << AnytunErrno(err); - } + } conf_.mtu_ = static_cast<u_int16_t>(mtu); } void TunDevice::waitUntilReady() { -// nothing to be done here + // nothing to be done here } diff --git a/src/win32/winService.cpp b/src/win32/winService.cpp index 8c17420..084fa85 100644 --- a/src/win32/winService.cpp +++ b/src/win32/winService.cpp @@ -1,197 +1,205 @@ -/*
- * 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
+/* + * 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 diff --git a/src/win32/winService.h b/src/win32/winService.h index 9c95400..91853fe 100644 --- a/src/win32/winService.h +++ b/src/win32/winService.h @@ -11,7 +11,7 @@ * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, * Christian Pointner <satp@wirdorange.org> * * This file is part of Anytun. @@ -41,12 +41,12 @@ class WinService { public: - #define SVC_NAME "anytun" +#define SVC_NAME "anytun" static void install(); static void uninstall(); static void start(); - static VOID WINAPI main(DWORD dwArgc, LPTSTR *lpszArgv); + static VOID WINAPI main(DWORD dwArgc, LPTSTR* lpszArgv); static VOID WINAPI ctrlHandler(DWORD dwCtrl); void reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode); @@ -61,8 +61,8 @@ public: private: WinService() {}; ~WinService() {}; - WinService(const WinService &w); - void operator=(const WinService &w); + WinService(const WinService& w); + void operator=(const WinService& w); SERVICE_STATUS status_; SERVICE_STATUS_HANDLE status_handle_; |