Adding cert-lockdown on https admin interface

Minor patch below which lets one lock down the admin https connection with certs explicitly. If not set - defaults to current behaviour (and existing normal trust stores).

Below is against -release.

Dw.

diff -r -c openfire_src.orig/src/java/org/jivesoftware/openfire/container/AdminConsolePlug in.java openfire_src/src/java/org/jivesoftware/openfire/container/AdminConsolePlugin.ja va

*** openfire_src.orig/src/java/org/jivesoftware/openfire/container/AdminConsolePlug in.java Fri Nov 21 19:53:55 2008

— openfire_src/src/java/org/jivesoftware/openfire/container/AdminConsolePlugin.ja va Mon Dec 29 22:48:30 2008


*** 95,121 ****

// Create a connector for https traffic if it’s enabled.

sslEnabled = false;

try {

! if (adminSecurePort > 0 && CertificateManager.isRSACertificate(SSLConfig.getKeyStore(), “*”))

{

! if (!CertificateManager.isRSACertificate(SSLConfig.getKeyStore(),

! XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {

! Log.warn(“Admin console: Using RSA certificates but they are not valid for the hosted domain”);

}

JiveSslConnector httpsConnector = new JiveSslConnector();

String bindInterface = getBindInterface();

httpsConnector.setHost(bindInterface);

httpsConnector.setPort(adminSecurePort);

! httpsConnector.setTrustPassword(SSLConfig.gets2sTrustPassword());

httpsConnector.setTruststoreType(SSLConfig.getStoreType());

! httpsConnector.setTruststore(SSLConfig.gets2sTruststoreLocation());

! httpsConnector.setNeedClientAuth(false);

! httpsConnector.setWantClientAuth(false);

! httpsConnector.setKeyPassword(SSLConfig.getKeyPassword());

httpsConnector.setKeystoreType(SSLConfig.getStoreType());

! httpsConnector.setKeystore(SSLConfig.getKeystoreLocation());

adminServer.addConnector(httpsConnector);

sslEnabled = true;

— 95,137 ----

// Create a connector for https traffic if it’s enabled.

sslEnabled = false;

try {

! if (adminSecurePort > 0 && CertificateManager.isRSACertificate(SSLConfig.getAdminKeyStore(), “*”))

{

! String fqdn = XMPPServer.getInstance().getServerInfo().getXMPPDomain();

! if (!CertificateManager.isRSACertificate(SSLConfig.getAdminKeyStore(), fqdn)) {

! Log.warn("Admin console: RSA certificate used for the admin console does " +

! “not match the domain name '”+ fqdn+"’");

}

JiveSslConnector httpsConnector = new JiveSslConnector();

String bindInterface = getBindInterface();

httpsConnector.setHost(bindInterface);

httpsConnector.setPort(adminSecurePort);

! // Only needed if we’re actually checking client certs.

! //

! httpsConnector.setTrustPassword(SSLConfig.getAdminTrustPassword());

httpsConnector.setTruststoreType(SSLConfig.getStoreType());

! httpsConnector.setTruststore(SSLConfig.getAdminTruststoreLocation());

!

! // Set policy for checking client certificates - if any

! String certPol = JiveGlobals.getProperty(“xmpp.socket.ssl.admin.policy”, “disabled”);

! if(certPol.equals(“needed”) || certPol.equals(“enabled”)) {

! httpsConnector.setNeedClientAuth(true);

! httpsConnector.setWantClientAuth(true);

! } else if(certPol.equals(“wanted”)) {

! httpsConnector.setNeedClientAuth(false);

! httpsConnector.setWantClientAuth(true);

! } else {

! httpsConnector.setNeedClientAuth(false);

! httpsConnector.setWantClientAuth(false);

! }

! // Cert used for the actual key

! httpsConnector.setKeyPassword(SSLConfig.getAdminKeyPassword());

httpsConnector.setKeystoreType(SSLConfig.getStoreType());

! httpsConnector.setKeystore(SSLConfig.getAdminKeystoreLocation());

adminServer.addConnector(httpsConnector);

sslEnabled = true;

diff -r -c openfire_src.orig/src/java/org/jivesoftware/openfire/net/SSLConfig.java openfire_src/src/java/org/jivesoftware/openfire/net/SSLConfig.java

*** openfire_src.orig/src/java/org/jivesoftware/openfire/net/SSLConfig.java Fri Nov 21 19:53:56 2008

— openfire_src/src/java/org/jivesoftware/openfire/net/SSLConfig.java Mon Dec 29 22:47:47 2008


*** 49,54 ****

— 49,58 ----

private static String keyStoreLocation;

private static String keypass;

  • private static KeyStore adminKeyStore;
    
  • private static String adminKeyStoreLocation;
    
  • private static String adminkeypass;
    

private static KeyStore s2sTrustStore;

private static String s2sTrustStoreLocation;

private static String s2sTrustpass;


*** 57,62 ****

— 61,69 ----

private static String c2sTrustStoreLocation;

private static String c2sTrustpass;

  • private static KeyStore adminTrustStore;
    
  • private static String adminTrustStoreLocation;
    
  • private static String admintrustpass;
    

private SSLConfig() {

}


*** 68,83 ****

// Get the keystore location. The default location is security/keystore

keyStoreLocation = JiveGlobals.getProperty(“xmpp.socket.ssl.keystore”,

“resources” + File.separator + “security” + File.separator + “keystore”);

  •     keyStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + keyStoreLocation;
    

// Get the keystore password. The default password is “changeit”.

keypass = JiveGlobals.getProperty(“xmpp.socket.ssl.keypass”, “changeit”);

keypass = keypass.trim();

// Get the truststore location for c2s connections

c2sTrustStoreLocation = JiveGlobals.getProperty(“xmpp.socket.ssl.client.truststore”,

“resources” + File.separator + “security” + File.separator + “client.truststore”);

  •     c2sTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + c2sTrustStoreLocation;
    

c2sTrustpass = JiveGlobals.getProperty(“xmpp.socket.ssl.client.trustpass”, “changeit”);

c2sTrustpass = c2sTrustpass.trim();

— 75,97 ----

// Get the keystore location. The default location is security/keystore

keyStoreLocation = JiveGlobals.getProperty(“xmpp.socket.ssl.keystore”,

“resources” + File.separator + “security” + File.separator + “keystore”);

// Get the keystore password. The default password is “changeit”.

keypass = JiveGlobals.getProperty(“xmpp.socket.ssl.keypass”, “changeit”);

keypass = keypass.trim();

  •     // Get the admin keystore location. The default location is the keystore location.
    
  •     adminKeyStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.admin.keystore", keyStoreLocation);
    
  •     // Get the admin keystore password. The default password is that of the keystore location.
    
  •     adminkeypass = JiveGlobals.getProperty("xmpp.socket.ssl.admin.keypass", keypass);
    
  •     adminkeypass = adminkeypass.trim();
    

// Get the truststore location for c2s connections

  • //

c2sTrustStoreLocation = JiveGlobals.getProperty(“xmpp.socket.ssl.client.truststore”,

“resources” + File.separator + “security” + File.separator + “client.truststore”);

c2sTrustpass = JiveGlobals.getProperty(“xmpp.socket.ssl.client.trustpass”, “changeit”);

c2sTrustpass = c2sTrustpass.trim();


*** 85,114 ****

// Get the truststore location for s2s connections

s2sTrustStoreLocation = JiveGlobals.getProperty(“xmpp.socket.ssl.truststore”,

“resources” + File.separator + “security” + File.separator + “truststore”);

  •     s2sTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + s2sTrustStoreLocation;
    

// Get the truststore passwprd; default is “changeit”.

s2sTrustpass = JiveGlobals.getProperty(“xmpp.socket.ssl.trustpass”, “changeit”);

s2sTrustpass = s2sTrustpass.trim();

! // Load s2s keystore and trusstore

try {

keyStore = KeyStore.getInstance(storeType);

keyStore.load(new FileInputStream(keyStoreLocation), keypass.toCharArray());

s2sTrustStore = KeyStore.getInstance(storeType);

s2sTrustStore.load(new FileInputStream(s2sTrustStoreLocation), s2sTrustpass.toCharArray());

!

}

catch (Exception e) {

! Log.error(“SSLConfig startup problem.\n” +

" storeType: [" + storeType + “]\n” +

" keyStoreLocation: [" + keyStoreLocation + “]\n” +

! " keypass: [" + keypass + “]\n” +

" s2sTrustStoreLocation: [" + s2sTrustStoreLocation + “]\n” +

! " s2sTrustpass: [" + s2sTrustpass + “]\n”);

keyStore = null;

s2sTrustStore = null;

s2sFactory = null;

}

— 99,152 ----

// Get the truststore location for s2s connections

s2sTrustStoreLocation = JiveGlobals.getProperty(“xmpp.socket.ssl.truststore”,

“resources” + File.separator + “security” + File.separator + “truststore”);

// Get the truststore passwprd; default is “changeit”.

s2sTrustpass = JiveGlobals.getProperty(“xmpp.socket.ssl.trustpass”, “changeit”);

s2sTrustpass = s2sTrustpass.trim();

! // Get the truststore location for s2s connections - default is same as s2s

! adminTrustStoreLocation = JiveGlobals.getProperty(“xmpp.socket.ssl.admin.truststore”,

! s2sTrustStoreLocation);

!

! // Get the admin truststore passwprd; default is same as s2s.

! admintrustpass = JiveGlobals.getProperty(“xmpp.socket.ssl.admin.trustpass”, s2sTrustpass);

! admintrustpass = admintrustpass.trim();

!

! // Move them relative to the home dir

! keyStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + keyStoreLocation;

! adminKeyStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + adminKeyStoreLocation;

! adminTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + adminTrustStoreLocation;

! s2sTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + s2sTrustStoreLocation;

! c2sTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + c2sTrustStoreLocation;

!

! // Load s2s keystore and trusstores for the normal http and admin http interface

try {

keyStore = KeyStore.getInstance(storeType);

keyStore.load(new FileInputStream(keyStoreLocation), keypass.toCharArray());

  •         adminKeyStore = KeyStore.getInstance(storeType);
    
  •         adminKeyStore.load(new FileInputStream(adminKeyStoreLocation), adminkeypass.toCharArray());
    

s2sTrustStore = KeyStore.getInstance(storeType);

s2sTrustStore.load(new FileInputStream(s2sTrustStoreLocation), s2sTrustpass.toCharArray());

! adminTrustStore = KeyStore.getInstance(storeType);

! adminTrustStore.load(new FileInputStream(adminTrustStoreLocation), admintrustpass.toCharArray());

}

catch (Exception e) {

! Log.error(“SSLConfig startup problem: “+e.getMessage()+”\n” +

" storeType: [" + storeType + “]\n” +

" keyStoreLocation: [" + keyStoreLocation + “]\n” +

! " keypass: [" + _obscure(keypass) + “]\n” +

! " adminKeyStoreLocation: [" + adminKeyStoreLocation + “]\n” +

! " adminkeypass: [" + _obscure(adminkeypass) + “]\n” +

! " adminTrustKeyStoreLocation: [" + adminTrustStoreLocation + “]\n” +

! " admintrustpass: [" + _obscure(admintrustpass) + “]\n” +

" s2sTrustStoreLocation: [" + s2sTrustStoreLocation + “]\n” +

! " s2sTrustpass: [" + _obscure(s2sTrustpass) + “]\n”);

keyStore = null;

  •         adminKeyStore = null;
    
  •         adminTrustStore = null;
    

s2sTrustStore = null;

s2sFactory = null;

}


*** 129,135 ****

c2sTrustStore.load(null, c2sTrustpass.toCharArray());

}

catch (Exception ex) {

! Log.error(“SSLConfig startup problem.\n” +

" storeType: [" + storeType + “]\n” +

" c2sTrustStoreLocation: [" + c2sTrustStoreLocation + “]\n” +

" c2sTrustPass: [" + c2sTrustpass + “]”, e);

— 167,173 ----

c2sTrustStore.load(null, c2sTrustpass.toCharArray());

}

catch (Exception ex) {

! Log.error(“SSLConfig startup problem: “+e.getMessage()+”\n” +

" storeType: [" + storeType + “]\n” +

" c2sTrustStoreLocation: [" + c2sTrustStoreLocation + “]\n” +

" c2sTrustPass: [" + c2sTrustpass + “]”, e);


*** 156,161 ****

— 194,208 ----

});

}

  • private static String _obscure(String s) {
    
  •         String obscure = JiveGlobals.getProperty("xmpp.socket.ssl.showpasswords", "false");
    
  •         if (obscure.equals("true"))
    
  • return s;
    
  •         return "****";
    
  • }
    

private static void resetFactory() {

try {

String algorithm = JiveGlobals.getProperty(“xmpp.socket.ssl.algorithm”, “TLS”);


*** 201,206 ****

— 248,254 ----

" c2sTrustStoreLocation: [" + c2sTrustStoreLocation + “]\n” +

" c2sTrustpass: [" + c2sTrustpass + “]”, e);

keyStore = null;

  •         adminKeyStore = null;
    

s2sTrustStore = null;

c2sTrustStore = null;

s2sFactory = null;


*** 218,223 ****

— 266,289 ----

}

/**

  •  * Get the Admin Key Store password
    
  •  *
    
  •  * @return the key store password
    
  •  */
    
  • public static String getAdminKeyPassword() {
    
  •     return adminkeypass;
    
  • }
    
  • /**
    
  •  * Get the Admin Trust Store password
    
  •  *
    
  •  * @return the trust store password
    
  •  */
    
  • public static String getAdminTrustPassword() {
    
  •     return admintrustpass;
    
  • }
    
  • /**
    
  • Return the Trust Store password for s2s connections.

  • @return the s2s trust store password.


*** 271,276 ****

— 337,365 ----

}

/**

  •  * Get the Admin Key Store
    
  •  *
    
  •  * @return the Key Store
    
  •  */
    
  • public static KeyStore getAdminKeyStore() throws IOException {
    
  •     if (adminKeyStore == null) {
    
  •         throw new IOException();
    
  •     }
    
  •     return adminKeyStore;
    
  • }
    
  • /**
    
  •  * Get the Admin Key Trust Store
    
  •  *
    
  •  * @return the Key Store
    
  •  */
    
  • public static KeyStore getAdminTrustStore() throws IOException {
    
  •     if (adminTrustStore == null) {
    
  •         throw new IOException();
    
  •     }
    
  •     return adminTrustStore;
    
  • }
    
  • /**
    
  • Get the Trust Store for s2s connections

  • @return the s2s Trust Store


*** 296,302 ****

/**

  • Initializes (wipes and recreates) the keystore, and returns the new keystore.

! *

  • @return Newly initialized keystore.

*/

public static KeyStore initializeKeyStore() {

— 385,391 ----

/**

  • Initializes (wipes and recreates) the keystore, and returns the new keystore.

! * @todo Never used ?

  • @return Newly initialized keystore.

*/

public static KeyStore initializeKeyStore() {


*** 369,374 ****

— 458,481 ----

}

/**

  •  * Get the Admin Key Store location
    
  •  *
    
  •  * @return the admin keystore location
    
  •  */
    
  • public static String getAdminKeystoreLocation() {
    
  •     return adminKeyStoreLocation;
    
  • }
    
  • /**
    
  •  * Get the Admin Trust Store location
    
  •  *
    
  •  * @return the admin trust store location
    
  •  */
    
  • public static String getAdminTruststoreLocation() {
    
  •     return adminTrustStoreLocation;
    
  • }
    
  • /**
    
  • Get the s2s Trust Store location

  • @return the s2s Trust Store location

Hi,

Thanks for your contribution, could you please attach your patch as a file and not include it inline.

thanks,

daryl

Apologies - but I kept/keep getting a permission denied ?Perhaps my account is not enabled yet.

In any case - I’ve put a copy on http://www.webweaving.org/tmp/admin.patch2 for now.

Dw

Hi,

I have attached your patch here, so feel free to delete from website. I’ll file this in Jira once I get file attach privs back there

daryl
admin.patch2 (17236 Bytes)