work with Globus certificates
authorAleš Křenek <ljocha@ics.muni.cz>
Wed, 13 May 2009 10:34:20 +0000 (10:34 +0000)
committerAleš Křenek <ljocha@ics.muni.cz>
Wed, 13 May 2009 10:34:20 +0000 (10:34 +0000)
org.glite.lb.client-java/Makefile
org.glite.lb.client-java/examples/SimpleLLTest.java [new file with mode: 0644]
org.glite.lb.client-java/nbproject/project.properties
org.glite.lb.client-java/src/org/glite/lb/ContextLL.java
org.glite.lb.client-java/src/org/glite/lb/ProducerTestLL.java
org.glite.lb.client-java/src/org/glite/lb/SSLSend.java

index f8f0d9c..734707b 100644 (file)
@@ -1,9 +1,28 @@
 -include Makefile.inc
 
+EXAMPLES := SimpleLLTest.class 
+# broken: ProducerTestIL.class ProducerTestLL.class
+
+VPATH := examples
+
+certmanagement_jar := $(shell ls ${jglobus_prefix}/lib/cog-certmanagement-*.jar | sort | tail -1)
+jglobus_jar := $(shell ls ${jglobus_prefix}/lib/cog-jglobus-*.jar | sort | tail -1)
+
 all compile:
-       ${ant_prefix}/bin/ant -Dno.deps=yes -Dreference.jobid-api-java.jar=${stagedir}/share/java/jobid-api-java.jar -DstageDir=${stagedir} 
+       JAVA_HOME=${jdk_prefix} \
+       ${ant_prefix}/bin/ant -Dno.deps=yes -DstageDir=${stagedir} \
+               -Dreference.jobid-api-java.jar=${stagedir}/share/java/jobid-api-java.jar \
+               -Dfile.reference.cog-certmanagement.jar=${certmanagement_jar} \
+               -Dfile.reference.cog-jglobus.jar=${jglobus_jar}
        cd src_c && make PREFIX=${PREFIX}
 
+examples: ${EXAMPLES}
+
+
+${EXAMPLES}: %.class: %.java
+       javac -cp build/classes/:${stagedir}/share/java/jobid-api-java.jar $<
+
+
 check:
        @echo "No check"
 
diff --git a/org.glite.lb.client-java/examples/SimpleLLTest.java b/org.glite.lb.client-java/examples/SimpleLLTest.java
new file mode 100644 (file)
index 0000000..083fea7
--- /dev/null
@@ -0,0 +1,34 @@
+import java.util.Random;
+import org.glite.jobid.Jobid;
+import org.glite.lb.*;
+
+/**
+ * This class shows how to work with ContextLL.
+ * 
+ * @author Pavel Piskac
+ */
+public class SimpleLLTest {
+
+    public static void main(String[] args) {
+
+        Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz:9000/paja6_test2");
+        SeqCode seqCode = new SeqCode();
+        ContextLL ctx = new ContextLL();
+        ctx.setId(new Random().nextInt(99999999));
+        ctx.setSource(1);
+        ctx.setFlag(0);
+        ctx.setHost("pelargir.ics.muni.cz");
+        ctx.setUser("Pavel Piskac");
+        ctx.setSrcInstance("");
+        ctx.setJobid(jobid);
+        ctx.setSeqCode(seqCode);
+        ctx.setTimeout(5);
+        ctx.setAddress("localhost");
+        ctx.setPort(9002);
+        ctx.setPathToCertificate(args[0]);
+        ctx.setPrefix("/tmp/dglog.paja6_testProxy6");
+        EventRunning running = new EventRunning();
+        running.setNode("node");
+        ctx.log(running);
+    }
+}
index 33e3dd9..63edd9f 100755 (executable)
@@ -18,11 +18,12 @@ dist.dir=dist
 dist.jar=${dist.dir}/lb-client-java.jar
 dist.javadoc.dir=${dist.dir}/javadoc
 excludes=
-file.reference.commons-codec-1.3.jar=../commons-codec-1.3.jar
 includes=**
 jar.compress=false
 javac.classpath=\
-    ${reference.jobid-api-java.jar}
+    ${reference.jobid-api-java.jar}:\
+    ${file.reference.cog-certmanagement.jar}:\
+    ${file.reference.cog-jglobus.jar} 
 # Space-separated list of extra javac options
 javac.compilerargs=
 javac.deprecation=false
index 127e0e9..357c86c 100644 (file)
@@ -1,7 +1,6 @@
 package org.glite.lb;
 
 import org.glite.jobid.Jobid;
-import org.glite.jobid.CheckedString;
 
 /** 
  * This class provides sending messages using network sockets.
@@ -16,7 +15,6 @@ public class ContextLL extends Context {
     private int repeatWriteToFile = 5;
     private int timeout = 30000; //in milliseconds
     private String pathToCertificate;
-    private String password;
     private SSLSend sslSend = null;
 
     public ContextLL() {
@@ -43,35 +41,35 @@ public class ContextLL extends Context {
         super(id, source, flag, host, user, prog, srcInstance, jobid);
 
         if (prefix == null) {
-            throw new IllegalArgumentException("ContextProxy prefix");
+            throw new IllegalArgumentException("ContextLL prefix");
         }
         if (address == null) {
-            throw new IllegalArgumentException("ContextProxy socket");
+            throw new IllegalArgumentException("ContextLL socket");
         }
         if (port < 0) {
-            throw new IllegalArgumentException("ContextProxy port");
+            throw new IllegalArgumentException("ContextLL port");
         }
 
-        this.prefix = new CheckedString(prefix).toString();
-        this.address = new CheckedString(address).toString();
+        this.prefix = prefix;
+        this.address = address;
     }
 
     @Override
     public void log(Event event) {
         if (event == null) {
-            throw new IllegalArgumentException("ContextProxy event");
+            throw new IllegalArgumentException("ContextLL event");
         }
 
         if (prefix == null) {
-            throw new IllegalArgumentException("ContextProxy prefix");
+            throw new IllegalArgumentException("ContextLL prefix");
         }
 
         if (address == null) {
-            throw new IllegalArgumentException("ContextProxy socket");
+            throw new IllegalArgumentException("ContextLL socket");
         }
 
         if (port < 0) {
-            throw new IllegalArgumentException("ContextProxy port");
+            throw new IllegalArgumentException("ContextLL port");
         }
 
         if (sslSend == null) {
@@ -83,7 +81,7 @@ public class ContextLL extends Context {
         ILFileWriter.write(prefix, message, repeatWriteToFile);
         
         
-        sslSend.send(pathToCertificate, password, address, port, timeout, message);
+        sslSend.send(pathToCertificate, address, port, timeout, message);
     }
 
     public String getAddress() {
@@ -92,7 +90,7 @@ public class ContextLL extends Context {
 
     public void setAddress(String address) {
         if (address == null) {
-            throw new IllegalArgumentException("ContextProxy address");
+            throw new IllegalArgumentException("ContextLL address");
         }
         
         this.address = address;
@@ -104,7 +102,7 @@ public class ContextLL extends Context {
 
     public void setPort(int port) {
         if (port < 0) {
-            throw new IllegalArgumentException("ContextProxy port");
+            throw new IllegalArgumentException("ContextLL port");
         }
         this.port = port;
     }
@@ -116,7 +114,7 @@ public class ContextLL extends Context {
 
     public void setPrefix(String prefix) {
         if (prefix == null) {
-            throw new IllegalArgumentException("ContextProxy prefix");
+            throw new IllegalArgumentException("ContextLL prefix");
         }
         
         this.prefix = prefix;
@@ -128,7 +126,7 @@ public class ContextLL extends Context {
 
     public void setRepeatWriteToFile(int repeatWriteToFile) {
         if (repeatWriteToFile < 1) {
-            throw new IllegalArgumentException("ContextProxy repeatWriteToFile");
+            throw new IllegalArgumentException("ContextLL repeatWriteToFile");
         }
         
         this.repeatWriteToFile = repeatWriteToFile;
@@ -140,30 +138,18 @@ public class ContextLL extends Context {
 
     public void setTimeout(int timeout) {
         if (timeout < 0) {
-            throw new IllegalArgumentException("ContextProxy timout");
+            throw new IllegalArgumentException("ContextLL timout");
         }
         this.timeout = timeout;
     }
 
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        if (password == null) {
-            throw new IllegalArgumentException("ContextProxy password");
-        }
-        
-        this.password = password;
-    }
-
     public String getPathToCertificate() {
         return pathToCertificate;
     }
 
     public void setPathToCertificate(String pathToCertificate) {
         if (pathToCertificate == null) {
-            throw new IllegalArgumentException("ContextProxy pathToCertificate");
+            throw new IllegalArgumentException("ContextLL pathToCertificate");
         }
         
         this.pathToCertificate = pathToCertificate;
index 4861109..d5d600c 100644 (file)
@@ -4,7 +4,7 @@ import java.util.Random;
 import org.glite.jobid.Jobid;
 
 /**
- * This class shows how to work with ContextLL.
+ * This class shows how to work with ContextIL.
  * 
  * @author Pavel Piskac
  */
@@ -12,7 +12,7 @@ public class ProducerTestLL {
 
     public static void main(String[] args) {
 
-        if (args.length != 13) {
+        if (args.length != 12) {
             System.out.println("How to use test class:\n" +
                     "you have to set 13 arguments in this order, if the choice is optional \"\" or text has to be set:\n" +
                     "1. jobid in format \"https://somewhere:port/unique_part\" (required)\n" +
@@ -25,8 +25,7 @@ public class ProducerTestLL {
                     "8. proxy server address (required)\n" +
                     "9. proxy server port, default value is 9002 (optional)\n" +
                     "10. path to user's certificate (required)\n" + 
-                    "11. password to certificate (required)\n" +
-                    "12. path to directory where will be saved files with logs until inter-logger sends the content.");
+                    "11. path to directory where will be saved files with logs until inter-logger sends the content.");
         } else {
             /* Create new instance of jobid, you can use other constructors too (see org.glite.jobid.api_java.Jobid.java) 
              * Examples:
@@ -51,7 +50,7 @@ public class ProducerTestLL {
              * SeqCode seqCode = new SeqCode();
              * seqCode.getSeqCodeFromString("UI=000001:NS=0000000002:WM=000003:BH=0000000004:" + 
              * "JSS=000005:LM=000006:LRMS=000007:APP=000008:LBS=000009"); 
-             * seqCode.incrementSeqCode(Sources.EDG_WLL_SOURCE_USER_INTERFACE); 
+             * seqCode.incrementSeqCode(Sources.USER_INTERFACE); 
              * resulting sequence code will be 
              * UI=000002:NS=0000000002:WM=000003:BH=0000000004:JSS=000005:LM=000006:LRMS=000007:APP=000008:LBS=000009
              */
@@ -137,19 +136,12 @@ public class ProducerTestLL {
             ctx.setPathToCertificate(args[9]);
             System.out.println("pathToCertificate: " + args[9]);
 
-            /* Password to certificate.
-             * Example: 
-             * ctx.setPassword("MySecretPassword");
-             */
-            ctx.setPassword(args[10]);
-            System.out.println("password: " + args[10]);
-
             /* Path to directory where will be saved files with logs until inter-logger sends 
              * the content.
              * Example: ctx.setPrefix("/home/paja6/tmp/dglog." + jobid.getUnique());
              */
-            ctx.setPrefix(args[11]);
-            System.out.println("prefix: " + args[11]);
+            ctx.setPrefix(args[10]);
+            System.out.println("prefix: " + args[10]);
 
             /* Create new instance of the event which will be logged.
              */
@@ -158,8 +150,8 @@ public class ProducerTestLL {
             /* Set some description for the event.
              * Example: running.setNode("worker node");
              */
-            running.setNode(args[12]);
-            System.out.println("node: " + args[12]);
+            running.setNode(args[11]);
+            System.out.println("node: " + args[11]);
 
             /* And now is the context and event prepared to work.
              * 
index f940cb5..c226140 100644 (file)
@@ -7,8 +7,16 @@ import java.net.Socket;
 import java.security.*;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Enumeration;
+import org.globus.cog.security.cert.request.BouncyCastleOpenSSLKey;
+import org.globus.gsi.GlobusCredential;
+import org.globus.gsi.GlobusCredentialException;
+import org.gridforum.jgss.ExtendedGSSCredential;
+import org.gridforum.jgss.ExtendedGSSManager;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
 
 // http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#SupportClasses
 /**
@@ -18,9 +26,9 @@ import java.util.Enumeration;
  * @author Pavel Piskac
  */
 public class SSLSend {
-    
+
     private static final String EDG_WLL_LOG_SOCKET_HEADER = "DGLOG";
-    
+
     /**
      * Implementation of abstract class X509KeyManager. 
      * It is used to manage X509 certificates which are used to authenticate
@@ -30,34 +38,50 @@ public class SSLSend {
 
         private X509Certificate[] certchain;
         private PrivateKey key;
-    
+
         public MyX509KeyManager(Certificate[] cchain, PrivateKey key) {
             this.certchain = new X509Certificate[cchain.length];
-            System.arraycopy(cchain, 0, this.certchain, 0, cchain.length);
+           System.arraycopy(cchain, 0, this.certchain, 0, cchain.length); 
             this.key = key;
         }
 
-        public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
+        public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket
+socket) {
+            //System.out.println("MyX509KeyManager.chooseClientAlias()");
+            //for (int i = 0; i < keyType.length; i++) {
+                //System.out.println("MyX509KeyManager.chooseClientAlias() keyType[" + i +
+//"]=" + keyType[i]);
+            //}
+            //for (int i = 0; i < issuers.length; i++) {
+                //System.out.println("MyX509KeyManager.chooseClientAlias() issuers[" + i +
+//"]=" + issuers[i]);
+            //}
             return "";
         }
 
-        public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+        public String chooseServerAlias(String keyType, Principal[] issuers, Socket
+socket) {
+            //System.out.println("MyX509KeyManager.chooseServerAlias(" + keyType + ")");
             return null;
         }
 
         public X509Certificate[] getCertificateChain(String alias) {
+            //System.out.println("MyX509KeyManager.getCertificateChain(" + alias + ")");
             return certchain;
         }
 
         public String[] getClientAliases(String keyType, Principal[] issuers) {
+            //System.out.println("MyX509KeyManager.getClientAliases(" + keyType + ")");
             return null;
         }
 
         public PrivateKey getPrivateKey(String alias) {
+            //System.out.println("MyX509KeyManager.getPrivateKey(" + alias + ")");
             return key;
         }
 
         public String[] getServerAliases(String keyType, Principal[] issuers) {
+            //System.out.println("MyX509KeyManager.getServerAliases(" + keyType + ")");
             return null;
         }
     }
@@ -73,10 +97,17 @@ public class SSLSend {
         }
 
         public void checkClientTrusted(X509Certificate[] certs, String authType) {
+            //System.out.println("X509TrustManager.checkClientTrusted(certs["+certs.length+"],"+authType+")");
         }
 
         public void checkServerTrusted(X509Certificate[] certs, String authType) throws
                 CertificateException {
+            //System.out.println("----X509TrustManager.checkServerTrusted-----");
+            //System.out.println("number of certs: "+certs.length+", authType="+authType);
+            //for(int i=0;i<certs.length;i++) {
+            //    System.out.println("cert["+i+"]="+certs[i].getSubjectDN());
+            //}
+            //System.out.println("--------------------------------------------");
         }
     }
 
@@ -85,53 +116,37 @@ public class SSLSend {
      */
     public SSLSend() {
     }
-    
+
     /**
      * This method is used to send messages using a secure socket.
      * 
      * @param keyStoreSender path to user's certificate
-     * @param password password to user's certificate
      * @param host host name
      * @param port port number
      * @param timeout connection timeout
      * @param message message which will be send
      */
-    public void send(String keyStoreSender, String password, String host,
+    public void send(String keyStoreSender, String host,
             int port, int timeout, String message) {
 
         try {
-            KeyStore ks1 = readKeyStore(keyStoreSender, password);
+            TrustManager[] trustAllCerts = new TrustManager[]{new MyX509TrustManager()};
+            X509KeyManager[] myKeyManager = createX509KeyManager(keyStoreSender);
             
-            String alias = null;
-            for (Enumeration e = ks1.aliases(); e.hasMoreElements();) {
-                String a = (String) e.nextElement();
-                if (ks1.isKeyEntry(a)) {
-                    alias = a;
-                }
+            if (myKeyManager == null) {
+                throw new NullPointerException("myKeyManager is null");
             }
-            
-            PrivateKey privateKey = (PrivateKey) ks1.getKey(alias, password.toCharArray());
-            Certificate[] chain = ks1.getCertificateChain(alias);
-            
-            TrustManager[] trustAllCerts = new TrustManager[]{new MyX509TrustManager()};
-            X509KeyManager[] myKeyManager = new X509KeyManager[]{new MyX509KeyManager(chain, privateKey)};
 
             SSLContext sctx = SSLContext.getInstance("SSLv3");
             sctx.init(myKeyManager, trustAllCerts, null);
 
             SSLSocketFactory factory = sctx.getSocketFactory();
-            
+
             connect(factory, host, port, timeout, message);
-        } catch (CertificateException ex) {
-            System.err.println(ex);
         } catch (KeyManagementException ex) {
             System.err.println(ex);
-        } catch (KeyStoreException ex) {
-            System.err.println(ex);
         } catch (NoSuchAlgorithmException ex) {
             System.err.println(ex);
-        } catch (UnrecoverableKeyException ex) {
-            System.err.println(ex);
         } catch (Exception ex) {
             System.err.println(ex);
         }
@@ -158,6 +173,7 @@ public class SSLSend {
             socket.setUseClientMode(true);
 
             socket.setSoTimeout(timeout * 10); //read timeout
+
             socket.connect(new InetSocketAddress(host, port), timeout); //connect timeout
 
             socket.startHandshake();
@@ -166,40 +182,39 @@ public class SSLSend {
             if (sess == null) {
                 throw new NullPointerException("null session");
             }
-          
-           message = message.replaceFirst("DG.LLLID=[0-9]* ", ""); 
-           message = message.replaceFirst("DG.USER=\\x22[a-zA-Z ]*\\x22 ", "");
-            System.out.println(message);
-           osw = new PrintStream(socket.getOutputStream(), false);
+
+            message = message.replaceFirst("DG.LLLID=[0-9]* ", "");
+            message = message.replaceFirst("DG.USER=\\x22[a-zA-Z ]*\\x22 ", "");
+            osw = new PrintStream(socket.getOutputStream(), false);
             osw.print(EDG_WLL_LOG_SOCKET_HEADER);
-           osw.flush();
-           
+            osw.flush();
+
             int messageSize = message.length() + 2;
-           byte revertedInt[] = new byte[4];
-           revertedInt[0] = (byte)(messageSize % 256);
-           messageSize >>= 8;  
-           revertedInt[1] = (byte)(messageSize % 256);
-           messageSize >>= 8;
-           revertedInt[2] = (byte)(messageSize % 256);
-           messageSize >>= 8;
-           revertedInt[3] = (byte)(messageSize); 
-           
+            byte revertedInt[] = new byte[4];
+            revertedInt[0] = (byte) (messageSize % 256);
+            messageSize >>= 8;
+            revertedInt[1] = (byte) (messageSize % 256);
+            messageSize >>= 8;
+            revertedInt[2] = (byte) (messageSize % 256);
+            messageSize >>= 8;
+            revertedInt[3] = (byte) (messageSize);
+
             osw.write(revertedInt, 0, 4);
-           osw.flush(); 
-           
+            osw.flush();
+
             osw.print(message + '\n' + '\0');
-           osw.flush();
+            osw.flush();
         } catch (IOException ex) {
-            System.err.println(ex);
+            ex.printStackTrace();
         } catch (NullPointerException ex) {
-            System.err.println(ex);
+            ex.printStackTrace();
         } finally {
             osw.close();
 
             try {
                 socket.close();
             } catch (IOException ex) {
-                System.err.println(ex);
+                ex.printStackTrace();
             }
         }
     }
@@ -208,29 +223,52 @@ public class SSLSend {
      * This methods reads user's certificate
      * 
      * @param ksfile path to certificate
-     * @param password password to certificate
      * @return instance of KeyStore with certificate
      * @throws java.security.KeyStoreException
      * @throws java.security.cert.CertificateException
      * @throws java.security.NoSuchAlgorithmException
      * @throws java.io.IOException
      */
-    static KeyStore readKeyStore(String ksfile, String password) throws
-            KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
-        
-        String kstype = null;
-        if (ksfile.endsWith(".ks")) {
-            kstype = "JKS";
-        }
-        if (ksfile.endsWith(".p12")) {
-            kstype = "PKCS12";
+    public X509KeyManager[] createX509KeyManager(String ksfile) throws KeyStoreException {
+
+        if (ksfile.endsWith(".pem") || !ksfile.contains(".")) {
+            return readPEM(ksfile);
         }
-        if (kstype == null) {
-            throw new KeyStoreException("Unknown key store");
+
+        throw new KeyStoreException("Unknown key store");
+    }
+
+    public X509KeyManager[] readPEM(String ksfile) {
+        BufferedReader br = null;
+        BufferedInputStream pemFile = null;
+        ByteArrayInputStream bais = null;
+
+        X509KeyManager[] myX509KeyManager = null;
+        
+       try {
+            // read in the credential data
+            File f = new File(ksfile);
+            pemFile = new BufferedInputStream(new FileInputStream(f));
+            byte [] data = new byte[(int)f.length()];
+            pemFile.read(data);
+            
+            GlobusCredential gc = new GlobusCredential(ksfile);
+            Certificate[] cert = gc.getCertificateChain();
+
+            PrivateKey privateKey = gc.getPrivateKey();
+            myX509KeyManager = new X509KeyManager[]{new MyX509KeyManager(cert, privateKey)};
+        } catch (IOException ex) {
+            System.err.println(ex);
+        } catch (GlobusCredentialException ex) {
+            System.err.println(ex);
+        } finally {
+            try {
+                pemFile.close();
+            } catch (IOException ex) {
+                System.err.println(ex);
+            }
         }
 
-        KeyStore store = KeyStore.getInstance(kstype);
-        store.load(new FileInputStream(ksfile), password.toCharArray());
-        return store;
+        return myX509KeyManager;
     }
 }