/** * Returns the prefix for all persistently stored properties of the account with the specified id. * * @param bundleContext a currently valid bundle context. * @param accountID the AccountID of the account whose properties we're looking for. * @param sourcePackageName a String containing the package name of the concrete factory class * that extends us. * @return a String indicating the ConfigurationService property name prefix under which all * account properties are stored or null if no account corresponding to the specified id was * found. */ public static String findAccountPrefix( BundleContext bundleContext, AccountID accountID, String sourcePackageName) { ServiceReference confReference = bundleContext.getServiceReference(ConfigurationService.class.getName()); ConfigurationService configurationService = (ConfigurationService) bundleContext.getService(confReference); // first retrieve all accounts that we've registered List<String> storedAccounts = configurationService.getPropertyNamesByPrefix(sourcePackageName, true); // find an account with the corresponding id. for (String accountRootPropertyName : storedAccounts) { // unregister the account in the configuration service. // all the properties must have been registered in the following // hierarchy: // net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME String accountUID = configurationService.getString( accountRootPropertyName // node id + "." + ACCOUNT_UID); // propname if (accountID.getAccountUniqueID().equals(accountUID)) { return accountRootPropertyName; } } return null; }
/** * The method stores the specified account in the configuration service under the package name of * the source factory. The restore and remove account methods are to be used to obtain access to * and control the stored accounts. * * <p>In order to store all account properties, the method would create an entry in the * configuration service corresponding (beginning with) the <tt>sourceFactory</tt>'s package name * and add to it a unique identifier (e.g. the current miliseconds.) * * @param accountID the AccountID corresponding to the account that we would like to store. * @param isModification if <tt>false</tt> there must be no such already loaded account, it * <tt>true</tt> ist modification of an existing account. Usually we use this method with * <tt>false</tt> in method installAccount and with <tt>true</tt> or the overridden method in * method modifyAccount. */ protected void storeAccount(AccountID accountID, boolean isModification) { if (!isModification && getAccountManager().getStoredAccounts().contains(accountID)) { throw new IllegalStateException( "An account for id " + accountID.getUserID() + " was already loaded!"); } try { getAccountManager().storeAccount(this, accountID); } catch (OperationFailedException ofex) { throw new UndeclaredThrowableException(ofex); } }
/** * Saves the password for the specified account after scrambling it a bit so that it is not * visible from first sight (Method remains highly insecure). * * <p>TODO Delegate the implementation to {@link AccountManager} because it knows the format in * which the password (among the other account properties) is to be saved. * * @param bundleContext a currently valid bundle context. * @param accountID the <tt>AccountID</tt> of the account whose password is to be stored * @param password the password to be stored * @throws IllegalArgumentException if no account corresponding to <tt>accountID</tt> has been * previously stored. * @throws OperationFailedException if anything goes wrong while storing the specified * <tt>password</tt> */ protected void storePassword(BundleContext bundleContext, AccountID accountID, String password) throws IllegalArgumentException, OperationFailedException { String accountPrefix = findAccountPrefix(bundleContext, accountID, getFactoryImplPackageName()); if (accountPrefix == null) { throw new IllegalArgumentException( "No previous records found for account ID: " + accountID.getAccountUniqueID() + " in package" + getFactoryImplPackageName()); } CredentialsStorageService credentialsStorage = ServiceUtils.getService(bundleContext, CredentialsStorageService.class); if (!credentialsStorage.storePassword(accountPrefix, password)) { throw new OperationFailedException( "CredentialsStorageService failed to storePassword", OperationFailedException.GENERAL_ERROR); } }
/** * Creates a protocol provider for the given <tt>accountID</tt> and registers it in the bundle * context. This method has a persistent effect. Once created the resulting account will remain * installed until removed through the uninstallAccount method. * * @param accountID the account identifier * @return <tt>true</tt> if the account with the given <tt>accountID</tt> is successfully loaded, * otherwise returns <tt>false</tt> */ public boolean loadAccount(AccountID accountID) { // Need to obtain the original user id property, instead of calling // accountID.getUserID(), because this method could return a modified // version of the user id property. String userID = accountID.getAccountPropertyString(ProtocolProviderFactory.USER_ID); ProtocolProviderService service = createService(userID, accountID); Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put(PROTOCOL, protocolName); properties.put(USER_ID, userID); ServiceRegistration serviceRegistration = bundleContext.registerService(ProtocolProviderService.class.getName(), service, properties); if (serviceRegistration == null) return false; else { synchronized (registeredAccounts) { registeredAccounts.put(accountID, serviceRegistration); } return true; } }
/** * Creates a SSH Session with a remote machine and tries to login according to the details * specified by Contact An appropriate message is shown to the end user in case the login fails * * @param sshContact ID of SSH Contact * @throws JSchException if a JSch is unable to create a SSH Session with the remote machine * @throws InterruptedException if the thread is interrupted before session connected or is timed * out * @throws OperationFailedException if not of above reasons :-) */ public void createSSHSessionAndLogin(ContactSSH sshContact) throws JSchException, OperationFailedException, InterruptedException { logger.info("Creating a new SSH Session to " + sshContact.getHostName()); // creating a new JSch Stack identifier for contact JSch jsch = new JSch(); String knownHosts = (String) accountID.getAccountProperties().get("KNOWN_HOSTS_FILE"); if (!knownHosts.equals("Optional")) jsch.setKnownHosts(knownHosts); String identitiyKey = (String) accountID.getAccountProperties().get("IDENTITY_FILE"); String userName = sshContact.getUserName(); // use the name of system user if the contact has not supplied SSH // details if (userName.equals("")) userName = System.getProperty("user.name"); if (!identitiyKey.equals("Optional")) jsch.addIdentity(identitiyKey); // creating a new session for the contact Session session = jsch.getSession( userName, sshContact.getHostName(), sshContact.getSSHConfigurationForm().getPort()); /** * Creating and associating User Info with the session User Info passes authentication from * sshContact to SSH Stack */ SSHUserInfo sshUserInfo = new SSHUserInfo(sshContact); session.setUserInfo(sshUserInfo); /** initializing the session */ session.connect(connectionTimeout); int count = 0; // wait for session to get connected while (!session.isConnected() && count <= 30000) { Thread.sleep(1000); count += 1000; logger.trace("SSH:" + sshContact.getHostName() + ": Sleep zzz .. "); } // if timeout have exceeded if (count > 30000) { sshContact.setSSHSession(null); JOptionPane.showMessageDialog( null, "SSH Connection attempt to " + sshContact.getHostName() + " timed out"); // error codes are not defined yet throw new OperationFailedException( "SSH Connection attempt to " + sshContact.getHostName() + " timed out", 2); } sshContact.setJSch(jsch); sshContact.setSSHSession(session); logger.info("A new SSH Session to " + sshContact.getHostName() + " Created"); }