implemented single housekeeping thread for all message wait queues
[public/netxms.git] / src / server / tools / nxap / nxap.cpp
CommitLineData
4cd1e46b
AK
1/*
2** nxap - command line tool used to manage agent policies
c11eee9b 3** Copyright (C) 2010-2015 Victor Kirhenshtein
4cd1e46b
AK
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** File: nxap.cpp
20**
21**/
22
23#include <nms_common.h>
24#include <nms_agent.h>
25#include <nms_util.h>
4cd1e46b
AK
26#include <nxsrvapi.h>
27
28#ifndef _WIN32
29#include <netdb.h>
30#endif
31
32
33//
34// Get policy list
35//
36
37static int GetPolicyInventory(AgentConnection &conn)
38{
39 AgentPolicyInfo *ap;
40 UINT32 rcc = conn.getPolicyInventory(&ap);
41 if (rcc == ERR_SUCCESS)
42 {
43 TCHAR buffer[64];
44 uuid_t guid;
45
46 _tprintf(_T("GUID Type Server\n")
47 _T("----------------------------------------------------------\n"));
a6312bd6 48 for(int i = 0; i < ap->size(); i++)
4cd1e46b
AK
49 {
50 ap->getGuid(i, guid);
51 _tprintf(_T("%-16s %-4d %s\n"), uuid_to_string(guid, buffer), ap->getType(i), ap->getServer(i));
52 }
53 delete ap;
54 }
55 else
56 {
57 _tprintf(_T("%d: %s\n"), rcc, AgentErrorCodeToText(rcc));
58 }
59 return (rcc == ERR_SUCCESS) ? 0 : 1;
60}
61
62
63//
64// Uninstall policy
65//
66
67static int UninstallPolicy(AgentConnection &conn, uuid_t guid)
68{
69 UINT32 rcc = conn.uninstallPolicy(guid);
70 if (rcc == ERR_SUCCESS)
71 {
72 _tprintf(_T("Policy successfully uninstalled from agent\n"));
73 }
74 else
75 {
76 _tprintf(_T("%d: %s\n"), rcc, AgentErrorCodeToText(rcc));
77 }
78 return (rcc == ERR_SUCCESS) ? 0 : 1;
79}
80
81
82//
83// Startup
84//
85
86int main(int argc, char *argv[])
87{
88 char *eptr;
89 BOOL bStart = TRUE, bVerbose = TRUE;
90 int i, ch, iExitCode = 3, action = -1;
91 int iAuthMethod = AUTH_NONE;
92#ifdef _WITH_ENCRYPTION
93 int iEncryptionPolicy = ENCRYPTION_ALLOWED;
94#else
95 int iEncryptionPolicy = ENCRYPTION_DISABLED;
96#endif
97 WORD wPort = AGENT_LISTEN_PORT;
c11eee9b 98 UINT32 dwTimeout = 5000, dwConnTimeout = 30000, dwError;
4cd1e46b
AK
99 TCHAR szSecret[MAX_SECRET_LENGTH] = _T("");
100 TCHAR szKeyFile[MAX_PATH] = DEFAULT_DATA_DIR DFILE_KEYS;
101 RSA *pServerKey = NULL;
102 uuid_t guid;
103
104 InitThreadLibrary();
105
106 // Parse command line
107 opterr = 1;
108 while((ch = getopt(argc, argv, "a:e:hK:lp:qs:u:vw:W:")) != -1)
109 {
110 switch(ch)
111 {
112 case 'h': // Display help and exit
113 _tprintf(_T("Usage: nxap [<options>] -l <host>\n")
114 _T(" or: nxap [<options>] -u <guid> <host>\n")
115 _T("Valid options are:\n")
116 _T(" -a <auth> : Authentication method. Valid methods are \"none\",\n")
117 _T(" \"plain\", \"md5\" and \"sha1\". Default is \"none\".\n")
118#ifdef _WITH_ENCRYPTION
119 _T(" -e <policy> : Set encryption policy. Possible values are:\n")
120 _T(" 0 = Encryption disabled;\n")
121 _T(" 1 = Encrypt connection only if agent requires encryption;\n")
122 _T(" 2 = Encrypt connection if agent supports encryption;\n")
123 _T(" 3 = Force encrypted connection;\n")
124 _T(" Default value is 1.\n")
125#endif
126 _T(" -h : Display help and exit.\n")
127#ifdef _WITH_ENCRYPTION
128 _T(" -K <file> : Specify server's key file\n")
129 _T(" (default is ") DEFAULT_DATA_DIR DFILE_KEYS _T(").\n")
130#endif
131 _T(" -p <port> : Specify agent's port number. Default is %d.\n")
132 _T(" -q : Quiet mode.\n")
133 _T(" -s <secret> : Specify shared secret for authentication.\n")
134 _T(" -v : Display version and exit.\n")
135 _T(" -w <seconds> : Set command timeout (default is 5 seconds)\n")
136 _T(" -W <seconds> : Set connection timeout (default is 30 seconds)\n")
137 _T("\n"), wPort);
138 bStart = FALSE;
139 break;
140 case 'a': // Auth method
141 if (!strcmp(optarg, "none"))
142 iAuthMethod = AUTH_NONE;
143 else if (!strcmp(optarg, "plain"))
144 iAuthMethod = AUTH_PLAINTEXT;
145 else if (!strcmp(optarg, "md5"))
146 iAuthMethod = AUTH_MD5_HASH;
147 else if (!strcmp(optarg, "sha1"))
148 iAuthMethod = AUTH_SHA1_HASH;
149 else
150 {
151 _tprintf(_T("Invalid authentication method \"%hs\"\n"), optarg);
152 bStart = FALSE;
153 }
154 break;
155 case 'p': // Port number
156 i = strtol(optarg, &eptr, 0);
157 if ((*eptr != 0) || (i < 0) || (i > 65535))
158 {
159 _tprintf(_T("Invalid port number \"%hs\"\n"), optarg);
160 bStart = FALSE;
161 }
162 else
163 {
164 wPort = (WORD)i;
165 }
166 break;
167 case 'q': // Quiet mode
168 bVerbose = FALSE;
169 break;
170 case 's': // Shared secret
171#ifdef UNICODE
172 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, szSecret, MAX_SECRET_LENGTH);
173 szSecret[MAX_SECRET_LENGTH - 1] = 0;
174#else
175 nx_strncpy(szSecret, optarg, MAX_SECRET_LENGTH);
176#endif
177 break;
178 case 'v': // Print version and exit
179 _tprintf(_T("NetXMS Agent Policy Management Tool Version ") NETXMS_VERSION_STRING _T("\n"));
180 bStart = FALSE;
181 break;
182 case 'w': // Command timeout
183 i = strtol(optarg, &eptr, 0);
184 if ((*eptr != 0) || (i < 1) || (i > 120))
185 {
186 _tprintf(_T("Invalid timeout \"%hs\"\n"), optarg);
187 bStart = FALSE;
188 }
189 else
190 {
191 dwTimeout = (UINT32)i * 1000; // Convert to milliseconds
192 }
193 break;
194 case 'W': // Connect timeout
195 i = strtol(optarg, &eptr, 0);
196 if ((*eptr != 0) || (i < 1) || (i > 120))
197 {
198 _tprintf(_T("Invalid timeout \"%hs\"\n"), optarg);
199 bStart = FALSE;
200 }
201 else
202 {
203 dwConnTimeout = (UINT32)i * 1000; // Convert to milliseconds
204 }
205 break;
206#ifdef _WITH_ENCRYPTION
207 case 'e':
208 iEncryptionPolicy = atoi(optarg);
209 if ((iEncryptionPolicy < 0) ||
210 (iEncryptionPolicy > 3))
211 {
212 _tprintf(_T("Invalid encryption policy %d\n"), iEncryptionPolicy);
213 bStart = FALSE;
214 }
215 break;
216 case 'K':
217#ifdef UNICODE
218 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, szKeyFile, MAX_PATH);
219 szKeyFile[MAX_PATH - 1] = 0;
220#else
221 nx_strncpy(szKeyFile, optarg, MAX_PATH);
222#endif
223 break;
224#else
225 case 'e':
226 case 'K':
227 _tprintf(_T("ERROR: This tool was compiled without encryption support\n"));
228 bStart = FALSE;
229 break;
230#endif
231 case 'l': // List policies on agent
232 action = 0;
233 break;
234 case 'u': // Uninstall policy from agent
235 action = 1;
236#ifdef UNICODE
237 WCHAR wguid[256];
238 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, wguid, 256);
239 wguid[255] = 0;
240 uuid_parse(wguid, guid);
241#else
242 uuid_parse(optarg, guid);
243#endif
244 break;
245 case '?':
246 bStart = FALSE;
247 break;
248 default:
249 break;
250 }
251 }
252
253 // Check parameter correctness
254 if (action == -1)
255 {
256 _tprintf(_T("ERROR: You must specify either -l or -u option\n"));
257 bStart = FALSE;
258 }
259
260 if (bStart)
261 {
262 if (argc - optind < 1)
263 {
264 _tprintf(_T("Required argument(s) missing.\nUse nxap -h to get complete command line syntax.\n"));
265 bStart = FALSE;
266 }
267 else if ((iAuthMethod != AUTH_NONE) && (szSecret[0] == 0))
268 {
269 _tprintf(_T("Shared secret not specified or empty\n"));
270 bStart = FALSE;
271 }
272
273 // Load server key if requested
274#ifdef _WITH_ENCRYPTION
275 if ((iEncryptionPolicy != ENCRYPTION_DISABLED) && bStart)
276 {
6468147c 277 if (InitCryptoLib(0xFFFF, NULL))
4cd1e46b
AK
278 {
279 pServerKey = LoadRSAKeys(szKeyFile);
280 if (pServerKey == NULL)
281 {
282 _tprintf(_T("Error loading RSA keys from \"%s\"\n"), szKeyFile);
283 if (iEncryptionPolicy == ENCRYPTION_REQUIRED)
284 bStart = FALSE;
285 }
286 }
287 else
288 {
289 _tprintf(_T("Error initializing cryptografy module\n"));
290 if (iEncryptionPolicy == ENCRYPTION_REQUIRED)
291 bStart = FALSE;
292 }
293 }
294#endif
295
296 // If everything is ok, start communications
297 if (bStart)
298 {
4cd1e46b
AK
299 // Initialize WinSock
300#ifdef _WIN32
301 WSADATA wsaData;
302 WSAStartup(2, &wsaData);
303#endif
304
c11eee9b
VK
305 InetAddress addr = InetAddress::resolveHostName(argv[optind]);
306 if (!addr.isValid())
4cd1e46b
AK
307 {
308 _tprintf(_T("Invalid host name or address specified\n"));
309 }
310 else
311 {
c11eee9b 312 AgentConnection conn(addr, wPort, iAuthMethod, szSecret);
4cd1e46b
AK
313
314 conn.setConnectionTimeout(dwConnTimeout);
315 conn.setCommandTimeout(dwTimeout);
316 conn.setEncryptionPolicy(iEncryptionPolicy);
317 if (conn.connect(pServerKey, bVerbose, &dwError))
318 {
319 if (action == 0)
320 {
321 iExitCode = GetPolicyInventory(conn);
322 }
323 else
324 {
325 iExitCode = UninstallPolicy(conn, guid);
326 }
327 conn.disconnect();
328 }
329 else
330 {
331 _tprintf(_T("%d: %s\n"), dwError, AgentErrorCodeToText(dwError));
332 iExitCode = 2;
333 }
334 }
335 }
336 }
337
d87ddcc2 338 MsgWaitQueue::shutdown();
4cd1e46b
AK
339 return iExitCode;
340}