Cassifying Zimbra 5: Difference between revisions

(New page: CASIFYING ZIMBRA COLLABORATION SUITE 5 This document allows guiding you in the process of cassifying Zimbra Collaboration Suite 5. Installation of the Cas Client To download the CAS Clien...)
 
No edit summary
 
(16 intermediate revisions by 5 users not shown)
Line 1: Line 1:
CASIFYING ZIMBRA COLLABORATION SUITE 5
{{Archive}}{{Unsupported}}
{{Article Infobox|{{admin}}||{{ZCS 5.0}}|}}
=CASIFYING ZIMBRA COLLABORATION SUITE 5=
This document allows guiding you in the process of cassifying Zimbra Collaboration Suite 5.
This document allows guiding you in the process of cassifying Zimbra Collaboration Suite 5.


Installation of the Cas Client
==Installation of the Cas Client==
To download the CAS Client Java 2.1.0 go to
Download the CAS Client Java 2.1.0 from http://www.yale.edu/tp/cas/cas-client-java-2.1.0/webDoc/ .
"http://www.ja-sig.org/products/cas/downloads/"
Uncompresse the downloaded file: 
# tar xzvf cas-client-java-2.1.0.tar.gz 
Navigate to the casclient jar file ("/cas-client-java-2.1.0 /dist") and copy the file "casclient.jar"
Go to the lib file in Jetty ("/opt/zimbra/jetty/common/lib") and paste the casclient jar file.


Configuration of the Server Zimbra
Untar the downloaded file: 
# tar xzvf cas-client-java-2.1.0.tar.gz 
Then copy the CASclient JAR file to Jetty's lib directory
# cp cas-client-java-2.1.10/dist/casclient.jar /opt/zimbra/jetty/common/lib
 
==Configuration of the Server Zimbra==
Edit the file "zimbra.web.xml.in" (/opt/zimbra/jetty/etc)  
Edit the file "zimbra.web.xml.in" (/opt/zimbra/jetty/etc)  
Add the following information after sections "<filter>" and "<filter-mapping>" and before the first section of "<servlet>" (by adapting them):  
Add the following information after sections "<filter>" and "<filter-mapping>" and before the first section of "<servlet>" (by adapting them):
<pre>
<filter>
  <filter-name>CAS Filter</filter-name>
  <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
  <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
      <param-value>https://casserver.example.com:8443/cas/login</param-value>
  </init-param>
  <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
      <param-value>https://casserver.example.com:8443/cas/proxyValidate</param-value>
  </init-param>
  <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
      <param-value>zimbraserver.example.com:80</param-value>
  </init-param>
</filter>
 
<filter-mapping>
  <filter-name>CAS Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
</pre>
When we use use both CAS-NTLM and Zimbra we encountered a lot of difficulties and freezes, it seems like zimbra made a lot of CAS requests and some doesn't responds, we modifed the filter as :
<pre>
<filter-mapping>
  <filter-name>CAS Filter</filter-name>
  <url-pattern>/preauth.jsp</url-pattern>
</filter-mapping>
</pre>
 
It reduced the CAS integration to the preauth only. If the user try to acces to http://zimbra.server.com/ it will show the standard login page. 
 
//A ScreenShot is missing
//A ScreenShot is missing


Generation of the SSL_Certificate with Java Keytool
==Generation of the SSL_Certificate with Java Keytool==


Important Note: It is necessary to delete the certificate if it already exists by using the following commands:
'''Important Note:''' It is necessary to delete the certificate if it already exists by using the following commands:
#keytool -delete -alias cas -keystore %JAVA_HOME%/jre/lib/security/cacerts
# keytool -delete -alias cas -keystore %JAVA_HOME%/jre/lib/security/cacerts
# Keytool -delete -alias cas -file server.cert  
# Keytool -delete -alias cas -file server.cert  
 
If you have no name of the generated certificate either that these commands do not work well, you can directly delete files ".keystore" (In the directory home of the user: "/root") and "cacerts" (In the directory "/jdk/jre/lib/security")
# rm /opt/java/jre/lib/security/cacerts
# rm /root/.keystore


If you don't know the name of the certificates (or if these commands did not succeed), you can delete the ".keystore" file in root's homedir and "cacerts" files in "/opt/java/jre/lib/security":
# rm /opt/java/jre/lib/security/cacerts
# rm /root/.keystore


Generate the certificate by the following command:
Generate the certificate by the following command:
# keytool -genkey -alias cas -keypass changeit -keyalg RSA
# keytool -genkey -alias cas -keypass changeit -keyalg RSA
Enter ‘changeit’ for the password
Enter ‘changeit’ for the password
Answer the list of questions.  
Answer the list of questions.  
Line 33: Line 68:


Export the certificate you generated from your personal keystore by the following command:
Export the certificate you generated from your personal keystore by the following command:
# keytool -export -alias cas -keypass changeit -file server.cert  
# keytool -export -alias cas -keypass changeit -file server.cert  
Enter ‘changeit’ for the password.
Enter ‘changeit’ for the password.
//A ScreenShot is missing
//A ScreenShot is missing


Import the certificate into Java's keystore with this command:
Import the certificate into Java's keystore with this command:
# keytool -import -alias cas -file server.cert -keypass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts
# keytool -import -alias cas -file server.cert -keypass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts
Enter ‘changeit’ for the password.
Enter ‘changeit’ for the password.
Answer by 'oui' to add the certificate to the keystore.
Answer by 'oui' to add the certificate to the keystore.
Line 44: Line 79:


Validation of the Certificate:
Validation of the Certificate:
Download the class "InstallCert.java" from the link: "http://blogs.sun.com/andreas/resource/InstallCert.java" (Attachements)
Download the class InstallCert.java from http://blogs.sun.com/andreas/resource/InstallCert.java and modify it to comment out some lines :
Add the modifications put in fat by adapting them:
 
//A ScreenShot is missing
<pre>
import java.io.*;
import java.net.URL;
 
import java.security.*;
import java.security.cert.*;
 
import javax.net.ssl.*;
 
public class InstallCert {
 
    public static void main(String[] args) throws Exception {
String host;
int port;
char[] passphrase;
args = new String[1];
args[0]="cas-server:8443";
if (args.length == 1 || args.length == 2) {
    String[] c = args[0].split(":");
    host = c[0];
    port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
    String p = (args.length == 1) ? "changeit" : args[1];
    passphrase = p.toCharArray();
} else {
    System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
    return;
}
//for my windows and java
File file = new File("/opt/zimbra/java/jre/lib/security/cacerts");
// if (!file.isFile()) {
//     char SEP = File.separatorChar;
//  
//     File dir = new File(System.getProperty("java.home") + SEP
//     + "lib" + SEP + "security");
//     file = new File(dir, "jssecacerts");
//     if (!file.isFile()) {
// file = new File(dir, "cacerts");
//     }
// }
System.out.println("Loading KeyStore " + file + "...");
InputStream in = new FileInputStream(file);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(in, passphrase);
in.close();
 
SSLContext context = SSLContext.getInstance("TLS");
TrustManagerFactory tmf =
    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
context.init(null, new TrustManager[] {tm}, null);
SSLSocketFactory factory = context.getSocketFactory();
System.out.println("Opening connection to " + host + ":" + port + "...");
SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
//socket.setSoTimeout(10000);
try {
    System.out.println("Starting SSL handshake...");
    socket.startHandshake();
    socket.close();
    System.out.println();
    System.out.println("No errors, certificate is already trusted");
} catch (SSLException e) {
    System.out.println();
    e.printStackTrace(System.out);
}
 
X509Certificate[] chain = tm.chain;
if (chain == null) {
    System.out.println("Could not obtain server certificate chain");
    return;
}
 
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
 
System.out.println();
System.out.println("Server sent " + chain.length + " certificate(s):");
System.out.println();
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
MessageDigest md5 = MessageDigest.getInstance("MD5");
for (int i = 0; i < chain.length; i++) {
    X509Certificate cert = chain[i];
    System.out.println
    (" " + (i + 1) + " Subject " + cert.getSubjectDN());
    System.out.println("  Issuer  " + cert.getIssuerDN());
    sha1.update(cert.getEncoded());
    System.out.println("  sha1    " + toHexString(sha1.digest()));
    md5.update(cert.getEncoded());
    System.out.println("  md5    " + toHexString(md5.digest()));
    System.out.println();
}
 
System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
String line = reader.readLine().trim();
int k;
try {
    k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
} catch (NumberFormatException e) {
    System.out.println("KeyStore not changed");
    return;
}
 
X509Certificate cert = chain[k];
String alias = host + "-" + (k + 1);
ks.setCertificateEntry(alias, cert);
 
OutputStream out = new FileOutputStream("/opt/zimbra/java/jre/lib/security/cacerts");
ks.store(out, passphrase);
out.close();
 
System.out.println();
System.out.println(cert);
System.out.println();
System.out.println
("Added certificate to keystore 'jssecacerts' using alias '"
+ alias + "'");
String gdzie = System.getProperty("java.home//") +
  "lib//"  + "security";
    System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    System.out.println(gdzie);
   
    }
   
    private static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 3);
for (int b : bytes) {
    b &= 0xff;
    sb.append(Character.forDigit(b >> 4, 16));
    sb.append(Character.forDigit(b & 0xF, 16));
    sb.append(' ');
}
return sb.toString();
    }
 
    private static class SavingTrustManager implements X509TrustManager {
private final X509TrustManager tm;
private X509Certificate[] chain;
SavingTrustManager(X509TrustManager tm) {
    this.tm = tm;
}
   
public X509Certificate[] getAcceptedIssuers() {
    throw new UnsupportedOperationException();
}
   
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
    throw new UnsupportedOperationException();
}
   
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
    this.chain = chain;
    tm.checkServerTrusted(chain, authType);
}
    }
 
}
</pre>


Compile and execute the class downloaded by the commands:
Compile and execute the class downloaded by the commands:
# javac InstallCert.java
# javac InstallCert.java
Launch the CAS Server and execute the following command:
Launch the CAS Server and execute the following command:
# java InstallCert  
# java InstallCert  
//A ScreenShot is missing
//A ScreenShot is missing


Line 58: Line 255:
//A ScreenShot is missing
//A ScreenShot is missing


Execute the zmprov command:
You now need to get the preAuth key :
Launch the Server Zimbra
# su - zimbra
Under the user "zimbra", execute the command:  
# zmprov gdpak your_domain_name
# zmprov gdpak Domaine_Name
 
(This will create a preAuthKey" as this one:
The preAuthKey should look like this: "45a9743161d93f5c2e2194890bca9c1452e45078844ea0134e357709bf11a06f"
"45a9743161d93f5c2e2194890bca9c1452e45078844ea0134e357709bf11a06f")
 
 
You can now modify preauth.jsp:  
# use the preAuthKey you just got for DOMAIN_KEY
# put your own domain name to replace "your_domain_name" (end of file)
 
<pre>
<%@ page import="java.security.InvalidKeyException" %>
<%@ page import="java.security.NoSuchAlgorithmException" %>
<%@ page import="java.security.SecureRandom" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.util.TreeSet" %>
<%@ page import="javax.crypto.Mac" %>
<%@ page import="javax.crypto.SecretKey" %>
<%!
public static final String DOMAIN_KEY =
"45a9743161d93f5c2e2194890bca9c1452e45078844ea0134e357709bf11a06f";
 
 
public static String generateRedirect(HttpServletRequest request, String name) {
    HashMap params = new HashMap();
    String ts = System.currentTimeMillis()+"";
    params.put("account", name);
    params.put("by", "name"); // needs to be part of hmac
    params.put("timestamp", ts);
    params.put("expires", "0"); // means use the default
 
    String preAuth = computePreAuth(params, DOMAIN_KEY);
    return request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/service/preauth/?" +
          "account="+name+
          "&by=name"+
          "&timestamp="+ts+
          "&expires=0"+
          "&preauth="+preAuth;
  }
 
    public static  String computePreAuth(Map params, String key) {
        StringBuffer sb = new StringBuffer();
        for (Iterator it=new TreeMap(params).values().iterator(); it.hasNext();) {
            if (sb.length() > 0) sb.append('|');
            sb.append(it.next());
        }
        return getHmac(sb.toString(), key.getBytes());       
    }
 
    private static String getHmac(String data, byte[] key) {
        try {
            ByteKey bk = new ByteKey(key);
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(bk);
            return toHex(mac.doFinal(data.getBytes()));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("fatal error", e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException("fatal error", e);
        }
    }
 
    static class ByteKey implements SecretKey {
        private byte[] mKey;
 
        ByteKey(byte[] key) {
            mKey = (byte[]) key.clone();;
        }
 
        public byte[] getEncoded() {
            return mKey;
        }


Note:
        public String getAlgorithm() {
To force the execution of the command zmprov you can add the option "-f" and the command will be: zmprov gdpak -f Domaine_Name
            return "HmacSHA1";
        }


        public String getFormat() {
            return "RAW";
        }
  }
    public static String toHex(byte[] data) {
        StringBuilder sb = new StringBuilder(data.length * 2);
        for (int i=0; i<data.length; i++ ) {
          sb.append(Character.forDigit((data[i] & 0xf0) >>> 4, 16));
          sb.append(Character.forDigit(data[i] & 0x0f, 16) );
        }
        return sb.toString();
    }
%><%
String casUser = (String) session.getAttribute
(edu.yale.its.tp.cas.client.filter.CASFilter.CAS_FILTER_USER);
out.println(casUser);
String redirect = generateRedirect(request, casUser+"@your_domain_name");
out.println(redirect);
response.sendRedirect(redirect);
%>
<html>
<head>
<title>Pre-auth redirect</title>
</head>
<body>
You should never see this page.
</body>
</html>
</pre>
Then copy this file to /opt/zimbra/jetty/webapps/zimbra


Configure the page "preauth.jsp" (Attachements):
Under the user "root", copy the page "preauth.jsp" in the directory: "/opt/zimbra/jetty/webapps/zimbra"
Replace the "DOMAIN_KEY" with the key which you produced with the "zmprov" in the previous stage.
//A ScreenShot is missing


It may be necessary to set the values of zimbraWebClientLoginURL and zimbraWebClientLogoutURL to redirect users to the /preauth.jsp page from http(s)://zimbra.server.com/
#zmprov md example.com zimbraWebClientLoginURL https://zimbra.example.com/zimbra/preauth.jsp
#
#zmprov md example.com zimbraWebClientLogoutURL https://cas.example.com/cas/logout


Modify the following lines towards the end of the JSP page, by substituting "domaine-name" by your domain:
//A ScreenShot is missing


Restart Zimbra to identify the new "jar" and the files of configuration:  
Restart Zimbra to identify the new "jar" and the files of configuration:  
# su root
# su - zimbra
# su - zimbra
# zmcontrol stop
# zmcontrol stop
# zmcontrol start
# zmcontrol start
 


Test the Cassified Zimbra’s Server:
Test the Cassified Zimbra’s Server:
Lunch the CAS server  
Launch the CAS server  
Launch Zimbra in the Web browser with the url  
Launch Zimbra in the Web browser with the url  
"http://ecm.ecmteggo.tp/zimbra/preauth.jsp"
"http://ecm.ecmteggo.tp/zimbra/preauth.jsp"
If everything is set up correctly you will be redirected to the CAS server’s login screen.[[Image:Example.jpg]]
If everything is set up correctly you will be redirected to the CAS server’s login screen.[[Image:Example.jpg]]
{{Article_Footer|unknown|3/18/2008}}
[[Category:Certificates]]
[[Category:Clients]]
[[Category:ZCS 5.0]]

Latest revision as of 16:36, 24 March 2015

Admin Article

Article Information

This article applies to the following ZCS versions.

ZCS 5.0 Article ZCS 5.0


CASIFYING ZIMBRA COLLABORATION SUITE 5

This document allows guiding you in the process of cassifying Zimbra Collaboration Suite 5.

Installation of the Cas Client

Download the CAS Client Java 2.1.0 from http://www.yale.edu/tp/cas/cas-client-java-2.1.0/webDoc/ .

Untar the downloaded file:

# tar xzvf cas-client-java-2.1.0.tar.gz   

Then copy the CASclient JAR file to Jetty's lib directory

# cp cas-client-java-2.1.10/dist/casclient.jar /opt/zimbra/jetty/common/lib

Configuration of the Server Zimbra

Edit the file "zimbra.web.xml.in" (/opt/zimbra/jetty/etc) Add the following information after sections "<filter>" and "<filter-mapping>" and before the first section of "<servlet>" (by adapting them):

<filter>
   <filter-name>CAS Filter</filter-name>
   <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
   <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
      <param-value>https://casserver.example.com:8443/cas/login</param-value>
   </init-param>
   <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
      <param-value>https://casserver.example.com:8443/cas/proxyValidate</param-value>
   </init-param>
   <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
      <param-value>zimbraserver.example.com:80</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>CAS Filter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

When we use use both CAS-NTLM and Zimbra we encountered a lot of difficulties and freezes, it seems like zimbra made a lot of CAS requests and some doesn't responds, we modifed the filter as :

<filter-mapping>
   <filter-name>CAS Filter</filter-name>
   <url-pattern>/preauth.jsp</url-pattern>
</filter-mapping>

It reduced the CAS integration to the preauth only. If the user try to acces to http://zimbra.server.com/ it will show the standard login page.

//A ScreenShot is missing

Generation of the SSL_Certificate with Java Keytool

Important Note: It is necessary to delete the certificate if it already exists by using the following commands:

# keytool -delete -alias cas -keystore %JAVA_HOME%/jre/lib/security/cacerts
# Keytool -delete -alias cas -file server.cert 

If you don't know the name of the certificates (or if these commands did not succeed), you can delete the ".keystore" file in root's homedir and "cacerts" files in "/opt/java/jre/lib/security":

# rm /opt/java/jre/lib/security/cacerts 
# rm /root/.keystore 

Generate the certificate by the following command:

# keytool -genkey -alias cas -keypass changeit -keyalg RSA

Enter ‘changeit’ for the password Answer the list of questions. //A ScreenShot is missing

Export the certificate you generated from your personal keystore by the following command:

# keytool -export -alias cas -keypass changeit -file server.cert 

Enter ‘changeit’ for the password. //A ScreenShot is missing

Import the certificate into Java's keystore with this command:

# keytool -import -alias cas -file server.cert -keypass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts

Enter ‘changeit’ for the password. Answer by 'oui' to add the certificate to the keystore. //A ScreenShot is missing

Validation of the Certificate: Download the class InstallCert.java from http://blogs.sun.com/andreas/resource/InstallCert.java and modify it to comment out some lines :

import java.io.*;
import java.net.URL; 

import java.security.*;
import java.security.cert.*;

import javax.net.ssl.*;

public class InstallCert {

    public static void main(String[] args) throws Exception {
	String host;
	int port;
	char[] passphrase;
	args = new String[1];
	args[0]="cas-server:8443";
	if (args.length == 1 || args.length == 2) {
	    String[] c = args[0].split(":");
	    host = c[0];
	    port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
	    String p = (args.length == 1) ? "changeit" : args[1];
	    passphrase = p.toCharArray();
	} else {
	    System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
	    return;
	}
//for my windows and java
	File file = new File("/opt/zimbra/java/jre/lib/security/cacerts");
//	if (!file.isFile()) {
//	    char SEP = File.separatorChar;
//	   
//	    File dir = new File(System.getProperty("java.home") + SEP
//		    + "lib" + SEP + "security");
//	    file = new File(dir, "jssecacerts");
//	    if (!file.isFile()) {
//		file = new File(dir, "cacerts");
//	    }
//	}
	System.out.println("Loading KeyStore " + file + "...");
	InputStream in = new FileInputStream(file);
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
	ks.load(in, passphrase);
	in.close();

	SSLContext context = SSLContext.getInstance("TLS");
	TrustManagerFactory tmf =
	    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
	tmf.init(ks);
	X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
	SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
	context.init(null, new TrustManager[] {tm}, null);
	SSLSocketFactory factory = context.getSocketFactory();
	
	System.out.println("Opening connection to " + host + ":" + port + "...");
	SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
	//socket.setSoTimeout(10000);
	try {
	    System.out.println("Starting SSL handshake...");
	    socket.startHandshake();
	    socket.close();
	    System.out.println();
	    System.out.println("No errors, certificate is already trusted");
	} catch (SSLException e) {
	    System.out.println();
	    e.printStackTrace(System.out);
	}

	X509Certificate[] chain = tm.chain;
	if (chain == null) {
	    System.out.println("Could not obtain server certificate chain");
	    return;
	}

	BufferedReader reader =
		new BufferedReader(new InputStreamReader(System.in));

	System.out.println();
	System.out.println("Server sent " + chain.length + " certificate(s):");
	System.out.println();
	MessageDigest sha1 = MessageDigest.getInstance("SHA1");
	MessageDigest md5 = MessageDigest.getInstance("MD5");
	for (int i = 0; i < chain.length; i++) {
	    X509Certificate cert = chain[i];
	    System.out.println
	    	(" " + (i + 1) + " Subject " + cert.getSubjectDN());
	    System.out.println("   Issuer  " + cert.getIssuerDN());
	    sha1.update(cert.getEncoded());
	    System.out.println("   sha1    " + toHexString(sha1.digest()));
	    md5.update(cert.getEncoded());
	    System.out.println("   md5     " + toHexString(md5.digest()));
	    System.out.println();
	}

	System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
	String line = reader.readLine().trim();
	int k;
	try {
	    k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
	} catch (NumberFormatException e) {
	    System.out.println("KeyStore not changed");
	    return;
	}

	X509Certificate cert = chain[k];
	String alias = host + "-" + (k + 1);
	ks.setCertificateEntry(alias, cert);

	OutputStream out = new FileOutputStream("/opt/zimbra/java/jre/lib/security/cacerts");
	ks.store(out, passphrase);
	out.close();

	System.out.println();
	System.out.println(cert);
	System.out.println();
	System.out.println
		("Added certificate to keystore 'jssecacerts' using alias '"
		+ alias + "'");
	 String gdzie = System.getProperty("java.home//") +
			   "lib//"   + "security";
		    System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
		    System.out.println(gdzie);
		    
    }
    
    private static String toHexString(byte[] bytes) {
	StringBuilder sb = new StringBuilder(bytes.length * 3);
	for (int b : bytes) {
	    b &= 0xff;
	    sb.append(Character.forDigit(b >> 4, 16));
	    sb.append(Character.forDigit(b & 0xF, 16));
	    sb.append(' ');
	}
	return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {
	
	private final X509TrustManager tm;
	private X509Certificate[] chain;
	
	SavingTrustManager(X509TrustManager tm) {
	    this.tm = tm;
	}
    
	public X509Certificate[] getAcceptedIssuers() {
	    throw new UnsupportedOperationException();
	}
    
	public void checkClientTrusted(X509Certificate[] chain, String authType)
		throws CertificateException {
	    throw new UnsupportedOperationException();
	}
    
	public void checkServerTrusted(X509Certificate[] chain, String authType)
		throws CertificateException {
	    this.chain = chain;
	    tm.checkServerTrusted(chain, authType);
	}
    }

}

Compile and execute the class downloaded by the commands:

# javac InstallCert.java

Launch the CAS Server and execute the following command:

# java InstallCert 

//A ScreenShot is missing


Answer the composed question by typing "Enter" //A ScreenShot is missing

You now need to get the preAuth key :

# su - zimbra
# zmprov gdpak your_domain_name

The preAuthKey should look like this: "45a9743161d93f5c2e2194890bca9c1452e45078844ea0134e357709bf11a06f"


You can now modify preauth.jsp:

  1. use the preAuthKey you just got for DOMAIN_KEY
  2. put your own domain name to replace "your_domain_name" (end of file)
<%@ page import="java.security.InvalidKeyException" %>
<%@ page import="java.security.NoSuchAlgorithmException" %>
<%@ page import="java.security.SecureRandom" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.util.TreeSet" %>
<%@ page import="javax.crypto.Mac" %>
<%@ page import="javax.crypto.SecretKey" %>
<%!
 public static final String DOMAIN_KEY =
	"45a9743161d93f5c2e2194890bca9c1452e45078844ea0134e357709bf11a06f";


 public static String generateRedirect(HttpServletRequest request, String name) {
     HashMap params = new HashMap();
     String ts = System.currentTimeMillis()+"";
     params.put("account", name);
     params.put("by", "name"); // needs to be part of hmac
     params.put("timestamp", ts);
     params.put("expires", "0"); // means use the default

     String preAuth = computePreAuth(params, DOMAIN_KEY);
     return request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/service/preauth/?" +
           "account="+name+
           "&by=name"+
           "&timestamp="+ts+
           "&expires=0"+
           "&preauth="+preAuth;
  }

    public static  String computePreAuth(Map params, String key) {
        StringBuffer sb = new StringBuffer();
        for (Iterator it=new TreeMap(params).values().iterator(); it.hasNext();) {
            if (sb.length() > 0) sb.append('|');
            sb.append(it.next());
        }
        return getHmac(sb.toString(), key.getBytes());        
    }

    private static String getHmac(String data, byte[] key) {
        try {
            ByteKey bk = new ByteKey(key);
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(bk);
            return toHex(mac.doFinal(data.getBytes()));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("fatal error", e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException("fatal error", e);
        }
    }

    static class ByteKey implements SecretKey {
        private byte[] mKey;

        ByteKey(byte[] key) {
            mKey = (byte[]) key.clone();;
        }

        public byte[] getEncoded() {
            return mKey;
        }

        public String getAlgorithm() {
            return "HmacSHA1";
        }

        public String getFormat() {
            return "RAW";
        }
   }

    public static String toHex(byte[] data) {
        StringBuilder sb = new StringBuilder(data.length * 2);
        for (int i=0; i<data.length; i++ ) {
           sb.append(Character.forDigit((data[i] & 0xf0) >>> 4, 16));
           sb.append(Character.forDigit(data[i] & 0x0f, 16) );
        }
        return sb.toString();
    }


%><%
String casUser = (String) session.getAttribute
(edu.yale.its.tp.cas.client.filter.CASFilter.CAS_FILTER_USER);
out.println(casUser);
String redirect = generateRedirect(request, casUser+"@your_domain_name");
out.println(redirect);
response.sendRedirect(redirect);

%>
<html>
<head>
<title>Pre-auth redirect</title>
</head>
<body>

You should never see this page.

</body>
</html>

Then copy this file to /opt/zimbra/jetty/webapps/zimbra


It may be necessary to set the values of zimbraWebClientLoginURL and zimbraWebClientLogoutURL to redirect users to the /preauth.jsp page from http(s)://zimbra.server.com/

#zmprov md example.com zimbraWebClientLoginURL https://zimbra.example.com/zimbra/preauth.jsp
#
#zmprov md example.com zimbraWebClientLogoutURL https://cas.example.com/cas/logout


Restart Zimbra to identify the new "jar" and the files of configuration:

# su - zimbra
# zmcontrol stop
# zmcontrol start


Test the Cassified Zimbra’s Server: Launch the CAS server Launch Zimbra in the Web browser with the url "http://ecm.ecmteggo.tp/zimbra/preauth.jsp" If everything is set up correctly you will be redirected to the CAS server’s login screen.File:Example.jpg

Verified Against: unknown Date Created: 3/18/2008
Article ID: https://wiki.zimbra.com/index.php?title=Cassifying_Zimbra_5 Date Modified: 2015-03-24



Try Zimbra

Try Zimbra Collaboration with a 60-day free trial.
Get it now »

Want to get involved?

You can contribute in the Community, Wiki, Code, or development of Zimlets.
Find out more. »

Looking for a Video?

Visit our YouTube channel to get the latest webinars, technology news, product overviews, and so much more.
Go to the YouTube channel »

Jump to: navigation, search