1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package it.jnrpe.client;
17
18 import it.jnrpe.ReturnValue;
19 import it.jnrpe.Status;
20 import it.jnrpe.net.JNRPERequest;
21 import it.jnrpe.net.JNRPEResponse;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.InetSocketAddress;
26 import java.net.Socket;
27 import java.net.SocketTimeoutException;
28 import java.security.SecureRandom;
29 import java.security.cert.CertificateException;
30 import java.security.cert.X509Certificate;
31
32 import javax.net.SocketFactory;
33 import javax.net.ssl.SSLContext;
34 import javax.net.ssl.TrustManager;
35 import javax.net.ssl.X509TrustManager;
36
37 import org.apache.commons.cli2.CommandLine;
38 import org.apache.commons.cli2.DisplaySetting;
39 import org.apache.commons.cli2.Group;
40 import org.apache.commons.cli2.OptionException;
41 import org.apache.commons.cli2.builder.ArgumentBuilder;
42 import org.apache.commons.cli2.builder.DefaultOptionBuilder;
43 import org.apache.commons.cli2.builder.GroupBuilder;
44 import org.apache.commons.cli2.commandline.Parser;
45 import org.apache.commons.cli2.option.DefaultOption;
46 import org.apache.commons.cli2.util.HelpFormatter;
47 import org.apache.commons.cli2.validation.NumberValidator;
48
49
50
51
52
53
54
55
56 public class JNRPEClient {
57
58
59
60
61 private static final int DEFAULT_TIMEOUT = 10;
62
63
64
65
66 private static final int DEFAULT_PORT = 5666;
67
68
69
70
71 private final String serverIPorURL;
72
73
74
75
76 private final int serverPort;
77
78
79
80
81 private final boolean useSSL;
82
83
84
85
86 private int communicationTimeout = DEFAULT_TIMEOUT;
87
88
89
90
91
92
93
94
95
96
97
98 public JNRPEClient(final String sJNRPEServerIP, final int iJNRPEServerPort,
99 final boolean bSSL) {
100 serverIPorURL = sJNRPEServerIP;
101 serverPort = iJNRPEServerPort;
102 useSSL = bSSL;
103 }
104
105
106
107
108
109
110 private TrustManager getTrustManager() {
111
112 return new X509TrustManager() {
113
114 public X509Certificate[] getAcceptedIssuers() {
115 return null;
116 }
117
118 public void checkServerTrusted(final X509Certificate[] chain,
119 final String authType) throws CertificateException {
120
121 }
122
123 public void checkClientTrusted(final X509Certificate[] chain,
124 final String authType) throws CertificateException {
125 }
126 };
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141 public final ReturnValue sendCommand(final String sCommandName,
142 final String... arguments) throws JNRPEClientException {
143 SocketFactory socketFactory = null;
144
145 Socket s = null;
146 try {
147 if (!useSSL) {
148 socketFactory = SocketFactory.getDefault();
149 } else {
150 SSLContext sslContext = SSLContext.getInstance("SSL");
151 sslContext.init(null, null, new java.security.SecureRandom());
152
153 sslContext.init(null, new TrustManager[] { getTrustManager() },
154 new SecureRandom());
155
156 socketFactory = sslContext.getSocketFactory();
157 }
158
159 s = socketFactory.createSocket();
160 s.setSoTimeout(communicationTimeout * 1000);
161 s.connect(new InetSocketAddress(serverIPorURL, serverPort));
162 JNRPERequest req = new JNRPERequest(sCommandName, arguments);
163
164 s.getOutputStream().write(req.toByteArray());
165
166 InputStream in = s.getInputStream();
167 JNRPEResponse res = new JNRPEResponse(in);
168
169 return new ReturnValue(Status.fromIntValue(res.getResultCode()),
170 res.getMessage());
171 } catch (Exception e) {
172
173 throw new JNRPEClientException(e);
174 } finally {
175 if (s != null) {
176 try {
177 s.close();
178 } catch (IOException e) {
179
180 }
181 }
182 }
183 }
184
185
186
187
188
189
190
191 public final void setTimeout(final int iTimeout) {
192 communicationTimeout = iTimeout;
193 }
194
195
196
197
198
199
200 public final int getTimeout() {
201 return communicationTimeout;
202 }
203
204
205
206
207
208
209 private static Group configureCommandLine() {
210 DefaultOptionBuilder oBuilder = new DefaultOptionBuilder();
211 ArgumentBuilder aBuilder = new ArgumentBuilder();
212 GroupBuilder gBuilder = new GroupBuilder();
213
214 DefaultOption nosslOption = oBuilder.withLongName("nossl")
215 .withShortName("n").withDescription("Do no use SSL").create();
216
217 DefaultOption unknownOption = oBuilder
218 .withLongName("unknown")
219 .withShortName("u")
220 .withDescription(
221 "Make socket timeouts return an UNKNOWN "
222 + "state instead of CRITICAL").create();
223
224 DefaultOption hostOption = oBuilder
225 .withLongName("host")
226 .withShortName("H")
227 .withDescription(
228 "The address of the host running "
229 + "the JNRPE/NRPE daemon")
230 .withArgument(
231 aBuilder.withName("host").withMinimum(1).withMaximum(1)
232 .create()).create();
233
234 NumberValidator positiveInt = NumberValidator.getIntegerInstance();
235 positiveInt.setMinimum(0);
236 DefaultOption portOption = oBuilder
237 .withLongName("port")
238 .withShortName("p")
239 .withDescription(
240 "The port on which the daemon "
241 + "is running (default=5666)")
242 .withArgument(
243 aBuilder.withName("port").withMinimum(1).withMaximum(1)
244 .withDefault(new Long(DEFAULT_PORT))
245 .withValidator(positiveInt).create()).create();
246
247 DefaultOption timeoutOption = oBuilder
248 .withLongName("timeout")
249 .withShortName("t")
250 .withDescription(
251 "Number of seconds before connection "
252 + "times out (default=10)")
253 .withArgument(
254 aBuilder.withName("timeout").withMinimum(1)
255 .withMaximum(1)
256 .withDefault(new Long(DEFAULT_TIMEOUT))
257 .withValidator(positiveInt).create()).create();
258
259 DefaultOption commandOption = oBuilder
260 .withLongName("command")
261 .withShortName("c")
262 .withDescription(
263 "The name of the command that "
264 + "the remote daemon should run")
265 .withArgument(
266 aBuilder.withName("command").withMinimum(1)
267 .withMaximum(1).create()).create();
268
269 DefaultOption argsOption = oBuilder
270 .withLongName("arglist")
271 .withShortName("a")
272 .withDescription(
273 "Optional arguments that should be "
274 + "passed to the command. Multiple "
275 + "arguments should be separated by "
276 + "a space (' '). If provided, "
277 + "this must be the last option "
278 + "supplied on the command line.")
279 .withArgument(
280 aBuilder.withName("arglist").withMinimum(1).create())
281 .create();
282
283 DefaultOption helpOption = oBuilder.withLongName("help")
284 .withShortName("h").withDescription("Shows this help").create();
285
286 Group executionOption = gBuilder.withOption(nosslOption)
287 .withOption(unknownOption).withOption(hostOption)
288 .withOption(portOption).withOption(timeoutOption)
289 .withOption(commandOption).withOption(argsOption).create();
290
291 Group mainGroup = gBuilder.withOption(executionOption)
292 .withOption(helpOption).withMinimum(1).withMaximum(1).create();
293
294 return mainGroup;
295 }
296
297
298
299
300 private static void printVersion() {
301
302 System.out.println("jcheck_nrpe version "
303 + JNRPEClient.class.getPackage().getImplementationVersion());
304 System.out.println("Copyright (c) 2013 Massimiliano Ziccardi");
305 System.out.println("Licensed under the Apache License, Version 2.0");
306 System.out.println();
307 }
308
309
310
311
312
313
314
315
316 @SuppressWarnings("unchecked")
317 private static void printUsage(final Exception e) {
318 printVersion();
319
320 StringBuffer sbDivider = new StringBuffer("=");
321
322 if (e != null) {
323 System.out.println(e.getMessage() + "\n");
324 }
325
326 HelpFormatter hf = new HelpFormatter();
327 while (sbDivider.length() < hf.getPageWidth()) {
328 sbDivider.append("=");
329 }
330
331
332 hf.getDisplaySettings().clear();
333 hf.getDisplaySettings().add(DisplaySetting.DISPLAY_GROUP_EXPANDED);
334 hf.getDisplaySettings().add(DisplaySetting.DISPLAY_PARENT_CHILDREN);
335
336
337
338 hf.getFullUsageSettings().clear();
339 hf.getFullUsageSettings().add(DisplaySetting.DISPLAY_PARENT_ARGUMENT);
340 hf.getFullUsageSettings()
341 .add(DisplaySetting.DISPLAY_ARGUMENT_BRACKETED);
342 hf.getFullUsageSettings().add(DisplaySetting.DISPLAY_PARENT_CHILDREN);
343 hf.getFullUsageSettings().add(DisplaySetting.DISPLAY_GROUP_EXPANDED);
344
345 hf.setDivider(sbDivider.toString());
346
347 hf.setGroup(configureCommandLine());
348 hf.print();
349 System.exit(0);
350 }
351
352
353
354
355
356
357
358
359 public static void main(final String[] args) throws Exception {
360
361 Parser parser = new Parser();
362 parser.setGroup(configureCommandLine());
363
364 boolean timeoutAsUnknown = false;
365
366 try {
367 CommandLine cli = parser.parse(args);
368
369 if (cli.hasOption("--help")) {
370 printUsage(null);
371 }
372
373 timeoutAsUnknown = cli.hasOption("--unknown");
374
375 String sHost = (String) cli.getValue("--host");
376 Long port = (Long) cli.getValue("--port", new Long(DEFAULT_PORT));
377 String sCommand = (String) cli.getValue("--command");
378
379 JNRPEClient client = new JNRPEClient(sHost, port.intValue(),
380 !cli.hasOption("--nossl"));
381 client.setTimeout(((Long) cli.getValue("--timeout", new Long(
382 DEFAULT_TIMEOUT))).intValue());
383
384 @SuppressWarnings("unchecked")
385 ReturnValue ret = client.sendCommand(sCommand, (String[]) cli
386 .getValues("--arglist").toArray(new String[0]));
387
388 System.out.println(ret.getMessage());
389 System.exit(ret.getStatus().intValue());
390 } catch (JNRPEClientException exc) {
391 Status returnStatus = null;
392
393 if (timeoutAsUnknown && exc.getCause() != null
394 && exc.getCause() instanceof SocketTimeoutException) {
395 returnStatus = Status.UNKNOWN;
396 } else {
397 returnStatus = Status.CRITICAL;
398 }
399
400 System.out.println(exc.getMessage());
401 System.exit(returnStatus.intValue());
402 } catch (OptionException oe) {
403 printUsage(oe);
404 }
405 }
406 }