package es.uji.security.keystore.mozilla; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.Enumeration; import java.util.Properties; import java.util.Vector; import es.uji.security.crypto.config.OS; import es.uji.security.util.RegQuery; /** * * This class represents Mozilla properties and defines methods to get where it is installed, the * profiles that have been defined and the profile user is using now. * * @author PSN */ public class Mozilla { private String _userHome; private String[] _profileDir; private String _userAppDataDir; private String _lockFile, _execName; boolean _linux = false, _windows = false, _mac = false; /** * Base constructor. */ public Mozilla() { _userHome = System.getProperty("user.home"); if (OS.isLinux()) { _profileDir = new String[1]; _profileDir[0] = _userHome + "/.mozilla/firefox/"; _lockFile = ".parentlock"; _linux = true; _execName = "firefox"; } else if (OS.isWindowsUpperEqualToNT()) { RegQuery rq = new RegQuery(); _userAppDataDir = rq.getCurrentUserPersonalFolderPath(); _profileDir = new String[1]; _profileDir[0] = _userAppDataDir + "\\Mozilla\\Firefox\\Profiles\\"; _lockFile = "parent.lock"; _windows = true; _execName = "firefox.exe"; } else if (OS.isMac()) { _profileDir = new String[2]; _profileDir[0] = _userHome + "/.mozilla/firefox/"; _profileDir[1] = _userHome + "/Library/Application Support/Firefox/Profiles/"; _lockFile = ".parentlock"; _mac = true; _execName = "firefox"; } } /** * Get the current user profile being used. * * @return An string with the path or "" if none used. */ public String getCurrentProfiledir() { String res = null, aux = ""; File dir; Vector<String> profiles = getProfiledirs(); for (Enumeration<String> e = profiles.elements(); e.hasMoreElements();) { aux = e.nextElement(); dir = new File(aux + File.separator + _lockFile); if (dir.exists()) { res = aux + File.separator; } } return res; } /** * Get All profile dirs that user has * * * @return A Vector with absolute paths to the profiles. */ public Vector<String> getProfiledirs() { Vector<String> profiles = new Vector<String>(); for (int i = 0; i < _profileDir.length; i++) { File dir = new File(_profileDir[i]); String aux[] = dir.list(); if (aux != null) { for (int j = 0; j < aux.length; j++) { dir = new File(_profileDir[i] + aux[j]); if (dir.isDirectory()) { profiles.add(_profileDir[i] + aux[j]); } } } } return profiles; } /** * Get installed application path for Mozilla Firefox. * * * @return A Stng with the absolute path. */ public String getAbsoluteApplicationPath() { String res = null; if (_windows) { RegQuery r = new RegQuery(); res = r.getAbsoluteApplicationPath(_execName); // Dirty hack to make the applet work on Windows 7 64 bit with 32 bit browsers. // In firefox, the path has a "(",")" characters and them are not allowed by the SunPkcs11 provider configuration parser. // What we do here is to copy the needed dll to the user tmp and load them from there. // References: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6581254 // http://hg.openjdk.java.net/jdk7/build/jdk/file/d4c2d2d72cfc/src/share/classes/sun/security/pkcs11/Config.java if ( System.getProperty("os.arch").equals("x86") && res.indexOf("m Files (x86)") != -1 ) { String strTmpDir= OS.getSystemTmpDir() + "cryptoapplet"; File dir= new File(strTmpDir); if (! dir.exists() && ! new File(strTmpDir).mkdir()) { return null; } String[] libraries= {"softokn3.dll", "nssutil3.dll", "plc4.dll", "nspr4.dll", "mozcrt19.dll"}; try { for (String orig:libraries) { if (new File(res + "\\" + orig).exists()) { OS.copyfile(res + "\\" + orig, strTmpDir + "\\" + orig); } } res= strTmpDir; } catch(Exception ex) { ex.printStackTrace(); return null; } } if (res == null) { String progFiles = System.getenv("ProgramFiles"); String dirs[] = { "\\Mozilla\\ Firefox\\", "\\Mozilla", "\\Firefox", "\\SeaMonkey", "\\mozilla.org\\SeaMonkey" }; for (int i = 0; i < dirs.length; i++) { File f = new File(progFiles + dirs[i]); if (f.exists()) { res= progFiles + dirs[i]; } } } try{ File tmp= new File(res); // Expanding 8.3 directories like foobar~1 res= tmp.getCanonicalPath(); } catch(Exception ex){ ex.printStackTrace(); return null; } } else if (_linux) { try { File f; Properties env = new Properties(); env.load(Runtime.getRuntime().exec("env").getInputStream()); String userPath = (String) env.get("PATH"); String[] pathDirs = userPath.split(":"); for (int i = 0; i < pathDirs.length; i++) { f = new File(pathDirs[i] + File.separator + _execName); if (f.exists()) { res= f.getCanonicalPath().substring(0, f.getCanonicalPath().length() - _execName.length()); } } } catch (Exception e) { return null; } } return res; } public String getPkcs11FilePath() { if (_windows) { return getAbsoluteApplicationPath() + "\\softokn3.dll"; } else if (_linux) { String[] libDirs= OS.getAllSystemLibDirectories(); String dirs[] = { "/usr/lib/nss/libsoftokn3.so", getAbsoluteApplicationPath() + "libsoftokn3.so", "/usr/lib/libsoftokn3.so", "/lib/libsoftokn3.so", "/usr/lib/iceweasel/libsoftokn3.so", "/usr/lib/mozilla//libsoftokn3.so", "/usr/lib/firefox/libsoftokn3.so", "/usr/lib/iceape/libsoftokn3.so", "/usr/lib/seamonkey/libsoftokn3.so" }; String[] allDirs= new String[libDirs.length + dirs.length]; for (int i = 0; i < libDirs.length; i++){ allDirs[i]= libDirs[i] + "/libsoftokn3.so"; } for (int i=libDirs.length; i < libDirs.length + dirs.length; i++){ allDirs[i]= dirs[i-libDirs.length]; } for (int i = 0; i < allDirs.length; i++) { File f = new File(allDirs[i]); System.out.println("Testing with: " + f.getPath()); if (f.exists()) { String res; try { res = new File(allDirs[i]).getCanonicalPath(); } catch (IOException e) { e.printStackTrace(); res = null; } return res; } } } else if (_mac) { String res = null; try { File f = new File("/Applications/Firefox.app/Contents/MacOS/libsoftokn3.dylib"); if (f.exists()) { res = f.getCanonicalPath(); } } catch (IOException e) { res = null; e.printStackTrace(); } return res; } return null; } public ByteArrayInputStream getPkcs11ConfigInputStream() { OS os = new OS(); String _pkcs11file = getPkcs11FilePath(); String _currentprofile = getCurrentProfiledir(); ByteArrayInputStream bais = null; if (OS.isWindowsUpperEqualToNT()) { bais = new ByteArrayInputStream(("name = NSS\r" + "library = " + _pkcs11file + "\r" + "attributes= compatibility" + "\r" + "slot=2\r" + "nssArgs=\"" + "configdir='" + _currentprofile.replace("\\", "/") + "' " + "certPrefix='' " + "keyPrefix='' " + "secmod=' secmod.db' " + "flags=readOnly\"\r").getBytes()); } else if (OS.isLinux() || OS.isMac()) { /* * TODO:With Linux is pending to test what's up with the white spaces in the path. */ bais = new ByteArrayInputStream(("name = NSS\r" + "library = " + _pkcs11file + "\n" + "attributes= compatibility" + "\n" + "slot=2\n" + "nssArgs=\"" + "configdir='" + _currentprofile + "' " + "certPrefix='' " + "keyPrefix='' " + "secmod=' secmod.db' " + "flags=readOnly\"\n").getBytes()); } return bais; } public String getPkcs11InitArgsString() { return "configdir='" + getCurrentProfiledir().replace("\\", "/") + "' certPrefix='' keyPrefix='' secmod='secmod.db' flags="; } public boolean isInitialized() { try { MozillaKeyStore mks = new MozillaKeyStore(); mks.load("".toCharArray()); mks.cleanUp(); return true; } catch (Exception e) { ByteArrayOutputStream os = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(os); e.printStackTrace(ps); String stk = new String(os.toByteArray()); if (stk.indexOf("CKR_USER_TYPE_INVALID") > -1) { return false; } return true; } } public static void main(String[] args){ Mozilla m= new Mozilla(); m.getPkcs11FilePath(); } }