[6380] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[1023] | 2 | package org.openstreetmap.josm.tools;
|
---|
| 3 |
|
---|
[4998] | 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
[13647] | 5 | import static org.openstreetmap.josm.tools.Utils.getSystemEnv;
|
---|
| 6 | import static org.openstreetmap.josm.tools.Utils.getSystemProperty;
|
---|
[4998] | 7 |
|
---|
[6682] | 8 | import java.awt.Desktop;
|
---|
[1023] | 9 | import java.awt.event.KeyEvent;
|
---|
[5850] | 10 | import java.io.BufferedReader;
|
---|
[4153] | 11 | import java.io.File;
|
---|
[1023] | 12 | import java.io.IOException;
|
---|
[13204] | 13 | import java.io.InputStream;
|
---|
[6682] | 14 | import java.net.URI;
|
---|
| 15 | import java.net.URISyntaxException;
|
---|
[7082] | 16 | import java.nio.charset.StandardCharsets;
|
---|
[7314] | 17 | import java.nio.file.Files;
|
---|
[7315] | 18 | import java.nio.file.Path;
|
---|
[7314] | 19 | import java.nio.file.Paths;
|
---|
[12241] | 20 | import java.security.KeyStoreException;
|
---|
| 21 | import java.security.NoSuchAlgorithmException;
|
---|
| 22 | import java.security.cert.CertificateException;
|
---|
| 23 | import java.security.cert.CertificateFactory;
|
---|
| 24 | import java.security.cert.X509Certificate;
|
---|
[6103] | 25 | import java.util.Arrays;
|
---|
[11162] | 26 | import java.util.Locale;
|
---|
[12830] | 27 | import java.util.concurrent.ExecutionException;
|
---|
[1023] | 28 |
|
---|
[6310] | 29 | import org.openstreetmap.josm.Main;
|
---|
[13450] | 30 | import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
|
---|
[12846] | 31 | import org.openstreetmap.josm.spi.preferences.Config;
|
---|
[6310] | 32 |
|
---|
[1023] | 33 | /**
|
---|
[12219] | 34 | * {@code PlatformHook} implementation for Unix systems.
|
---|
| 35 | * @since 1023
|
---|
[2376] | 36 | */
|
---|
[1023] | 37 | public class PlatformHookUnixoid implements PlatformHook {
|
---|
[6070] | 38 |
|
---|
[5994] | 39 | private String osDescription;
|
---|
[6070] | 40 |
|
---|
[4897] | 41 | @Override
|
---|
[12776] | 42 | public Platform getPlatform() {
|
---|
| 43 | return Platform.UNIXOID;
|
---|
| 44 | }
|
---|
| 45 |
|
---|
| 46 | @Override
|
---|
[6443] | 47 | public void preStartupHook() {
|
---|
[9750] | 48 | // See #12022 - Disable GNOME ATK Java wrapper as it causes a lot of serious trouble
|
---|
[13647] | 49 | if ("org.GNOME.Accessibility.AtkWrapper".equals(getSystemProperty("assistive_technologies"))) {
|
---|
[9750] | 50 | System.clearProperty("assistive_technologies");
|
---|
| 51 | }
|
---|
[1169] | 52 | }
|
---|
[4897] | 53 |
|
---|
| 54 | @Override
|
---|
[1169] | 55 | public void openUrl(String url) throws IOException {
|
---|
[12846] | 56 | for (String program : Config.getPref().getList("browser.unix",
|
---|
[6682] | 57 | Arrays.asList("xdg-open", "#DESKTOP#", "$BROWSER", "gnome-open", "kfmclient openURL", "firefox"))) {
|
---|
[1169] | 58 | try {
|
---|
[6682] | 59 | if ("#DESKTOP#".equals(program)) {
|
---|
| 60 | Desktop.getDesktop().browse(new URI(url));
|
---|
| 61 | } else if (program.startsWith("$")) {
|
---|
| 62 | program = System.getenv().get(program.substring(1));
|
---|
| 63 | Runtime.getRuntime().exec(new String[]{program, url});
|
---|
| 64 | } else {
|
---|
| 65 | Runtime.getRuntime().exec(new String[]{program, url});
|
---|
| 66 | }
|
---|
[1169] | 67 | return;
|
---|
[7004] | 68 | } catch (IOException | URISyntaxException e) {
|
---|
[12620] | 69 | Logging.warn(e);
|
---|
[1169] | 70 | }
|
---|
| 71 | }
|
---|
| 72 | }
|
---|
[1023] | 73 |
|
---|
[4897] | 74 | @Override
|
---|
[1169] | 75 | public void initSystemShortcuts() {
|
---|
[8518] | 76 | // CHECKSTYLE.OFF: LineLength
|
---|
[4897] | 77 | // TODO: Insert system shortcuts here. See Windows and especially OSX to see how to.
|
---|
[8513] | 78 | for (int i = KeyEvent.VK_F1; i <= KeyEvent.VK_F12; ++i) {
|
---|
[8518] | 79 | Shortcut.registerSystemShortcut("screen:toogle"+i, tr("reserved"), i, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 80 | .setAutomatic();
|
---|
[8513] | 81 | }
|
---|
[8518] | 82 | Shortcut.registerSystemShortcut("system:reset", tr("reserved"), KeyEvent.VK_DELETE, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 83 | .setAutomatic();
|
---|
| 84 | Shortcut.registerSystemShortcut("system:resetX", tr("reserved"), KeyEvent.VK_BACK_SPACE, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 85 | .setAutomatic();
|
---|
| 86 | // CHECKSTYLE.ON: LineLength
|
---|
[1169] | 87 | }
|
---|
[6920] | 88 |
|
---|
[4897] | 89 | @Override
|
---|
[2376] | 90 | public String getDefaultStyle() {
|
---|
[2371] | 91 | return "javax.swing.plaf.metal.MetalLookAndFeel";
|
---|
| 92 | }
|
---|
[4153] | 93 |
|
---|
[6103] | 94 | /**
|
---|
[10166] | 95 | * Determines if the distribution is Debian or Ubuntu, or a derivative.
|
---|
| 96 | * @return {@code true} if the distribution is Debian, Ubuntu or Mint, {@code false} otherwise
|
---|
| 97 | */
|
---|
| 98 | public static boolean isDebianOrUbuntu() {
|
---|
| 99 | try {
|
---|
| 100 | String dist = Utils.execOutput(Arrays.asList("lsb_release", "-i", "-s"));
|
---|
| 101 | return "Debian".equalsIgnoreCase(dist) || "Ubuntu".equalsIgnoreCase(dist) || "Mint".equalsIgnoreCase(dist);
|
---|
[12830] | 102 | } catch (IOException | ExecutionException | InterruptedException e) {
|
---|
[10627] | 103 | // lsb_release is not available on all Linux systems, so don't log at warning level
|
---|
[12620] | 104 | Logging.debug(e);
|
---|
[10166] | 105 | return false;
|
---|
| 106 | }
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | /**
|
---|
[6850] | 110 | * Get the package name including detailed version.
|
---|
[7314] | 111 | * @param packageNames The possible package names (when a package can have different names on different distributions)
|
---|
[6850] | 112 | * @return The package name and package version if it can be identified, null otherwise
|
---|
[7314] | 113 | * @since 7314
|
---|
[6850] | 114 | */
|
---|
[11747] | 115 | public static String getPackageDetails(String... packageNames) {
|
---|
[6850] | 116 | try {
|
---|
[10378] | 117 | // CHECKSTYLE.OFF: SingleSpaceSeparator
|
---|
[11096] | 118 | boolean dpkg = Paths.get("/usr/bin/dpkg-query").toFile().exists();
|
---|
| 119 | boolean eque = Paths.get("/usr/bin/equery").toFile().exists();
|
---|
| 120 | boolean rpm = Paths.get("/bin/rpm").toFile().exists();
|
---|
[10378] | 121 | // CHECKSTYLE.ON: SingleSpaceSeparator
|
---|
[7349] | 122 | if (dpkg || rpm || eque) {
|
---|
[7314] | 123 | for (String packageName : packageNames) {
|
---|
[10308] | 124 | String[] args;
|
---|
[7314] | 125 | if (dpkg) {
|
---|
| 126 | args = new String[] {"dpkg-query", "--show", "--showformat", "${Architecture}-${Version}", packageName};
|
---|
[7349] | 127 | } else if (eque) {
|
---|
| 128 | args = new String[] {"equery", "-q", "list", "-e", "--format=$fullversion", packageName};
|
---|
[7314] | 129 | } else {
|
---|
| 130 | args = new String[] {"rpm", "-q", "--qf", "%{arch}-%{version}", packageName};
|
---|
| 131 | }
|
---|
[12830] | 132 | try {
|
---|
| 133 | String version = Utils.execOutput(Arrays.asList(args));
|
---|
| 134 | if (version != null && !version.isEmpty()) {
|
---|
| 135 | return packageName + ':' + version;
|
---|
[12239] | 136 | }
|
---|
[12830] | 137 | } catch (ExecutionException e) {
|
---|
| 138 | // Package does not exist, continue
|
---|
| 139 | Logging.trace(e);
|
---|
[7314] | 140 | }
|
---|
| 141 | }
|
---|
[6962] | 142 | }
|
---|
[12830] | 143 | } catch (IOException | InterruptedException e) {
|
---|
[12620] | 144 | Logging.warn(e);
|
---|
[6850] | 145 | }
|
---|
[6962] | 146 | return null;
|
---|
[6850] | 147 | }
|
---|
[6920] | 148 |
|
---|
[6850] | 149 | /**
|
---|
[6103] | 150 | * Get the Java package name including detailed version.
|
---|
| 151 | *
|
---|
| 152 | * Some Java bugs are specific to a certain security update, so in addition
|
---|
| 153 | * to the Java version, we also need the exact package version.
|
---|
| 154 | *
|
---|
[7314] | 155 | * @return The package name and package version if it can be identified, null otherwise
|
---|
[6103] | 156 | */
|
---|
| 157 | public String getJavaPackageDetails() {
|
---|
[13647] | 158 | String home = getSystemProperty("java.home");
|
---|
[10580] | 159 | if (home.contains("java-8-openjdk") || home.contains("java-1.8.0-openjdk")) {
|
---|
| 160 | return getPackageDetails("openjdk-8-jre", "java-1_8_0-openjdk", "java-1.8.0-openjdk");
|
---|
| 161 | } else if (home.contains("java-9-openjdk") || home.contains("java-1.9.0-openjdk")) {
|
---|
[12830] | 162 | return getPackageDetails("openjdk-9-jre", "java-1_9_0-openjdk", "java-1.9.0-openjdk", "java-9-openjdk");
|
---|
[7349] | 163 | } else if (home.contains("icedtea")) {
|
---|
| 164 | return getPackageDetails("icedtea-bin");
|
---|
| 165 | } else if (home.contains("oracle")) {
|
---|
| 166 | return getPackageDetails("oracle-jdk-bin", "oracle-jre-bin");
|
---|
[6103] | 167 | }
|
---|
| 168 | return null;
|
---|
| 169 | }
|
---|
[6920] | 170 |
|
---|
[6850] | 171 | /**
|
---|
| 172 | * Get the Web Start package name including detailed version.
|
---|
| 173 | *
|
---|
[7314] | 174 | * OpenJDK packages are shipped with icedtea-web package,
|
---|
| 175 | * but its version generally does not match main java package version.
|
---|
[6920] | 176 | *
|
---|
[6850] | 177 | * Simply return {@code null} if there's no separate package for Java WebStart.
|
---|
| 178 | *
|
---|
| 179 | * @return The package name and package version if it can be identified, null otherwise
|
---|
| 180 | */
|
---|
| 181 | public String getWebStartPackageDetails() {
|
---|
[7314] | 182 | if (isOpenJDK()) {
|
---|
| 183 | return getPackageDetails("icedtea-netx", "icedtea-web");
|
---|
[6850] | 184 | }
|
---|
| 185 | return null;
|
---|
| 186 | }
|
---|
[6103] | 187 |
|
---|
[10734] | 188 | /**
|
---|
| 189 | * Get the Gnome ATK wrapper package name including detailed version.
|
---|
| 190 | *
|
---|
| 191 | * Debian and Ubuntu derivatives come with a pre-enabled accessibility software
|
---|
| 192 | * completely buggy that makes Swing crash in a lot of different ways.
|
---|
| 193 | *
|
---|
| 194 | * Simply return {@code null} if it's not found.
|
---|
| 195 | *
|
---|
| 196 | * @return The package name and package version if it can be identified, null otherwise
|
---|
| 197 | */
|
---|
| 198 | public String getAtkWrapperPackageDetails() {
|
---|
| 199 | if (isOpenJDK() && isDebianOrUbuntu()) {
|
---|
| 200 | return getPackageDetails("libatk-wrapper-java");
|
---|
| 201 | }
|
---|
| 202 | return null;
|
---|
| 203 | }
|
---|
| 204 |
|
---|
[12219] | 205 | private String buildOSDescription() {
|
---|
[13647] | 206 | String osName = getSystemProperty("os.name");
|
---|
[5850] | 207 | if ("Linux".equalsIgnoreCase(osName)) {
|
---|
| 208 | try {
|
---|
[8540] | 209 | // Try lsb_release (only available on LSB-compliant Linux systems,
|
---|
| 210 | // see https://www.linuxbase.org/lsb-cert/productdir.php?by_prod )
|
---|
[12411] | 211 | String line = exec("lsb_release", "-ds");
|
---|
[12217] | 212 | if (line != null && !line.isEmpty()) {
|
---|
| 213 | line = line.replaceAll("\"+", "");
|
---|
| 214 | line = line.replaceAll("NAME=", ""); // strange code for some Gentoo's
|
---|
| 215 | if (line.startsWith("Linux ")) // e.g. Linux Mint
|
---|
| 216 | return line;
|
---|
| 217 | else if (!line.isEmpty())
|
---|
| 218 | return "Linux " + line;
|
---|
[5850] | 219 | }
|
---|
| 220 | } catch (IOException e) {
|
---|
[12620] | 221 | Logging.debug(e);
|
---|
[5877] | 222 | // Non LSB-compliant Linux system. List of common fallback release files: http://linuxmafia.com/faq/Admin/release-files.html
|
---|
| 223 | for (LinuxReleaseInfo info : new LinuxReleaseInfo[]{
|
---|
| 224 | new LinuxReleaseInfo("/etc/lsb-release", "DISTRIB_DESCRIPTION", "DISTRIB_ID", "DISTRIB_RELEASE"),
|
---|
| 225 | new LinuxReleaseInfo("/etc/os-release", "PRETTY_NAME", "NAME", "VERSION"),
|
---|
| 226 | new LinuxReleaseInfo("/etc/arch-release"),
|
---|
| 227 | new LinuxReleaseInfo("/etc/debian_version", "Debian GNU/Linux "),
|
---|
| 228 | new LinuxReleaseInfo("/etc/fedora-release"),
|
---|
| 229 | new LinuxReleaseInfo("/etc/gentoo-release"),
|
---|
[7314] | 230 | new LinuxReleaseInfo("/etc/redhat-release"),
|
---|
| 231 | new LinuxReleaseInfo("/etc/SuSE-release")
|
---|
[5877] | 232 | }) {
|
---|
| 233 | String description = info.extractDescription();
|
---|
| 234 | if (description != null && !description.isEmpty()) {
|
---|
| 235 | return "Linux " + description;
|
---|
| 236 | }
|
---|
| 237 | }
|
---|
[5850] | 238 | }
|
---|
| 239 | }
|
---|
| 240 | return osName;
|
---|
| 241 | }
|
---|
[6070] | 242 |
|
---|
[5994] | 243 | @Override
|
---|
| 244 | public String getOSDescription() {
|
---|
| 245 | if (osDescription == null) {
|
---|
| 246 | osDescription = buildOSDescription();
|
---|
| 247 | }
|
---|
| 248 | return osDescription;
|
---|
| 249 | }
|
---|
[6070] | 250 |
|
---|
[12219] | 251 | private static class LinuxReleaseInfo {
|
---|
[5877] | 252 | private final String path;
|
---|
| 253 | private final String descriptionField;
|
---|
| 254 | private final String idField;
|
---|
| 255 | private final String releaseField;
|
---|
| 256 | private final boolean plainText;
|
---|
| 257 | private final String prefix;
|
---|
[6070] | 258 |
|
---|
[12219] | 259 | LinuxReleaseInfo(String path, String descriptionField, String idField, String releaseField) {
|
---|
[5877] | 260 | this(path, descriptionField, idField, releaseField, false, null);
|
---|
| 261 | }
|
---|
| 262 |
|
---|
[12219] | 263 | LinuxReleaseInfo(String path) {
|
---|
[5877] | 264 | this(path, null, null, null, true, null);
|
---|
| 265 | }
|
---|
| 266 |
|
---|
[12219] | 267 | LinuxReleaseInfo(String path, String prefix) {
|
---|
[5877] | 268 | this(path, null, null, null, true, prefix);
|
---|
| 269 | }
|
---|
[6070] | 270 |
|
---|
[5877] | 271 | private LinuxReleaseInfo(String path, String descriptionField, String idField, String releaseField, boolean plainText, String prefix) {
|
---|
| 272 | this.path = path;
|
---|
| 273 | this.descriptionField = descriptionField;
|
---|
| 274 | this.idField = idField;
|
---|
| 275 | this.releaseField = releaseField;
|
---|
| 276 | this.plainText = plainText;
|
---|
| 277 | this.prefix = prefix;
|
---|
| 278 | }
|
---|
| 279 |
|
---|
[12219] | 280 | @Override
|
---|
| 281 | public String toString() {
|
---|
[6070] | 282 | return "ReleaseInfo [path=" + path + ", descriptionField=" + descriptionField +
|
---|
[8846] | 283 | ", idField=" + idField + ", releaseField=" + releaseField + ']';
|
---|
[5877] | 284 | }
|
---|
[6070] | 285 |
|
---|
[5877] | 286 | /**
|
---|
| 287 | * Extracts OS detailed information from a Linux release file (/etc/xxx-release)
|
---|
| 288 | * @return The OS detailed information, or {@code null}
|
---|
| 289 | */
|
---|
| 290 | public String extractDescription() {
|
---|
| 291 | String result = null;
|
---|
| 292 | if (path != null) {
|
---|
[7315] | 293 | Path p = Paths.get(path);
|
---|
[11096] | 294 | if (p.toFile().exists()) {
|
---|
[7315] | 295 | try (BufferedReader reader = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {
|
---|
[5877] | 296 | String id = null;
|
---|
| 297 | String release = null;
|
---|
| 298 | String line;
|
---|
| 299 | while (result == null && (line = reader.readLine()) != null) {
|
---|
| 300 | if (line.contains("=")) {
|
---|
| 301 | String[] tokens = line.split("=");
|
---|
| 302 | if (tokens.length >= 2) {
|
---|
| 303 | // Description, if available, contains exactly what we need
|
---|
| 304 | if (descriptionField != null && descriptionField.equalsIgnoreCase(tokens[0])) {
|
---|
| 305 | result = Utils.strip(tokens[1]);
|
---|
| 306 | } else if (idField != null && idField.equalsIgnoreCase(tokens[0])) {
|
---|
| 307 | id = Utils.strip(tokens[1]);
|
---|
| 308 | } else if (releaseField != null && releaseField.equalsIgnoreCase(tokens[0])) {
|
---|
| 309 | release = Utils.strip(tokens[1]);
|
---|
| 310 | }
|
---|
| 311 | }
|
---|
| 312 | } else if (plainText && !line.isEmpty()) {
|
---|
| 313 | // Files composed of a single line
|
---|
| 314 | result = Utils.strip(line);
|
---|
| 315 | }
|
---|
| 316 | }
|
---|
| 317 | // If no description has been found, try to rebuild it with "id" + "release" (i.e. "name" + "version")
|
---|
| 318 | if (result == null && id != null && release != null) {
|
---|
[8846] | 319 | result = id + ' ' + release;
|
---|
[5877] | 320 | }
|
---|
| 321 | } catch (IOException e) {
|
---|
| 322 | // Ignore
|
---|
[12620] | 323 | Logging.trace(e);
|
---|
[5877] | 324 | }
|
---|
| 325 | }
|
---|
| 326 | }
|
---|
| 327 | // Append prefix if any
|
---|
| 328 | if (result != null && !result.isEmpty() && prefix != null && !prefix.isEmpty()) {
|
---|
| 329 | result = prefix + result;
|
---|
| 330 | }
|
---|
[8510] | 331 | if (result != null)
|
---|
| 332 | result = result.replaceAll("\"+", "");
|
---|
[5877] | 333 | return result;
|
---|
| 334 | }
|
---|
| 335 | }
|
---|
[6920] | 336 |
|
---|
[11162] | 337 | /**
|
---|
| 338 | * Get the dot directory <code>~/.josm</code>.
|
---|
| 339 | * @return the dot directory
|
---|
| 340 | */
|
---|
[11218] | 341 | private static File getDotDirectory() {
|
---|
[11162] | 342 | String dirName = "." + Main.pref.getJOSMDirectoryBaseName().toLowerCase(Locale.ENGLISH);
|
---|
[13647] | 343 | return new File(getSystemProperty("user.home"), dirName);
|
---|
[11162] | 344 | }
|
---|
| 345 |
|
---|
| 346 | /**
|
---|
| 347 | * Returns true if the dot directory should be used for storing preferences,
|
---|
| 348 | * cache and user data.
|
---|
| 349 | * Currently this is the case, if the dot directory already exists.
|
---|
| 350 | * @return true if the dot directory should be used
|
---|
| 351 | */
|
---|
[11613] | 352 | private static boolean useDotDirectory() {
|
---|
[11162] | 353 | return getDotDirectory().exists();
|
---|
| 354 | }
|
---|
| 355 |
|
---|
[7206] | 356 | @Override
|
---|
[7829] | 357 | public File getDefaultCacheDirectory() {
|
---|
[11162] | 358 | if (useDotDirectory()) {
|
---|
| 359 | return new File(getDotDirectory(), "cache");
|
---|
| 360 | } else {
|
---|
[13647] | 361 | String xdgCacheDir = getSystemEnv("XDG_CACHE_HOME");
|
---|
[11162] | 362 | if (xdgCacheDir != null && !xdgCacheDir.isEmpty()) {
|
---|
| 363 | return new File(xdgCacheDir, Main.pref.getJOSMDirectoryBaseName());
|
---|
| 364 | } else {
|
---|
[13647] | 365 | return new File(getSystemProperty("user.home") + File.separator +
|
---|
[11162] | 366 | ".cache" + File.separator + Main.pref.getJOSMDirectoryBaseName());
|
---|
| 367 | }
|
---|
| 368 | }
|
---|
[7829] | 369 | }
|
---|
[7831] | 370 |
|
---|
| 371 | @Override
|
---|
| 372 | public File getDefaultPrefDirectory() {
|
---|
[11162] | 373 | if (useDotDirectory()) {
|
---|
| 374 | return getDotDirectory();
|
---|
| 375 | } else {
|
---|
[13647] | 376 | String xdgConfigDir = getSystemEnv("XDG_CONFIG_HOME");
|
---|
[11162] | 377 | if (xdgConfigDir != null && !xdgConfigDir.isEmpty()) {
|
---|
| 378 | return new File(xdgConfigDir, Main.pref.getJOSMDirectoryBaseName());
|
---|
| 379 | } else {
|
---|
[13647] | 380 | return new File(getSystemProperty("user.home") + File.separator +
|
---|
[11162] | 381 | ".config" + File.separator + Main.pref.getJOSMDirectoryBaseName());
|
---|
| 382 | }
|
---|
| 383 | }
|
---|
[7831] | 384 | }
|
---|
[7834] | 385 |
|
---|
| 386 | @Override
|
---|
| 387 | public File getDefaultUserDataDirectory() {
|
---|
[11162] | 388 | if (useDotDirectory()) {
|
---|
| 389 | return getDotDirectory();
|
---|
| 390 | } else {
|
---|
[13647] | 391 | String xdgDataDir = getSystemEnv("XDG_DATA_HOME");
|
---|
[11162] | 392 | if (xdgDataDir != null && !xdgDataDir.isEmpty()) {
|
---|
| 393 | return new File(xdgDataDir, Main.pref.getJOSMDirectoryBaseName());
|
---|
| 394 | } else {
|
---|
[13647] | 395 | return new File(getSystemProperty("user.home") + File.separator +
|
---|
[11162] | 396 | ".local" + File.separator + "share" + File.separator + Main.pref.getJOSMDirectoryBaseName());
|
---|
| 397 | }
|
---|
| 398 | }
|
---|
[7834] | 399 | }
|
---|
[8015] | 400 |
|
---|
[11642] | 401 | @Override
|
---|
[13450] | 402 | public X509Certificate getX509Certificate(NativeCertAmend certAmend)
|
---|
[12241] | 403 | throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
|
---|
[13693] | 404 | for (String dir : new String[] {"/etc/ssl/certs", "/usr/share/ca-certificates/mozilla"}) {
|
---|
| 405 | File f = new File(dir, certAmend.getFilename());
|
---|
| 406 | if (f.exists()) {
|
---|
| 407 | CertificateFactory fact = CertificateFactory.getInstance("X.509");
|
---|
| 408 | try (InputStream is = Files.newInputStream(f.toPath())) {
|
---|
| 409 | return (X509Certificate) fact.generateCertificate(is);
|
---|
| 410 | }
|
---|
[12241] | 411 | }
|
---|
| 412 | }
|
---|
| 413 | return null;
|
---|
| 414 | }
|
---|
[1023] | 415 | }
|
---|