Java tutorial
/******************************************************************************* * Copyright (c) 2007, 2014 Massimiliano Ziccardi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package it.jnrpe.client; import it.jnrpe.ReturnValue; import it.jnrpe.Status; import it.jnrpe.net.JNRPERequest; import it.jnrpe.net.JNRPEResponse; import it.jnrpe.utils.TimeUnit; import java.io.IOException; import java.io.InputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.List; import java.util.Set; import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.commons.cli2.CommandLine; import org.apache.commons.cli2.DisplaySetting; import org.apache.commons.cli2.Group; import org.apache.commons.cli2.OptionException; import org.apache.commons.cli2.builder.ArgumentBuilder; import org.apache.commons.cli2.builder.DefaultOptionBuilder; import org.apache.commons.cli2.builder.GroupBuilder; import org.apache.commons.cli2.commandline.Parser; import org.apache.commons.cli2.option.DefaultOption; import org.apache.commons.cli2.util.HelpFormatter; import org.apache.commons.cli2.validation.NumberValidator; /** * This class represent a simple JNRPE client that can be used to invoke * commands installed inside JNRPE by code. It is the JAVA equivalent of * check_nrpe. * * @author Massimiliano Ziccardi */ public class JNRPEClient { /** * Default timeout in seconds. */ private static final int DEFAULT_TIMEOUT = 10; /** * Default server port. */ private static final int DEFAULT_PORT = 5666; /** * The IP address (or URL) of the JNRPE Server. */ private final String serverIPorURL; /** * The port where the JNRPE server listens to. */ private final int serverPort; /** * <code>true</code> if the communication must happens through SSL. */ private final boolean useSSL; /** * <code>true</code> to enable weak cipher suites. Useful if you need to be * able to communicate with NSClient++ */ private boolean weakCipherSuitesEnabled = false; /** * The communication timeout (in seconds). */ private int communicationTimeout = DEFAULT_TIMEOUT; /** * The trust manager. */ private static final TrustAllManager TRUSTALL_MGR = new TrustAllManager(); /** * Trust manager implementation. This trust manager allows connection on any * host. * * @author Massimiliano Ziccardi */ private static final class TrustAllManager implements X509TrustManager { /** * Empty list of accepted issuers. */ private static final X509Certificate[] ISSUERS = new X509Certificate[0]; /** * Simply returns null. * * @return null */ public X509Certificate[] getAcceptedIssuers() { return ISSUERS; } /** * No checks performed. * * @param chain * certificate chain * @param authType * authentication type */ public void checkServerTrusted(final X509Certificate[] chain, final String authType) { } /** * No checks performed. * * @param chain * certificate chain * @param authType * authentication type */ public void checkClientTrusted(final X509Certificate[] chain, final String authType) { } } /** * Instantiates a JNRPE client. * * @param sJNRPEServerIP * The IP where the JNRPE is installed * @param iJNRPEServerPort * The port where the JNRPE server listens * @param bSSL * <code>true</code> if SSL must be used */ public JNRPEClient(final String sJNRPEServerIP, final int iJNRPEServerPort, final boolean bSSL) { serverIPorURL = sJNRPEServerIP; serverPort = iJNRPEServerPort; useSSL = bSSL; } /** * Creates a custom TrustManager that trusts any certificate. * * @return The custom trustmanager */ private TrustManager getTrustManager() { return TRUSTALL_MGR; } /** * Inovoke a command installed in JNRPE. * * @param sCommandName * The name of the command to be invoked * @param arguments * The arguments to pass to the command (will substitute the * $ARGSx$ parameters) * @return The value returned by the server * @throws JNRPEClientException * Thrown on any communication error. */ public final ReturnValue sendCommand(final String sCommandName, final String... arguments) throws JNRPEClientException { SocketFactory socketFactory; Socket s = null; try { if (!useSSL) { socketFactory = SocketFactory.getDefault(); } else { SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, new TrustManager[] { getTrustManager() }, new SecureRandom()); socketFactory = sslContext.getSocketFactory(); } s = socketFactory.createSocket(); if (weakCipherSuitesEnabled) { SSLSocket ssl = (SSLSocket) s; ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites()); } s.setSoTimeout((int) TimeUnit.SECOND.convert(communicationTimeout)); s.connect(new InetSocketAddress(serverIPorURL, serverPort)); JNRPERequest req = new JNRPERequest(sCommandName, arguments); s.getOutputStream().write(req.toByteArray()); InputStream in = s.getInputStream(); JNRPEResponse res = new JNRPEResponse(in); return new ReturnValue(Status.fromIntValue(res.getResultCode()), res.getMessage()); } catch (RuntimeException re) { throw re; } catch (Exception e) { throw new JNRPEClientException(e); } finally { if (s != null) { try { s.close(); } catch (IOException e) { // Ignore } } } } /** * Sets the connection timeout in seconds. * * @param iTimeout * The new connection timeout. Default : 10 */ public final void setTimeout(final int iTimeout) { communicationTimeout = iTimeout; } /** * Returns the currently configured connection timeout in seconds. * * @return The connection timeout */ public final int getTimeout() { return communicationTimeout; } /** * Configures the command line parser. * * @return The command line parser configuration */ private static Group configureCommandLine() { DefaultOptionBuilder oBuilder = new DefaultOptionBuilder(); ArgumentBuilder aBuilder = new ArgumentBuilder(); GroupBuilder gBuilder = new GroupBuilder(); DefaultOption nosslOption = oBuilder.withLongName("nossl").withShortName("n") .withDescription("Do no use SSL").create(); DefaultOption weakSslOption = oBuilder.withLongName("weakCiherSuites").withShortName("w") .withDescription("Enable weak cipher suites").create(); DefaultOption unknownOption = oBuilder.withLongName("unknown").withShortName("u") .withDescription("Make socket timeouts return an UNKNOWN state instead of CRITICAL").create(); DefaultOption hostOption = oBuilder.withLongName("host").withShortName("H") .withDescription("The address of the host running the JNRPE/NRPE daemon") .withArgument(aBuilder.withName("host").withMinimum(1).withMaximum(1).create()).create(); NumberValidator positiveInt = NumberValidator.getIntegerInstance(); positiveInt.setMinimum(0); DefaultOption portOption = oBuilder.withLongName("port").withShortName("p") .withDescription("The port on which the daemon is running (default=5666)") .withArgument(aBuilder.withName("port").withMinimum(1).withMaximum(1) .withDefault(Long.valueOf(DEFAULT_PORT)).withValidator(positiveInt).create()) .create(); DefaultOption timeoutOption = oBuilder.withLongName("timeout").withShortName("t") .withDescription("Number of seconds before connection times out (default=10)") .withArgument(aBuilder.withName("timeout").withMinimum(1).withMaximum(1) .withDefault(Long.valueOf(DEFAULT_TIMEOUT)).withValidator(positiveInt).create()) .create(); DefaultOption commandOption = oBuilder.withLongName("command").withShortName("c") .withDescription("The name of the command that the remote daemon should run") .withArgument(aBuilder.withName("command").withMinimum(1).withMaximum(1).create()).create(); DefaultOption argsOption = oBuilder.withLongName("arglist").withShortName("a").withDescription( "Optional arguments that should be passed to the command. Multiple arguments should be separated by " + "a space (' '). If provided, this must be the last option supplied on the command line.") .withArgument(aBuilder.withName("arglist").withMinimum(1).create()).create(); DefaultOption helpOption = oBuilder.withLongName("help").withShortName("h") .withDescription("Shows this help").create(); Group executionOption = gBuilder.withOption(nosslOption).withOption(weakSslOption).withOption(unknownOption) .withOption(hostOption).withOption(portOption).withOption(timeoutOption).withOption(commandOption) .withOption(argsOption).create(); return gBuilder.withOption(executionOption).withOption(helpOption).withMinimum(1).withMaximum(1).create(); } /** * Prints the application version. */ private static void printVersion() { System.out.println("jcheck_nrpe version " + JNRPEClient.class.getPackage().getImplementationVersion()); System.out.println("Copyright (c) 2013 Massimiliano Ziccardi"); System.out.println("Licensed under the Apache License, Version 2.0"); System.out.println(); } /** * Prints usage instrunctions and, eventually, an error message about the * latest execution. * * @param e * The exception error */ @SuppressWarnings("unchecked") private static void printUsage(final Exception e) { printVersion(); StringBuilder sbDivider = new StringBuilder("="); if (e != null) { System.out.println(e.getMessage() + "\n"); } HelpFormatter hf = new HelpFormatter(); while (sbDivider.length() < hf.getPageWidth()) { sbDivider.append('='); } // DISPLAY SETTING Set displaySettings = hf.getDisplaySettings(); displaySettings.clear(); displaySettings.add(DisplaySetting.DISPLAY_GROUP_EXPANDED); displaySettings.add(DisplaySetting.DISPLAY_PARENT_CHILDREN); // USAGE SETTING Set usageSettings = hf.getFullUsageSettings(); usageSettings.clear(); usageSettings.add(DisplaySetting.DISPLAY_PARENT_ARGUMENT); usageSettings.add(DisplaySetting.DISPLAY_ARGUMENT_BRACKETED); usageSettings.add(DisplaySetting.DISPLAY_PARENT_CHILDREN); usageSettings.add(DisplaySetting.DISPLAY_GROUP_EXPANDED); hf.setDivider(sbDivider.toString()); hf.setGroup(configureCommandLine()); hf.print(); } /** * Enables weak cipher suites. */ public final void enableWeakCipherSuites() { weakCipherSuitesEnabled = true; } /** * * @param args * command line arguments * - */ public static void main(final String[] args) { Parser parser = new Parser(); parser.setGroup(configureCommandLine()); CommandLine cli = null; try { cli = parser.parse(args); if (cli.hasOption("--help")) { printUsage(null); } //timeoutAsUnknown = cli.hasOption("--unknown"); String sHost = (String) cli.getValue("--host"); final Long port = (Long) cli.getValue("--port", Long.valueOf(DEFAULT_PORT)); String sCommand = (String) cli.getValue("--command", "_NRPE_CHECK"); JNRPEClient client = new JNRPEClient(sHost, port.intValue(), !cli.hasOption("--nossl")); client.setTimeout(((Long) cli.getValue("--timeout", Long.valueOf(DEFAULT_TIMEOUT))).intValue()); if (cli.hasOption("--weakCiherSuites")) { client.enableWeakCipherSuites(); } @SuppressWarnings("unchecked") List<String> argList = cli.getValues("--arglist"); ReturnValue ret = client.sendCommand(sCommand, argList.toArray(new String[argList.size()])); System.out.println(ret.getMessage()); System.exit(ret.getStatus().intValue()); } catch (JNRPEClientException exc) { Status returnStatus; Throwable cause = exc.getCause(); if (cli.hasOption("--unknown") && cause instanceof SocketTimeoutException) { returnStatus = Status.UNKNOWN; } else { returnStatus = Status.CRITICAL; } System.out.println(exc.getMessage()); System.exit(returnStatus.intValue()); } catch (OptionException oe) { printUsage(oe); } } }