/** * MailArchiver is an application that provides services for storing and managing e-mail messages through a Web Services SOAP interface. * Copyright (C) 2012 Marcio Andre Scholl Levien and Fernando Alberto Reuter Wendt and Jose Ronaldo Nogueira Fonseca Junior * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ /******************************************************************************\ * * This product was developed by * * SERVIÇO FEDERAL DE PROCESSAMENTO DE DADOS (SERPRO), * * a government company established under Brazilian law (5.615/70), * at Department of Development of Porto Alegre. * \******************************************************************************/ package serpro.mailarchiver.util; import java.io.FileReader; import java.io.FilterReader; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import com.sun.jna.Native; import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.Advapi32Util.Account; import com.sun.jna.platform.win32.Shell32; import com.sun.jna.platform.win32.ShlObj; import com.sun.jna.platform.win32.W32Errors; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HRESULT; import org.jvnet.libpam.UnixUser; @Configurable public class SystemAccount { private static final Logger log = Logger.getLocalLogger(); @Autowired private Environment env; private String username; private Path homePath; //-- Windows -- private String sid; private String domain; private Path appDataPath; private Path localAppDataPath; //------------- //--- Unix ---- private int uid; private int gid; //------------- public SystemAccount(HANDLE token) { Account account = Advapi32Util.getTokenAccount(token); username = account.name; sid = account.sidString; domain = account.domain; homePath = getKnownFolderPath(token, ShlObj.CSIDL_PROFILE); appDataPath = getKnownFolderPath(token, ShlObj.CSIDL_APPDATA); localAppDataPath = getKnownFolderPath(token, ShlObj.CSIDL_LOCAL_APPDATA); System.out.printf( "Windows account\n" + "\tsid: %s\n" + "\tusername: %s\n" + "\tdomain: %s\n" + "\thome path: %s\n" + "\tappData path: %s\n" + "\tlocalAppData path: %s\n", sid, username, domain, homePath, appDataPath, localAppDataPath); } public SystemAccount(UnixUser unixUser) { username = unixUser.getUserName(); uid = unixUser.getUID(); gid = unixUser.getGID(); homePath = FileSystems.getDefault().getPath("/home").resolve(username); System.out.printf( "Unix account\n" + "\tuid: %d\n" + "\tgid: %d\n" + "\tusername: %s\n" + "\thome path: %s\n", uid, gid, username, homePath); } private Path getKnownFolderPath(HANDLE token, int folder) { char[] path = new char[WinDef.MAX_PATH]; HRESULT hr = Shell32.INSTANCE.SHGetFolderPath(null, folder, token, ShlObj.SHGFP_TYPE_CURRENT, path); if(hr.equals(W32Errors.S_OK)) { return Paths.get(Native.toString(path)); } else { log.error("getKnownFolderPath {username=%s, csidl=%s} error: %d", username, folder, hr.intValue()); } return null; } public Path getFirefoxProfilesIniPath() { switch(env.getOperatingSystem()) { case WindowsXP: case WindowsVista: case Windows7: return appDataPath .resolve("Mozilla") .resolve("Firefox") .resolve("profiles.ini"); case MacOSX: Path path = homePath .resolve("Library") .resolve("Application Support") .resolve("Firefox") .resolve("profiles.ini"); if(Files.exists(path)) { return path; } return homePath .resolve("Library") .resolve("Mozilla") .resolve("Firefox") .resolve("profiles.ini"); case Linux: return homePath .resolve(".mozilla") .resolve("firefox") .resolve("profiles.ini"); default: return null; } } public Path getThunderbirdProfilesIniPath() { Path path; switch(env.getOperatingSystem()) { case WindowsXP: case WindowsVista: case Windows7: return appDataPath .resolve("Thunderbird") .resolve("profiles.ini"); case MacOSX: path = homePath .resolve("Library") .resolve("Application Support") .resolve("Thunderbird") .resolve("profiles.ini"); if(Files.exists(path)) { return path; } return homePath .resolve("Library") .resolve("Thunderbird") .resolve("profiles.ini"); case Linux: path = homePath .resolve(".thunderbird") .resolve("profiles.ini"); if(Files.exists(path)) { return path; } return homePath .resolve(".mozilla-thunderbird") .resolve("profiles.ini"); default: return null; } } public Path getThunderbirdLocalFoldersPath() { MozillaProfile profile = getDefaultThunderbirdProfile(); Path path; switch(env.getOperatingSystem()) { case WindowsXP: case WindowsVista: case Windows7: if(profile.isRelative()) { return localAppDataPath .resolve("Thunderbird") .resolve(profile.getPathStr()) .resolve("Mail") .resolve("Local Folders"); } else { return Paths.get(profile.getPathStr(), "Mail", "Local Folders"); } case MacOSX: if(profile.isRelative()) { path = homePath .resolve("Library") .resolve("Application Support") .resolve("Thunderbird") .resolve(profile.getPathStr()) .resolve("Mail") .resolve("Local Folders"); if(Files.exists(path)) { return path; } return homePath .resolve("Library") .resolve("Thunderbird") .resolve(profile.getPathStr()) .resolve("Mail") .resolve("Local Folders"); } else { return Paths.get(profile.getPathStr(), "Mail", "Local Folders"); } case Linux: if(profile.isRelative()) { path = homePath .resolve(".thunderbird") .resolve(profile.getPathStr()) .resolve("Mail") .resolve("Local Folders"); if(Files.exists(path)) { return path; } return homePath .resolve(".mozilla-thunderbird") .resolve(profile.getPathStr()) .resolve("Mail") .resolve("Local Folders"); } else { return Paths.get(profile.getPathStr(), "Mail", "Local Folders"); } default: return null; } } public MozillaProfile getDefaultFirefoxProfile() { Path iniPath = getFirefoxProfilesIniPath(); return ((iniPath != null) && Files.isReadable(iniPath)) ? getDefaultMozillaProfile(iniPath) : null; } public List getFirefoxProfiles() { Path iniPath = getFirefoxProfilesIniPath(); return (List) (((iniPath != null) && Files.isReadable(iniPath)) ? getMozillaProfiles(iniPath) : Collections.emptyList()); } public MozillaProfile getDefaultThunderbirdProfile() { Path iniPath = getThunderbirdProfilesIniPath(); return ((iniPath != null) && Files.isReadable(iniPath)) ? getDefaultMozillaProfile(iniPath) : null; } public List getThunderbirdProfiles() { Path iniPath = getThunderbirdProfilesIniPath(); return (List) (((iniPath != null) && Files.isReadable(iniPath)) ? getMozillaProfiles(iniPath) : Collections.emptyList()); } private MozillaProfile getDefaultMozillaProfile(Path iniPath) { Ini ini = null; try { ini = new Ini(iniPath); } catch (IOException ex) { log.error(ex); return null; } Ini.Section section = null; for(Map.Entry entry : ini.entrySet()) { if( ! entry.getKey().startsWith("Profile")) { continue; } section = entry.getValue(); String def = section.get("Default"); if((def != null) && def.equals("1")) { break; } } //se nenhuma seção marcada como default, usa a última, //provavelmente a única if(section != null) { return new MozillaProfile( section.get("Name"), section.get("Path"), section.get("IsRelative").equals("1")); } return null; } private List getMozillaProfiles(Path iniPath) { Ini ini = null; try { ini = new Ini(iniPath); } catch(IOException ex) { log.error(ex); return null; } List profiles = new ArrayList(); for(Map.Entry entry : ini.entrySet()) { if( ! entry.getKey().startsWith("Profile")) { continue; } Ini.Section section = entry.getValue(); profiles.add(new MozillaProfile( section.get("Name"), section.get("Path"), section.get("IsRelative").equals("1"))); } return profiles; } private class Ini extends org.ini4j.Ini { public Ini(Path iniPath) throws IOException { super(new FilterReader(new FileReader(iniPath.toFile())) { @Override public int read(char[] cbuf, int off, int len) throws IOException { // escape '\' // necessario quando o perfil usa um caminho absoluto no Windows // ex: Path=C:\perfis_firefox\perfil_X ==> Path=C:\\perfis_firefox\\perfil_X int c = in.read(); if(c == -1) { return -1; } if(c == '\\') { cbuf[off] = '\\'; cbuf[off + 1] = '\\'; return 2; } else { cbuf[off] = (char) c; return 1; } } }); } } public Path getGearsPath(Browser browser) { OperatingSystem os = env.getOperatingSystem(); MozillaProfile profile; switch(os.id|browser.id) { case 0x501: // Windows7 + InternetExplorer case 0x401: // WindowsVista + InternetExplorer return homePath .resolve("AppData") .resolve("LocalLow") .resolve("Google") .resolve("Google Gears for Internet Explorer"); case 0x301: // WindowsXP + InternetExplorer return localAppDataPath .resolve("Google") .resolve("Google Gears for Internet Explorer"); case 0x502: // Windows7 + Firefox case 0x402: // WindowsVista + Firefox case 0x302: // WindowsXP + Firefox profile = getDefaultFirefoxProfile(); if(profile == null) { return localAppDataPath .resolve("Mozilla") .resolve("Firefox") .resolve("null") .resolve("Google Gears for Firefox"); } if(profile.isRelative()) { return localAppDataPath .resolve("Mozilla") .resolve("Firefox") .resolve(profile.getPathStr()) .resolve("Google Gears for Firefox"); } else { return Paths.get(profile.getPathStr(), "Google Gears for Firefox"); } case 0x503: // Windows7 + Chrome case 0x403: // WindowsVista + Chrome case 0x303: // WindowsXP + Chrome return localAppDataPath .resolve("Google") .resolve("Chrome") .resolve("User Data") .resolve("Default") .resolve("Plugin Data") .resolve("Google Gears"); case 0x202: // MacOSX + Firefox profile = getDefaultFirefoxProfile(); if(profile == null) { return homePath .resolve("Library") .resolve("Caches") .resolve("Firefox") .resolve("null") .resolve("Google Gears for Firefox"); } if(profile.isRelative()) { return homePath .resolve("Library") .resolve("Caches") .resolve("Firefox") .resolve(profile.getPathStr()) .resolve("Google Gears for Firefox"); } else { return Paths.get(profile.getPathStr(), "Google Gears for Firefox"); } case 0x204: // MacOSX + Safari return homePath .resolve("Library") .resolve("Application Support") .resolve("Google") .resolve("Google Gears for Safari"); case 0x102: // Linux + Firefox profile = getDefaultFirefoxProfile(); if(profile == null) { return homePath .resolve(".mozilla") .resolve("firefox") .resolve("null") .resolve("Google Gears for Firefox"); } if(profile.isRelative()) { return homePath .resolve(".mozilla") .resolve("firefox") .resolve(profile.getPathStr()) .resolve("Google Gears for Firefox"); } else { return Paths.get(profile.getPathStr(), "Google Gears for Firefox"); } default: return null; } } public List getFirefoxGearsPaths() { List paths = new ArrayList(); switch(env.getOperatingSystem()) { case Windows7: case WindowsVista: case WindowsXP: for(MozillaProfile profile : getFirefoxProfiles()) { if(profile.isRelative()) { paths.add(localAppDataPath .resolve("Mozilla") .resolve("Firefox") .resolve(profile.getPathStr()) .resolve("Google Gears for Firefox")); } else { paths.add(Paths.get(profile.getPathStr(), "Google Gears for Firefox")); } } return paths; case MacOSX: for(MozillaProfile profile : getFirefoxProfiles()) { if(profile.isRelative()) { paths.add(homePath .resolve("Library") .resolve("Caches") .resolve("Firefox") .resolve(profile.getPathStr()) .resolve("Google Gears for Firefox")); } else { paths.add(Paths.get(profile.getPathStr(), "Google Gears for Firefox")); } } return paths; case Linux: for(MozillaProfile profile : getFirefoxProfiles()) { if(profile.isRelative()) { paths.add(homePath .resolve(".mozilla") .resolve("firefox") .resolve(profile.getPathStr()) .resolve("Google Gears for Firefox")); } else { paths.add(Paths.get(profile.getPathStr(), "Google Gears for Firefox")); } } return paths; default: return null; } } }