From 26603c51665e6b5d9121fabf98d7ae16c3a15519 Mon Sep 17 00:00:00 2001
From: ramonn <noreply@pandorafms.org>
Date: Thu, 11 Dec 2008 10:20:07 +0000
Subject: [PATCH] 2008-12-11  Ramon Novoa  <rnovoa@artica.es>

	* win32/windows/pandora_wmi.cc,
          win32/pandora_windows_service.h,
          win32/PandoraAgent.dev,
          win32/pandora_windows_service.cc: Added an UDP Server. The
          agent can receive remote commands.

        * win32/udp_server,
          win32/udp_server/udp_server.cc,
          win32/udp_server/udp_server.h: Added to repository. UDP Server.




git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1287 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
---
 pandora_agents/ChangeLog                      |  17 ++
 pandora_agents/win32/PandoraAgent.dev         |  24 +-
 .../win32/pandora_windows_service.cc          | 104 ++++----
 .../win32/pandora_windows_service.h           |  21 +-
 pandora_agents/win32/udp_server/udp_server.cc | 241 ++++++++++++++++++
 pandora_agents/win32/udp_server/udp_server.h  |  38 +++
 pandora_agents/win32/windows/pandora_wmi.cc   | 240 ++++++++---------
 7 files changed, 510 insertions(+), 175 deletions(-)
 create mode 100644 pandora_agents/win32/udp_server/udp_server.cc
 create mode 100644 pandora_agents/win32/udp_server/udp_server.h

diff --git a/pandora_agents/ChangeLog b/pandora_agents/ChangeLog
index 5ed6e4b9a6..2c4e005252 100644
--- a/pandora_agents/ChangeLog
+++ b/pandora_agents/ChangeLog
@@ -1,3 +1,20 @@
+2008-12-11  Ramon Novoa  <rnovoa@artica.es>
+
+	* win32/windows/pandora_wmi.cc,
+	  win32/pandora_windows_service.h,
+	  win32/PandoraAgent.dev,
+	  win32/pandora_windows_service.cc: Added an UDP Server. The
+	  agent can receive remote commands.
+
+	* win32/udp_server,
+	  win32/udp_server/udp_server.cc,
+	  win32/udp_server/udp_server.h: Added to repository. UDP Server.
+
+2008-12-10  Ramon Novoa  <rnovoa@artica.es>
+
+	*  linux/pandora_agent,
+	   linux/pandora_agent.conf: Added support for a secondary server.
+
 2008-11-25  Sancho Lerena <slerena@gmail.com>
 
 	* linux/pandora_agent: Fixed problem parsing async_string.
diff --git a/pandora_agents/win32/PandoraAgent.dev b/pandora_agents/win32/PandoraAgent.dev
index 79a8691ab3..ab25fcd120 100644
--- a/pandora_agents/win32/PandoraAgent.dev
+++ b/pandora_agents/win32/PandoraAgent.dev
@@ -1,7 +1,7 @@
 [Project]
 FileName=PandoraAgent.dev
 Name=PandoraAgent
-UnitCount=77
+UnitCount=79
 Type=1
 Ver=1
 ObjFiles=
@@ -20,7 +20,7 @@ ObjectOutput=
 OverrideOutput=0
 OverrideOutputName=PandoraAgent.exe
 HostApplication=
-Folders=FTP,Misc,Modules,Modules/Utils,SSH,SSH/libssh2,Windows,Windows/WMI,XML
+Folders=FTP,Misc,Modules,Modules/Utils,SSH,SSH/libssh2,"UDP Server",Windows,Windows/WMI,XML
 CommandLine=
 UseCustomMakefile=0
 CustomMakefile=
@@ -817,3 +817,23 @@ Priority=1000
 OverrideBuildCmd=0
 BuildCmd=
 
+[Unit78]
+FileName=udp_server\udp_server.h
+CompileCpp=1
+Folder=UDP Server
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit79]
+FileName=udp_server\udp_server.cc
+CompileCpp=1
+Folder=UDP Server
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
diff --git a/pandora_agents/win32/pandora_windows_service.cc b/pandora_agents/win32/pandora_windows_service.cc
index 8886043044..5048d98b6e 100644
--- a/pandora_agents/win32/pandora_windows_service.cc
+++ b/pandora_agents/win32/pandora_windows_service.cc
@@ -27,6 +27,7 @@
 #include "ftp/pandora_ftp_client.h"
 #include "misc/pandora_file.h"
 #include "windows/pandora_windows_info.h"
+#include "udp_server/udp_server.h"
 
 #include <iostream>
 #include <cstdlib>
@@ -37,15 +38,15 @@ using namespace std;
 using namespace Pandora;
 using namespace Pandora_Modules;
 using namespace Pandora_Strutils;
-
+
 Pandora_Windows_Service::Pandora_Windows_Service ()
-  : Windows_Service (NULL, NULL, NULL) {
+  : Windows_Service (NULL, NULL, NULL) {
 	this->setInitFunction ((void (Windows_Service::*) ())
 			       &Pandora_Windows_Service::pandora_init);
 	this->setRunFunction ((void (Windows_Service::*) ())
-			      &Pandora_Windows_Service::pandora_run);
-	this->started = false;
-}
+			      &Pandora_Windows_Service::pandora_run);
+	this->started = false;
+}
 
 /** 
  * Set Pandora service Windows properties.
@@ -54,7 +55,7 @@ Pandora_Windows_Service::Pandora_Windows_Service ()
  * @param svc_display_name Service name that will appear in the
  *        Windows service administration tool.
  * @param svc_description Long description of the service.
- */
+ */
 void
 Pandora_Windows_Service::setValues (const char * svc_name,
 				    const char * svc_display_name,
@@ -83,28 +84,30 @@ Pandora_Windows_Service::~Pandora_Windows_Service () {
 	}
 	pandoraLog ("Pandora agent stopped");
 }
-
-Pandora_Windows_Service *
-Pandora_Windows_Service::getInstance () {
-	static Pandora_Windows_Service *service = NULL;
-	
-	if (service != NULL)
-		return service;
-	
-	service = new Pandora_Windows_Service ();
-	
-	return service;
-}
-
-void
-Pandora_Windows_Service::start () {
-	this->started = true;
+
+Pandora_Windows_Service *
+Pandora_Windows_Service::getInstance () {
+	static Pandora_Windows_Service *service = NULL;
+	
+	if (service != NULL)
+		return service;
+	
+	service = new Pandora_Windows_Service ();
+	
+	return service;
+}
+
+void
+Pandora_Windows_Service::start () {
+	this->started = true;
 }
 
 void
 Pandora_Windows_Service::pandora_init () {
 	string conf_file, interval, debug, transfer_interval;
-	
+	string udp_server_enabled, udp_server_port, udp_server_addr, udp_server_auth_addr;
+	static UDP_Server *udp_server = NULL;
+
 	setPandoraDebug (true);
 	
 	conf_file = Pandora::getPandoraInstallDir ();
@@ -144,6 +147,16 @@ Pandora_Windows_Service::pandora_init () {
 	this->setSleepTime (this->interval);
 	
 	pandoraLog ("Pandora agent started");
+	
+	/* Launch UDP Server */
+	udp_server_enabled = conf->getValue ("udp_server");
+	if (udp_server == NULL && udp_server_enabled.compare ("1") == 0) {
+		udp_server_port = conf->getValue ("udp_server_port");
+		udp_server_addr = conf->getValue ("udp_server_address");
+		udp_server_auth_addr = conf->getValue ("udp_server_auth_address");
+		udp_server = new UDP_Server (this, udp_server_addr, udp_server_auth_addr, atoi (udp_server_port.c_str ()));
+		udp_server->start ();
+	}
 }
 
 TiXmlElement *
@@ -607,7 +620,7 @@ Pandora_Windows_Service::checkConfig () {
 	/* Reload configuration */
 	this->pandora_init ();
 }
-
+
 void
 Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
 	TiXmlDeclaration *decl;
@@ -616,16 +629,16 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
 	string            xml_filename, random_integer;
 	string            tmp_filename, tmp_filepath;
 	string            encoding;
-	bool              saved;
-	static HANDLE     mutex = 0; 
-	
-	if (mutex == 0) {
-		mutex = CreateMutex (NULL, FALSE, NULL);
-	}
-	
-	/* Wait for the mutex to be opened */
-	WaitForSingleObject (mutex, INFINITE);
-	
+	bool              saved;
+	static HANDLE     mutex = 0; 
+	
+	if (mutex == 0) {
+		mutex = CreateMutex (NULL, FALSE, NULL);
+	}
+	
+	/* Wait for the mutex to be opened */
+	WaitForSingleObject (mutex, INFINITE);
+	
 	agent = getXmlHeader ();
 	
 	if (modules != NULL) {
@@ -644,7 +657,7 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
 			}
 			modules->goNext ();
 		}
-	}
+	}
 	
 	/* Generate temporal filename */
 	random_integer = inttostr (rand());
@@ -677,7 +690,7 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
 
 	if (!saved) {
 		pandoraLog ("Error when saving the XML in %s",
-			    tmp_filepath.c_str ());
+			    tmp_filepath.c_str ());
 		ReleaseMutex (mutex);
 		return;
 	}
@@ -690,10 +703,10 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
 			Pandora_File::removeFile (tmp_filepath);
 		} catch (Pandora_File::Delete_Error e) {
 		}
-	}
-	
-	ReleaseMutex (mutex);
-}
+	}
+	
+	ReleaseMutex (mutex);
+}
 
 void
 Pandora_Windows_Service::pandora_run () {
@@ -720,10 +733,10 @@ Pandora_Windows_Service::pandora_run () {
 	}
 
 	this->elapsed_transfer_time += this->interval;
-	
+	
 	if (this->elapsed_transfer_time >= this->transfer_interval) {
-		this->elapsed_transfer_time = 0;
-		
+		this->elapsed_transfer_time = 0;
+		
 		this->sendXml (this->modules);
 	}
 	
@@ -732,3 +745,8 @@ Pandora_Windows_Service::pandora_run () {
 
 	return;
 }
+
+Pandora_Agent_Conf  *
+Pandora_Windows_Service::getConf () {
+	return this->conf;
+}
diff --git a/pandora_agents/win32/pandora_windows_service.h b/pandora_agents/win32/pandora_windows_service.h
index 3e6d29f3bf..10c7791350 100644
--- a/pandora_agents/win32/pandora_windows_service.h
+++ b/pandora_agents/win32/pandora_windows_service.h
@@ -43,7 +43,7 @@ namespace Pandora {
 		string               agent_name;
 		long                 interval;
 		long                 elapsed_transfer_time;
-		long                 transfer_interval;
+		long                 transfer_interval;
 		bool                 started;
 		
 		TiXmlElement  *getXmlHeader    ();
@@ -59,23 +59,24 @@ namespace Pandora {
 		void           recvDataFile (string filename);
 		void           recvTentacleDataFile (string host,
 						     string filename);
-		void           checkConfig ();
-		
+		void           checkConfig ();
+		
 		Pandora_Windows_Service     ();
 	public:
 		void           pandora_run  ();
 		void           pandora_init ();
-	public:
-		static Pandora_Windows_Service *getInstance ();
+	public:
+		static Pandora_Windows_Service *getInstance ();
+		
+		~Pandora_Windows_Service    ();
 		
-		~Pandora_Windows_Service    ();
-		
 		void           setValues    (const char *svc_name,
 					     const char *svc_display_name,
-					     const char *svc_description);
-		
-		void           start        ();
+					     const char *svc_description);
+		
+		void           start        ();
 		void           sendXml      (Pandora_Module_List *modules);
+		Pandora_Agent_Conf  *getConf ();
 	};
 }
 
diff --git a/pandora_agents/win32/udp_server/udp_server.cc b/pandora_agents/win32/udp_server/udp_server.cc
new file mode 100644
index 0000000000..26553a410b
--- /dev/null
+++ b/pandora_agents/win32/udp_server/udp_server.cc
@@ -0,0 +1,241 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <WinSock2.h>
+
+#include "udp_server.h"
+#include "../pandora.h"
+#include "../windows/pandora_wmi.h"
+
+using namespace Pandora;
+
+/** 
+ * Get the address of the server.
+ * 
+ * @return Server address.
+ */
+unsigned long UDP_Server::getAddress () {
+    return this->address;
+}
+
+/** 
+ * Get the address authorized to send commands to
+ * the server.
+ * 
+ * @return Authorized address.
+ */
+unsigned long UDP_Server::getAuthAddress () {
+    return this->auth_address;
+}
+
+/** 
+ * Get the port of the server.
+ * 
+ * @return Server port.
+ */
+unsigned long UDP_Server::getPort () {
+    return this->port;
+}
+
+/** 
+ * Get the windows service associated to the server.
+ * 
+ * @return Windows service associated to the server.
+ */
+Pandora_Windows_Service *UDP_Server::getService () {
+    return this->service;
+}
+
+/** 
+ * Returns the state of the server.
+ * 
+ * @return 1 if the server is running, 0 if not.
+ */
+unsigned char UDP_Server::isRunning () {
+    return this->running;
+}
+
+/** 
+ * UDP_Server constructor.
+ * 
+ * @param service Service associated to the server.
+ * @param address Server address.
+ * @param auth_address Authorized address.
+ * @param port Server port.
+ */
+UDP_Server::UDP_Server (Pandora_Windows_Service *service, string address, string auth_address, unsigned int port) {
+	if (address.empty ()) {
+	   this->address = INADDR_ANY;
+	} else {
+        this->address = inet_addr (address.c_str ());
+    }
+    if (auth_address.empty ()) {
+        this->auth_address = INADDR_ANY;
+    } else {
+	   this->auth_address = inet_addr (auth_address.c_str ());
+	}
+	this->port = port;
+	this->running = 0;
+	this->service = service;
+}
+
+/** 
+ * Starts the server.
+ * 
+ * @return 1 on error, 0 otherwise.
+ */
+int UDP_Server::start () {
+	if (this->running != 0) {
+		return 1;
+	}
+	
+	/* Run in a new thread */
+	this->running = 1;
+	if (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) listen, this, 0, NULL) == NULL) {
+        this->running = 0;
+		pandoraLog ("UDP Server: Error starting UDP Server thread");
+		return 1;
+	}
+
+	pandoraLog ("UDP Server: UDP Server started on port %d", this->port);
+	return 0;
+}
+
+/** 
+ * Stops the server.
+ * 
+ * @return 1 on error, 0 otherwise.
+ */
+int UDP_Server::stop () {
+	if (this->running != 0) {
+		return 1;
+	}
+	
+	this->running = 0;
+	pandoraLog ("UDP Server: UDP Server going down");
+	return 0;
+}
+
+/** 
+ * Listens for incoming packets.
+ * 
+ * @param server UDP Server.
+ */
+void Pandora::listen (UDP_Server *server) {
+    int sockfd,n;
+    struct sockaddr_in servaddr, cliaddr;
+    int len, err;
+    char mesg[MAX_PACKET_SIZE];  
+    unsigned long auth_addr;
+    WSADATA wsa;
+
+    err = WSAStartup (MAKEWORD (2,0), &wsa);
+    if (err != 0) {
+        /* Could not find a usable Winsock DLL */
+        printf("UDP Server: WSAStartup failed with error: %d\n", err);
+        return;
+    }
+
+    sockfd = socket (AF_INET, SOCK_DGRAM, 0);
+
+    memset (&servaddr, 0, sizeof(servaddr));
+    servaddr.sin_family = AF_INET;
+    servaddr.sin_addr.s_addr = htonl (server->getAddress ());
+    servaddr.sin_port = htons (server->getPort ());
+    bind(sockfd, (struct sockaddr *)&servaddr, sizeof (servaddr));
+
+    /* Get authorised address */
+    auth_addr = server->getAuthAddress ();
+
+	while (server->isRunning () == 1) {
+		len = sizeof(cliaddr);
+		n = recvfrom(sockfd, mesg, MAX_PACKET_SIZE, 0, (struct sockaddr *)&cliaddr, &len);
+		if (n == SOCKET_ERROR) {
+            pandoraLog ("UDP Server: Error %d", WSAGetLastError ());
+            break;
+        }
+
+		/* Authenticate client */
+		if (auth_addr != INADDR_ANY && auth_addr != cliaddr.sin_addr.s_addr) {
+            pandoraLog ("UDP Server: Unauthorised access from %s", inet_ntoa (cliaddr.sin_addr));
+            continue;
+		}
+
+    	mesg[n] = 0;
+    	process_command (server->getService (), mesg);
+	}
+
+    WSACleanup ();
+}
+
+/** 
+ * Processes and executes server commands.
+ * 
+ * @param service Windows service associated to the server.
+ * @param command Server command.
+ * 
+ * @return 1 on error, 0 otherwise.
+ */
+int Pandora::process_command (Pandora_Windows_Service *service, char *command) {
+	int rc;
+	char operation[MAX_PACKET_SIZE], action[MAX_PACKET_SIZE], target[MAX_PACKET_SIZE];
+	string var, value;
+    Pandora_Agent_Conf  *conf = NULL;
+
+	rc = sscanf (command, "%s %s %s", operation, action, target);
+	if (rc < 3) {
+		pandoraLog ("UDP Server: Received invalid data: %s", command);
+		return 1;
+	}
+
+    /* Re-run */	
+	if (strcmp (operation, "REFRESH") == 0) {
+        service->pandora_run ();
+        return 0;
+    }
+    
+    conf = service->getConf();
+    
+    /* Service management */
+    if (strcmp (action, "SERVICE") == 0) {
+        var = "service_";
+        var.append (target);
+        std::transform(var.begin(), var.end(), var.begin(), ::tolower);
+        value = conf->getValue (var);
+        if (atoi (value.c_str ()) != 1) {
+            pandoraLog ("UDP Server: Unauthorised access to service %s", target);
+            return 1;
+        }
+
+        if (strcmp (operation, "START") == 0) {
+            Pandora_Wmi::startService (target);
+        } else if (strcmp (operation, "STOP") == 0) {
+            Pandora_Wmi::stopService (target);
+        }
+    }
+
+    /* Process management */
+    if (strcmp (action, "PROCESS") == 0) {
+        var = "process_";
+        var.append (target);
+        std::transform(var.begin(), var.end(), var.begin(), ::tolower);
+
+        if (strcmp (operation, "START") == 0) {
+            var.append ("_start");
+        } else if (strcmp (operation, "STOP") == 0) {
+            var.append ("_stop");
+        } else {
+            return 1;
+        }
+
+        value = conf->getValue (var);
+        if (value.empty ()) {
+            pandoraLog ("UDP Server: Unauthorised access to process %s", target);
+            return 1;
+        }
+        
+        system (value.c_str());
+    }
+
+	return 0;
+}
diff --git a/pandora_agents/win32/udp_server/udp_server.h b/pandora_agents/win32/udp_server/udp_server.h
new file mode 100644
index 0000000000..e70c73d66a
--- /dev/null
+++ b/pandora_agents/win32/udp_server/udp_server.h
@@ -0,0 +1,38 @@
+#ifndef __UDP_SERVER_H__
+#define __UDP_SERVER_H__
+
+#define MAX_PACKET_SIZE	1024
+
+#include "../pandora_windows_service.h"
+
+namespace Pandora {
+
+	/**
+	 * UDP Server class.
+	 */
+	class UDP_Server {
+		public:
+			UDP_Server (Pandora_Windows_Service *service, string address, string auth_address, unsigned int port);
+			~UDP_Server ();
+            unsigned long getAddress ();
+            unsigned long getAuthAddress ();
+            unsigned long getPort ();
+            Pandora_Windows_Service *getService ();
+			unsigned char isRunning ();
+
+			int start ();
+			int stop ();
+
+		private:
+			unsigned long address;
+            unsigned long auth_address;
+			unsigned long port;
+			unsigned char running;
+			Pandora_Windows_Service *service;
+	};
+
+    void listen (UDP_Server *server);
+	int process_command (Pandora_Windows_Service *service, char *command);
+}
+
+#endif
diff --git a/pandora_agents/win32/windows/pandora_wmi.cc b/pandora_agents/win32/windows/pandora_wmi.cc
index 75e83f046f..321cdcca40 100644
--- a/pandora_agents/win32/windows/pandora_wmi.cc
+++ b/pandora_agents/win32/windows/pandora_wmi.cc
@@ -25,7 +25,7 @@
 #include <algorithm>
 #include <cctype>
 #include <sstream>
-#include <ctime>
+#include <ctime>
 #include <winuser.h>
 
 using namespace std;
@@ -389,8 +389,8 @@ Pandora_Wmi::getSystemName () {
  * @return The list of events.
  */
 void
-Pandora_Wmi::getEventList (string source, string type, string code,
-			   string pattern, int interval,
+Pandora_Wmi::getEventList (string source, string type, string code,
+			   string pattern, int interval,
 			   list<string> &event_list) {
 	CDhInitialize init;
 	CDispPtr      wmi_svc, quickfixes;
@@ -514,121 +514,121 @@ Pandora_Wmi::convertWMIDate (string wmi_date, SYSTEMTIME *system_time)
 	system_time->wHour = atoi (wmi_date.substr (8, 2).c_str());
 	system_time->wMinute = atoi (wmi_date.substr (10, 2).c_str());
 	system_time->wSecond = atoi (wmi_date.substr (12, 2).c_str());
-}
+}
+
+/**
+ * Runs a program in a new process.
+ *
+ * @param command Command to run, with parameters
+ */
+bool
+Pandora_Wmi::runProgram (string command) {
+	PROCESS_INFORMATION process_info;
+	STARTUPINFO         startup_info;
+	bool                success;
+	char               *cmd;
+	
+	if (command == "")
+		return false;
+	
+	ZeroMemory (&startup_info, sizeof (startup_info));
+	startup_info.cb = sizeof (startup_info);
+	ZeroMemory (&process_info, sizeof (process_info));
+	
+	pandoraDebug ("Start process \"%s\".", command.c_str ());
+	cmd = strdup (command.c_str ());
+	success = CreateProcess (NULL, cmd, NULL, NULL, FALSE, 0,
+				 NULL, NULL, &startup_info, &process_info);
+	pandoraFree (cmd);
+	
+	if (success) {
+		pandoraDebug ("The process \"%s\" was started.", command.c_str ());
+		return true;
+	}
+	pandoraLog ("Could not start process \"%s\". Error %d", command.c_str (),
+		    GetLastError());
+	return false;
+}
+
+/**
+ * Start a Windows service.
+ *
+ * @param service_name Service internal name to start.
+ *
+ * @retval true If the service started.
+ * @retval false If the service could not start. A log message is created.
+ */
+bool
+Pandora_Wmi::startService (string service_name) {
+	SC_HANDLE manager, service;
+	bool      success;
+	
+	manager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+	if (manager == NULL) {
+		pandoraLog ("Could not access to service \"%s\" to start.",
+			    service_name.c_str ());
+		return false;
+	}
+	
+	service = OpenService (manager, service_name.c_str (), GENERIC_EXECUTE);
+	if (service == NULL) {
+		pandoraLog ("Could not access to service \"%s\" to start.",
+			    service_name.c_str ());
+		CloseServiceHandle (manager);
+		return false;
+	}
+	
+	success = StartService (service, 0, NULL);
+	
+	CloseServiceHandle (service);
+	CloseServiceHandle (manager);
+	
+	if (! success) {
+		pandoraLog ("Could not start service \"%s\". (Error %d)",
+			    service_name.c_str (), GetLastError ());
+	}
+	
+	return success;
+}
+
+/**
+ * Stop a Windows service.
+ *
+ * @param service_name Service internal name to stop.
+ *
+ * @retval true If the service started.
+ * @retval false If the service could not stop. A log message is created.
+ */
+bool
+Pandora_Wmi::stopService (string service_name) {
+	SC_HANDLE manager, service;
+	bool      success;
+	
+	manager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+	if (manager == NULL) {
+		pandoraLog ("Could not access to service \"%s\" to stop.",
+			    service_name.c_str ());
+		return false;
+	}
+	
+	service = OpenService (manager, service_name.c_str (), SERVICE_STOP);
+	if (service == NULL) {
+		pandoraLog ("Could not access to service \"%s\" to stop.",
+			    service_name.c_str ());
+		CloseServiceHandle (manager);
+		return false;
+	}
+	
+	success = ControlService (service, SERVICE_CONTROL_STOP, NULL);
+	
+	CloseServiceHandle (service);
+	CloseServiceHandle (manager);
+	
+	if (! success) {
+		pandoraLog ("Could not stop service \"%s\". (Error %d)",
+			    service_name.c_str (), GetLastError ());
+	}
+	
+	return success;
+}
 
-/**
- * Runs a program in a new process.
- *
- * @param command Command to run, with parameters
- */
-bool
-Pandora_Wmi::runProgram (string command) {
-	PROCESS_INFORMATION process_info;
-	STARTUPINFO         startup_info;
-	bool                success;
-	char               *cmd;
-	
-	if (command == "")
-		return false;
-	
-	ZeroMemory (&startup_info, sizeof (startup_info));
-	startup_info.cb = sizeof (startup_info);
-	ZeroMemory (&process_info, sizeof (process_info));
-	
-	pandoraDebug ("Start process \"%s\".", command.c_str ());
-	cmd = strdup (command.c_str ());
-	success = CreateProcess (NULL, cmd, NULL, NULL, FALSE, 0,
-				 NULL, NULL, &startup_info, &process_info);
-	pandoraFree (cmd);
-	
-	if (success) {
-		pandoraDebug ("The process \"%s\" was started.", command.c_str ());
-		return true;
-	}
-	pandoraLog ("Could not start process \"%s\". Error %d", command.c_str (),
-		    GetLastError());
-	return false;
-}
-
-/**
- * Start a Windows service.
- *
- * @param service_name Service internal name to start.
- *
- * @retval true If the service started.
- * @retval false If the service could not start. A log message is created.
- */
-bool
-Pandora_Wmi::startService (string service_name) {
-	SC_HANDLE manager, service;
-	bool      success;
-	
-	manager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
-	if (manager == NULL) {
-		pandoraLog ("Could not access to service \"%s\" to start.",
-			    service_name.c_str ());
-		return false;
-	}
-	
-	service = OpenService (manager, service_name.c_str (), GENERIC_EXECUTE);
-	if (service == NULL) {
-		pandoraLog ("Could not access to service \"%s\" to start.",
-			    service_name.c_str ());
-		CloseServiceHandle (manager);
-		return false;
-	}
-	
-	success = StartService (service, 0, NULL);
-	
-	CloseServiceHandle (service);
-	CloseServiceHandle (manager);
-	
-	if (! success) {
-		pandoraLog ("Could not start service \"%s\". (Error %d)",
-			    service_name.c_str (), GetLastError ());
-	}
-	
-	return success;
-}
-
-/**
- * Stop a Windows service.
- *
- * @param service_name Service internal name to stop.
- *
- * @retval true If the service started.
- * @retval false If the service could not stop. A log message is created.
- */
-bool
-Pandora_Wmi::stopService (string service_name) {
-	SC_HANDLE manager, service;
-	bool      success;
-	
-	manager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
-	if (manager == NULL) {
-		pandoraLog ("Could not access to service \"%s\" to stop.",
-			    service_name.c_str ());
-		return false;
-	}
-	
-	service = OpenService (manager, service_name.c_str (), GENERIC_EXECUTE);
-	if (service == NULL) {
-		pandoraLog ("Could not access to service \"%s\" to stop.",
-			    service_name.c_str ());
-		CloseServiceHandle (manager);
-		return false;
-	}
-	
-	success = ControlService (service, SERVICE_CONTROL_STOP, NULL);
-	
-	CloseServiceHandle (service);
-	CloseServiceHandle (manager);
-	
-	if (! success) {
-		pandoraLog ("Could not stop service \"%s\". (Error %d)",
-			    service_name.c_str (), GetLastError ());
-	}
-	
-	return success;
-}
-