/* * Autopsy Forensic Browser * * Copyright 2015 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> org * * 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 org.sleuthkit.autopsy.events; import java.net.URI; import java.net.URISyntaxException; import javax.annotation.concurrent.Immutable; import javax.jms.Connection; import javax.jms.JMSException; import org.apache.activemq.ActiveMQConnectionFactory; import java.io.IOException; import java.net.InetAddress; import java.util.MissingResourceException; import org.openide.util.NbBundle; /** * Connection info for a Java Message Service (JMS) provider. Thread-safe. */ @Immutable public final class MessageServiceConnectionInfo { private static final String MESSAGE_SERVICE_URI = "tcp://%s:%s?wireFormat.maxInactivityDuration=0"; //NON-NLS private static final String CONNECTION_TIMED_OUT = "connection timed out"; //NON-NLS private static final String CONNECTION_REFUSED = "connection refused"; //NON-NLS private static final String PASSWORD_OR_USERNAME_BAD = "user name ["; //NON-NLS private static final int IS_REACHABLE_TIMEOUT_MS = 1000; private final String userName; private final String password; private final String host; private final int port; /** * Constructs an object containing connection info for a Java Message * Service (JMS) provider. * * @param host The host to use for a message service connection. May be * a host name or an IP address. * @param port The port number to use for a message service connection. * @param userName The user name to use for a message service connection. * May be the empty string. * @param password The password to use for a message service connection. May * be the empty string. * */ public MessageServiceConnectionInfo(String host, int port, String userName, String password) { this.host = host; this.port = port; this.userName = userName; this.password = password; } /** * Gets the user name to use for a message service connection. * * @return The user name as a string. May be empty. */ public String getUserName() { return userName; } /** * Gets the password to use for a message service connection. * * @return The password as a string. May be empty. */ public String getPassword() { return password; } /** * Gets the host to use for a message service connection. May be a host name * or an IP address. * * @return The host as a string. */ public String getHost() { return host; } /** * Gets the port number to use for a message service connection. * * @return The port as an int. */ public int getPort() { return port; } /** * Gets the TCP URI to use for a message service connection. * * @return The URI. * * @throws URISyntaxException if the connection info is not for a valid TCP * URI. */ URI getURI() throws URISyntaxException { return new URI(String.format(MESSAGE_SERVICE_URI, getHost(), Integer.toString(getPort()))); } /** * Verifies connection to messaging service. Throws if we cannot communicate * with messaging service. * * When issues occur, it attempts to diagnose them by looking at the * exception messages, returning the appropriate user-facing text for the * exception received. This method expects the Exceptions messages to be in * English and compares against English text. * * @throws org.sleuthkit.autopsy.events.MessageServiceException */ public void tryConnect() throws MessageServiceException { if (host == null || host.isEmpty()) { throw new MessageServiceException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.MissingHostname")); //NON-NLS } else if (userName == null) { throw new MessageServiceException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.MissingUsername")); //NON-NLS } else if (password == null) { throw new MessageServiceException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.MissingPassword")); //NON-NLS } try { ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(getUserName(), getPassword(), getURI()); Connection connection = connectionFactory.createConnection(getUserName(), getPassword()); connection.start(); connection.close(); } catch (URISyntaxException ex) { // The hostname or port seems bad throw new MessageServiceException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.HostnameOrPort")); //NON-NLS } catch (JMSException ex) { String result; Throwable cause = ex.getCause(); if (null != cause && null != cause.getMessage()) { // there is more information from another exception String msg = cause.getMessage(); if (msg.startsWith(CONNECTION_TIMED_OUT)) { // The hostname or IP address seems bad result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Hostname"); //NON-NLS } else if (msg.toLowerCase().startsWith(CONNECTION_REFUSED)) { // The port seems bad result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Port"); //NON-NLS } else if (msg.toLowerCase().startsWith(PASSWORD_OR_USERNAME_BAD)) { // The username or password seems bad result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.UsernameAndPassword"); //NON-NLS } else { // Could be either hostname or port number result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.HostnameOrPort"); //NON-NLS } } else { // there is no more information from another exception try { if (InetAddress.getByName(getHost()).isReachable(IS_REACHABLE_TIMEOUT_MS)) { // if we can reach the host, then it's probably a port problem result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Port"); //NON-NLS } else { result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Hostname"); //NON-NLS } } catch (IOException | MissingResourceException any) { // it may be anything result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Everything"); //NON-NLS } } throw new MessageServiceException(result); } } }