Java tutorial
/* * Copyright 1999-2008 University of Chicago * * 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.nimbustools.messaging.gt4_0_elastic.v2008_05_05.security; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.globus.util.Base64; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.CreateKeyPairResponseType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.CreateKeyPairType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DeleteKeyPairResponseType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DeleteKeyPairType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DescribeKeyPairsInfoType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DescribeKeyPairsItemType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DescribeKeyPairsResponseInfoType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DescribeKeyPairsResponseItemType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DescribeKeyPairsResponseType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.DescribeKeyPairsType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.ImportKeyPairResponseType; import org.nimbustools.messaging.gt4_0_elastic.generated.v2010_08_31.ImportKeyPairType; import org.nimbustools.messaging.gt4_0_elastic.v2008_05_05.ServiceSecurity; import org.nimbustools.messaging.gt4_0_elastic.v2008_05_05.rm.ContainerInterface; import org.nimbustools.messaging.gt4_0_elastic.v2008_05_05.service.UnimplementedOperations; import org.nimbustools.messaging.gt4_0_elastic.DisabledException; import org.nimbustools.api.repr.Caller; import org.nimbustools.api.repr.CannotTranslateException; import java.rmi.RemoteException; import java.util.List; import java.util.LinkedList; /** * extends UnimplementedOperations to make sure the unimplemented operations of * the ServiceSecurity interface are covered by some implementation. */ public class ServiceSecurityImpl extends UnimplementedOperations implements ServiceSecurity { // ------------------------------------------------------------------------- // STATIC VARIABLES // ------------------------------------------------------------------------- private static final Log logger = LogFactory.getLog(ServiceSecurityImpl.class.getName()); private static final String FAKE_FINGERPRINT = "N0:KE:YF:IN:GE:RP:RI:NT"; // ------------------------------------------------------------------------- // INSTANCE VARIABLES // ------------------------------------------------------------------------- protected final SSHKeys sshKeys; protected final KeyGen keyGen; protected final ContainerInterface container; // ------------------------------------------------------------------------- // CONSTRUCTORS // ------------------------------------------------------------------------- public ServiceSecurityImpl(SSHKeys sshKeysImpl, KeyGen keyGenImpl, ContainerInterface containerImpl) { if (sshKeysImpl == null) { throw new IllegalArgumentException("sshKeysImpl may not be null"); } this.sshKeys = sshKeysImpl; if (keyGenImpl == null) { throw new IllegalArgumentException("keyGenImpl may not be null"); } this.keyGen = keyGenImpl; if (containerImpl == null) { throw new IllegalArgumentException("containerImpl may not be null"); } this.container = containerImpl; } // ------------------------------------------------------------------------- // *PARTIALLY* implements ServiceSecurity // ------------------------------------------------------------------------- public CreateKeyPairResponseType createKeyPair(CreateKeyPairType req) throws RemoteException { // no use proceeding if these calls fail: final Caller caller = this.container.getCaller(); final String ownerID; try { ownerID = this.container.getOwnerID(caller); } catch (CannotTranslateException e) { throw new RemoteException(e.getMessage(), e); } if (req == null) { throw new RemoteException("createKeyPair request is missing"); } final String input = req.getKeyName(); if (input == null) { throw new RemoteException("createKeyPair request does not contain key name"); } final String splitToken; try { splitToken = this.sshKeys.getSplitToken(); } catch (DisabledException e) { /* If split token method is disabled that means the standard "create keypair serverside" method is enabled. Input field is the requested key name. */ try { // *** EARLY RETURN *** return this.keyGen.createNewKeyPair(caller, input.trim()); } catch (DisabledException e1) { throw new RuntimeException("Both SSH key implementations are disabled?"); } catch (KeyGenException e1) { throw new RemoteException(e1.getMessage(), e1); } } // this is like an 'else' clause, see createNewKeyPair() call return this.splitMethod(splitToken, input, ownerID); } public ImportKeyPairResponseType importKeyPair(ImportKeyPairType req) throws RemoteException { // no use proceeding if these calls fail: final Caller caller = this.container.getCaller(); final String ownerID; try { ownerID = this.container.getOwnerID(caller); } catch (CannotTranslateException e) { throw new RemoteException(e.getMessage(), e); } if (req == null) { throw new RemoteException("key name is missing"); } final String keyName = req.getKeyName(); if (keyName == null) { throw new RemoteException("createKeyPair request does not contain key name"); } final String publicKeyMaterial = req.getPublicKeyMaterial(); if (publicKeyMaterial == null) { throw new RemoteException("key material is missing"); } if (!Base64.isBase64(publicKeyMaterial)) { throw new RemoteException("key material does not appear to " + "be base64 encoded?"); } final byte[] bytes = Base64.decode(publicKeyMaterial.getBytes()); final String keyMaterial = new String(bytes); this.sshKeys.newKey(ownerID, keyName, keyMaterial, FAKE_FINGERPRINT); final ImportKeyPairResponseType resp = new ImportKeyPairResponseType(FAKE_FINGERPRINT, keyName, null); logger.info("SSH key registered, name='" + keyName + "', owner ID='" + ownerID + "'"); return resp; } public DescribeKeyPairsResponseType describeKeyPairs(DescribeKeyPairsType req) throws RemoteException { // no use proceeding if these calls fail: final Caller caller = this.container.getCaller(); final String ownerID; try { ownerID = this.container.getOwnerID(caller); } catch (CannotTranslateException e) { throw new RemoteException(e.getMessage(), e); } if (req == null) { throw new RemoteException("describeKeyPairs request is missing"); } final DescribeKeyPairsInfoType pairsInfoType = req.getKeySet(); final DescribeKeyPairsItemType[] keyPairsItemTypes = pairsInfoType.getItem(); final String[] filterQuery; if (keyPairsItemTypes == null || keyPairsItemTypes.length == 0) { filterQuery = null; } else { filterQuery = new String[keyPairsItemTypes.length]; for (int i = 0; i < keyPairsItemTypes.length; i++) { if (keyPairsItemTypes[i] == null) { throw new RemoteException("describeKeyPairs request is invalid, contains empty element?"); } filterQuery[i] = keyPairsItemTypes[i].getKeyName(); if (filterQuery[i] == null || filterQuery[i].trim().length() == 0) { throw new RemoteException("describeKeyPairs request is invalid, contains empty element?"); } } } if (filterQuery == null) { return this.describeAllPairs(ownerID); } else { return this.describeSomePairs(ownerID, filterQuery); } } public DeleteKeyPairResponseType deleteKeyPair(DeleteKeyPairType req) throws RemoteException { // no use proceeding if these calls fail: final Caller caller = this.container.getCaller(); final String ownerID; try { ownerID = this.container.getOwnerID(caller); } catch (CannotTranslateException e) { throw new RemoteException(e.getMessage(), e); } if (req == null) { throw new RemoteException("deleteKeyPair request is missing"); } final String keyToDelete = req.getKeyName(); final boolean aKeyWasDeleted = this.sshKeys.removeKey(ownerID, keyToDelete); final DeleteKeyPairResponseType dkprt = new DeleteKeyPairResponseType(); dkprt.set_return(aKeyWasDeleted); return dkprt; } // ------------------------------------------------------------------------- // SPLITTING IMPL (PUBKEY ONLY METHOD) // ------------------------------------------------------------------------- protected CreateKeyPairResponseType splitMethod(String splitToken, String input, String ownerID) throws RemoteException { final String err = "Cannot register keypair. Semantics " + "for keypair creation are different than normal, see " + "documentation. " + "(Expecting <keyname>" + splitToken + "<keyvalue>)"; final int idx = input.indexOf(splitToken); if (idx < 1) { // (can't be idx 0 either, there would be no keyname then) throw new RemoteException(err + " (no token '" + splitToken + "')"); } if (input.length() < splitToken.length() + 2) { throw new RemoteException(err + " (token present but " + "name or value is missing)"); } final String givenKeyName = input.substring(0, idx); final int validx = idx + splitToken.length(); final String givenKeyValue = input.substring(validx); final String keyName = givenKeyName.trim(); final String keyValue = givenKeyValue.trim(); if (keyName.length() == 0 || keyValue.length() == 0) { throw new RemoteException(err + " (token present but " + "name or value is missing)"); } final String fingerprint = FAKE_FINGERPRINT; this.sshKeys.newKey(ownerID, keyName, keyValue, fingerprint); final CreateKeyPairResponseType ckprt = new CreateKeyPairResponseType(); ckprt.setKeyFingerprint(fingerprint); ckprt.setKeyName(keyName); ckprt.setKeyMaterial(keyValue); logger.info("SSH key registered, name='" + keyName + "', owner ID='" + ownerID + "'"); return ckprt; } // ------------------------------------------------------------------------- // DESCRIBE IMPL // ------------------------------------------------------------------------- protected DescribeKeyPairsResponseType describeAllPairs(String ownerID) { if (ownerID == null) { throw new IllegalArgumentException("ownerID may not be null"); } final SSHKey[] allKeys = this.sshKeys.getOwnerKeys(ownerID); final List retList = new LinkedList(); for (int i = 0; i < allKeys.length; i++) { final SSHKey key = allKeys[i]; if (key == null) { logger.error("null in allKeys[]"); continue; // *** SKIP *** } final DescribeKeyPairsResponseItemType one = this.getAPair(key); if (one == null) { continue; // *** SKIP *** } retList.add(one); } return convertDKPRTList(retList); } protected DescribeKeyPairsResponseType describeSomePairs(String ownerID, String[] filter) { if (filter == null || filter.length == 0) { throw new IllegalArgumentException("filters may not be null/empty"); } final List retList = new LinkedList(); for (int i = 0; i < filter.length; i++) { if (filter[i] == null || filter[i].trim().length() == 0) { throw new IllegalArgumentException("filters may not have null/empty elements"); } final String keyname = filter[i].trim(); final SSHKey key = this.sshKeys.findKey(ownerID, keyname); if (key == null) { continue; // *** SKIP *** } final DescribeKeyPairsResponseItemType one = this.getAPair(key); if (one == null) { continue; // *** SKIP *** } retList.add(one); } return convertDKPRTList(retList); } protected DescribeKeyPairsResponseItemType getAPair(SSHKey key) { if (key == null) { throw new IllegalArgumentException("key may not be null"); } final DescribeKeyPairsResponseItemType dkprit = new DescribeKeyPairsResponseItemType(); dkprit.setKeyName(key.getKeyName()); dkprit.setKeyFingerprint(key.getFingerprint()); return dkprit; } private static DescribeKeyPairsResponseType convertDKPRTList(List retList) { final DescribeKeyPairsResponseItemType[] rets = (DescribeKeyPairsResponseItemType[]) retList .toArray(new DescribeKeyPairsResponseItemType[retList.size()]); final DescribeKeyPairsResponseInfoType dkprt = new DescribeKeyPairsResponseInfoType(); dkprt.setItem(rets); final DescribeKeyPairsResponseType response = new DescribeKeyPairsResponseType(); response.setKeySet(dkprt); return response; } }