// Java I/O import java.io.*; // The WSDL generated types for messages and components of messages. import edu.isi.www.fedd_types.*; import edu.isi.www.fedd_wsdl.*; // Topdl classes import edu.isi.www.topdl.*; // The fault thrown by failed commands import org.apache.axis.AxisFault; // The ABAC commands throw this import java.security.GeneralSecurityException; // ABAC classes. http://abac.deterlab.net import net.deterlab.abac.*; class Create extends FeddCommand { /** * Read a file into a byte array; used to load the topology file. * @param f the File to read * @throws IOException if there is an error reading the file. */ static public byte[] readNsFile(File f) throws IOException { // This is tedious but straightforward final int bsize = 4096; byte[] buf = new byte[bsize]; byte[] rv = new byte[0]; int r = 0; FileInputStream fs = new FileInputStream(f); while ((r = fs.read(buf)) != -1 ) { byte[] newRv = new byte[rv.length + r]; System.arraycopy(rv, 0, newRv, 0, rv.length); System.arraycopy(buf, 0, newRv, rv.length, r); rv = newRv; } fs.close(); return rv; } /** * Reads a topology file as topdl. If this fails, just return null as * later code will read the file as tcl. * @param f The file to read * @return the TopologyType encoded, or null of unparsable/unreadable * @throws IOException if the file cannot be read */ static public TopologyType readTopdl(File f) throws IOException { try { ParseTopdl p = new ParseTopdl(new FileInputStream(f), "experiment"); return p.getTopology(); } catch (IOException e) { throw e; } catch (Exception e) { return null; } } /** * Create an ABAC credential indicating the the given destination acts for * the given Identity, and attach a certificate to it. * For some reason, the parse doesn't fail silently - something in the * bowels of the XML parser prints an error. Sigh. * @param id the Identity delegating authority * @param dest the destination * @throws IOException an I/O problem, very unlikely * @throws GeneralSecurityException crypto or identity misconfiguration. */ static public Credential delegate(Identity id, String dest) throws IOException,GeneralSecurityException { Credential c = new Credential(new Role(id.getKeyID()+".acting_for"), new Role(dest)); c.make_cert(id); return c; } /** * Create an experiment with the given mnemonic name, from the given tcl * topology file using the given identity certificate, on the given fedd. * Reads the identity and topology into memory and constructs a New request * for an empty experiment and a Create request to actually start it. The * start is asynchronous, so this returns when the creation begins, not * when it completes. */ public static void main(String args[]) throws javax.xml.rpc.ServiceException, java.net.MalformedURLException, java.rmi.RemoteException { // Parse out the args String exptName = "test"; String topoFileName = "./deter-only.tcl"; String certFile = "./emulab.pem"; String urlString = "https://users.isi.deterlab.net:23235"; if (args.length > 0) exptName = args[0]; if (args.length > 1) topoFileName = args[1]; if (args.length > 2) certFile = args[2]; if (args.length > 3) urlString = args[3]; /* * Get the Web Service for users and read the identity and topology */ FeddPortType port = getPort(urlString); File topoFile = new File(topoFileName); Identity AbacID = null; byte[] nsContents = null; TopologyType topo = null; try { if ( (topo = readTopdl(topoFile)) == null) nsContents = readNsFile(topoFile); } catch (IOException e) { System.err.println("Cannot load topology file " + e); System.exit(20); } try { AbacID = new Identity(new File(certFile)); } catch (GeneralSecurityException e) { System.err.println("Error reading ABAC identity " + e); System.err.println("Make sure your certificate (in "+ certFile + ") is self-signed"); System.exit(20); } catch (IOException e) { System.err.println("Cannot load ABAC id from " + certFile + ": " + e); System.exit(20); } /* * Build and send a NewRequestType Message */ NewRequestType newReq = new NewRequestType(null, new IDType(null, null, null, exptName, null), null); NewResponseType newResp = null; try { newResp = port._new(newReq); } catch (AxisFault f) { System.err.println("Error in New: " + f); System.exit(20); } // Parse out the name of the new empty experiment, and start building // the CreateRequestType message. ExperimentLabels newLabels = new ExperimentLabels(newResp.getExperimentID()); CreateRequestType createReq = new CreateRequestType(null, new ExperimentDescriptionType(nsContents, topo), null, new IDType(null, null, null, newLabels.getLocalname(), null), null); CreateResponseType createResp = null; // Reloading the port clears cached SSL connections. port = getPort("https://users.isi.deterlab.net:23235"); // This block creates an ABAC credential telling the fedd that the // experiment we brought to life with the New call above can act with // our authority. We could keep the certificate around for other // commands to use, but once we tell fedd about it, fedd remembers it. // // NB: We have to send both the identity used to sign the credential // and the credential itself, so that fedd can validate it. try { Credential c = null; byte[][] ca = new byte[2][]; ca[0] = AbacID.getCertificate().getEncoded(); // Identity c = delegate(AbacID, newLabels.getFedid()); ca[1] = c.cert().getEncoded(); // Credential createReq.setCredential(ca); } catch (GeneralSecurityException e) { System.err.println("Failed to delegate authority: " + e); System.exit(20); } catch (IOException e) { System.err.println("Failed to delegate authority: ?!!" +e); System.exit(20); } // The create call try { createResp = port.create(createReq); } catch (AxisFault f) { System.err.println("Error in Create: " + f); System.exit(20); } // Tell the user we're underway ExperimentLabels createLabels = new ExperimentLabels(createResp.getExperimentID()); System.out.println("Success: " + createLabels.getLocalname() + " (" + createLabels.getFedid() + ") " + createResp.getExperimentStatus().getValue()); } }