1 /* Copyright (C) 2009 Trend Micro Inc.
2 * All rights reserved.
3 *
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
7 * Foundation.
8 */
9
10 #ifdef WIN32
11
12 #include "shared.h"
13 #include "os_win.h"
14 #include <winsvc.h>
15
16 #ifndef ARGV0
17 #define ARGV0 "ossec-agent"
18 #endif
19
20 static LPTSTR g_lpszServiceName = "OssecSvc";
21 static LPTSTR g_lpszServiceDisplayName = "OSSEC HIDS";
22 static LPTSTR g_lpszServiceDescription = "OSSEC HIDS Windows Agent";
23
24 static SERVICE_STATUS ossecServiceStatus;
25 static SERVICE_STATUS_HANDLE ossecServiceStatusHandle;
26
27 void WINAPI OssecServiceStart (DWORD argc, LPTSTR *argv);
28
29
30 /* Start OSSEC-HIDS service */
os_start_service()31 int os_start_service()
32 {
33 int rc = 0;
34 SC_HANDLE schSCManager, schService;
35
36 /* Start the database */
37 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
38 if (schSCManager) {
39 schService = OpenService(schSCManager, g_lpszServiceName,
40 SC_MANAGER_ALL_ACCESS);
41 if (schService) {
42 if (StartService(schService, 0, NULL)) {
43 rc = 1;
44 } else {
45 if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) {
46 rc = -1;
47 }
48 }
49
50 CloseServiceHandle(schService);
51 }
52
53 CloseServiceHandle(schSCManager);
54 }
55
56 return (rc);
57 }
58
59 /* Stop OSSEC-HIDS service */
os_stop_service()60 int os_stop_service()
61 {
62 int rc = 0;
63 SC_HANDLE schSCManager, schService;
64
65 /* Stop the service database */
66 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
67 if (schSCManager) {
68 schService = OpenService(schSCManager, g_lpszServiceName,
69 SC_MANAGER_ALL_ACCESS);
70 if (schService) {
71 SERVICE_STATUS lpServiceStatus;
72
73 if (ControlService(schService, SERVICE_CONTROL_STOP, &lpServiceStatus)) {
74 rc = 1;
75 }
76
77 CloseServiceHandle(schService);
78 }
79
80 CloseServiceHandle(schSCManager);
81 }
82
83 return (rc);
84 }
85
86 /* Check if the OSSEC-HIDS agent service is running
87 * Returns 1 on success (running) or 0 if not running
88 */
CheckServiceRunning()89 int CheckServiceRunning()
90 {
91 int rc = 0;
92 SC_HANDLE schSCManager, schService;
93
94 /* Check service status */
95 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
96 if (schSCManager) {
97 schService = OpenService(schSCManager, g_lpszServiceName,
98 SC_MANAGER_ALL_ACCESS);
99 if (schService) {
100 /* Check status */
101 SERVICE_STATUS lpServiceStatus;
102
103 if (QueryServiceStatus(schService, &lpServiceStatus)) {
104 if (lpServiceStatus.dwCurrentState == SERVICE_RUNNING) {
105 rc = 1;
106 }
107 }
108 CloseServiceHandle(schService);
109 }
110
111 CloseServiceHandle(schSCManager);
112 }
113
114 return (rc);
115 }
116
117 /* Install the OSSEC-HIDS agent service */
InstallService(char * path)118 int InstallService(char *path)
119 {
120 int ret;
121 SC_HANDLE schSCManager, schService;
122 LPCTSTR lpszBinaryPathName = NULL;
123 SERVICE_DESCRIPTION sdBuf;
124
125 /* Uninstall service (if it exists) */
126 if (!UninstallService()) {
127 verbose("%s: ERROR: Failure running UninstallService().", ARGV0);
128 return (0);
129 }
130
131 /* Executable path -- it must be called with the full path */
132 lpszBinaryPathName = path;
133
134 /* Opening the service database */
135 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
136
137 if (schSCManager == NULL) {
138 goto install_error;
139 }
140
141 /* Create the service */
142 schService = CreateService(schSCManager,
143 g_lpszServiceName,
144 g_lpszServiceDisplayName,
145 SERVICE_ALL_ACCESS,
146 SERVICE_WIN32_OWN_PROCESS,
147 SERVICE_AUTO_START,
148 SERVICE_ERROR_NORMAL,
149 lpszBinaryPathName,
150 NULL, NULL, NULL, NULL, NULL);
151
152 if (schService == NULL) {
153 CloseServiceHandle(schSCManager);
154 goto install_error;
155 }
156
157 /* Set description */
158 sdBuf.lpDescription = g_lpszServiceDescription;
159 ret = ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdBuf);
160
161 CloseServiceHandle(schService);
162 CloseServiceHandle(schSCManager);
163
164 /* Check for errors */
165 if (!ret) {
166 goto install_error;
167 }
168
169 verbose("%s: INFO: Successfully added to the service database.", ARGV0);
170 return (1);
171
172 install_error: {
173 char local_msg[1025];
174 LPVOID lpMsgBuf;
175
176 memset(local_msg, 0, 1025);
177
178 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
179 FORMAT_MESSAGE_FROM_SYSTEM |
180 FORMAT_MESSAGE_IGNORE_INSERTS,
181 NULL,
182 GetLastError(),
183 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
184 (LPTSTR) &lpMsgBuf,
185 0,
186 NULL);
187
188 verbose("%s: ERROR: Unable to create service entry: %s", ARGV0, (LPCTSTR)lpMsgBuf);
189 return (0);
190 }
191 }
192
193 /* Uninstall the OSSEC-HIDS agent service */
UninstallService()194 int UninstallService()
195 {
196 int ret;
197 int rc = 0;
198 SC_HANDLE schSCManager, schService;
199 SERVICE_STATUS lpServiceStatus;
200
201 /* Remove from the service database */
202 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
203 if (schSCManager) {
204 schService = OpenService(schSCManager, g_lpszServiceName, SERVICE_STOP | DELETE);
205 if (schService) {
206 if (CheckServiceRunning()) {
207 verbose("%s: INFO: Found (%s) service is running going to try and stop it.", ARGV0, g_lpszServiceName);
208 ret = ControlService(schService, SERVICE_CONTROL_STOP, &lpServiceStatus);
209 if (!ret) {
210 verbose("%s: ERROR: Failure stopping service (%s) before removing it (%ld).", ARGV0, g_lpszServiceName, GetLastError());
211 } else {
212 verbose("%s: INFO: Successfully stopped (%s).", ARGV0, g_lpszServiceName);
213 }
214 } else {
215 verbose("%s: INFO: Found (%s) service is not running.", ARGV0, g_lpszServiceName);
216 ret = 1;
217 }
218
219 if (ret && DeleteService(schService)) {
220 verbose("%s: INFO: Successfully removed (%s) from the service database.", ARGV0, g_lpszServiceName);
221 rc = 1;
222 }
223 CloseServiceHandle(schService);
224 } else {
225 verbose("%s: INFO: Service does not exist (%s) nothing to remove.", ARGV0, g_lpszServiceName);
226 rc = 1;
227 }
228 CloseServiceHandle(schSCManager);
229 }
230
231 if (!rc) {
232 verbose("%s: ERROR: Failure removing (%s) from the service database.", ARGV0, g_lpszServiceName);
233 }
234
235 return (rc);
236 }
237
238 /* "Signal" handler */
OssecServiceCtrlHandler(DWORD dwOpcode)239 VOID WINAPI OssecServiceCtrlHandler(DWORD dwOpcode)
240 {
241 switch (dwOpcode) {
242 case SERVICE_CONTROL_STOP:
243 ossecServiceStatus.dwCurrentState = SERVICE_STOPPED;
244 ossecServiceStatus.dwWin32ExitCode = 0;
245 ossecServiceStatus.dwCheckPoint = 0;
246 ossecServiceStatus.dwWaitHint = 0;
247
248 verbose("%s: INFO: Received exit signal.", ARGV0);
249 SetServiceStatus (ossecServiceStatusHandle, &ossecServiceStatus);
250 verbose("%s: INFO: Exiting...", ARGV0);
251 return;
252 default:
253 break;
254 }
255 return;
256 }
257
258 /* Set the error code in the service */
WinSetError()259 void WinSetError()
260 {
261 OssecServiceCtrlHandler(SERVICE_CONTROL_STOP);
262 }
263
264 /* Initialize OSSEC-HIDS dispatcher */
os_WinMain(int argc,char ** argv)265 int os_WinMain(__attribute__((unused)) int argc, __attribute__((unused)) char **argv)
266 {
267 SERVICE_TABLE_ENTRY steDispatchTable[] = {
268 { g_lpszServiceName, OssecServiceStart },
269 { NULL, NULL }
270 };
271
272 if (!StartServiceCtrlDispatcher(steDispatchTable)) {
273 verbose("%s: INFO: Unable to set service information.", ARGV0);
274 return (1);
275 }
276
277 return (1);
278 }
279
280 /* Start OSSEC service */
OssecServiceStart(DWORD argc,LPTSTR * argv)281 void WINAPI OssecServiceStart (__attribute__((unused)) DWORD argc, __attribute__((unused)) LPTSTR *argv)
282 {
283 ossecServiceStatus.dwServiceType = SERVICE_WIN32;
284 ossecServiceStatus.dwCurrentState = SERVICE_START_PENDING;
285 ossecServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
286 ossecServiceStatus.dwWin32ExitCode = 0;
287 ossecServiceStatus.dwServiceSpecificExitCode = 0;
288 ossecServiceStatus.dwCheckPoint = 0;
289 ossecServiceStatus.dwWaitHint = 0;
290
291 ossecServiceStatusHandle =
292 RegisterServiceCtrlHandler(g_lpszServiceName,
293 OssecServiceCtrlHandler);
294
295 if (ossecServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) {
296 verbose("%s: INFO: RegisterServiceCtrlHandler failed.", ARGV0);
297 return;
298 }
299
300 ossecServiceStatus.dwCurrentState = SERVICE_RUNNING;
301 ossecServiceStatus.dwCheckPoint = 0;
302 ossecServiceStatus.dwWaitHint = 0;
303
304 if (!SetServiceStatus(ossecServiceStatusHandle, &ossecServiceStatus)) {
305 verbose("%s: INFO: SetServiceStatus error.", ARGV0);
306 return;
307 }
308
309 #ifdef OSSECHIDS
310 /* Start process */
311 local_start();
312 #endif
313 }
314
315 #endif /* WIN32 */
316