SitePaths: Convert SSH-related paths to Path

Change-Id: I7dc8fdfcf8fec2bab159e02cab23cd64186913f2
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java b/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java
index aa2fcbc..e557301 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java
@@ -21,6 +21,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Arrays;
 
@@ -67,6 +68,15 @@
     }
   }
 
+  public static long lastModified(Path p) {
+    // Replicate File#lastModified() behavior of returning 0 on errors.
+    try {
+      return Files.getLastModifiedTime(p).toMillis();
+    } catch (IOException e) {
+      return 0;
+    }
+  }
+
   private FileUtil() {
   }
 }
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitHttpd.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitHttpd.java
index c8f1cd7..afd503b 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitHttpd.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitHttpd.java
@@ -29,10 +29,11 @@
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
-import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 
 /** Initialize the {@code httpd} configuration section. */
 @Singleton
@@ -149,8 +150,9 @@
       return;
     }
 
-    final File store = site.ssl_keystore;
-    if (!ui.yesno(!store.exists(), "Create new self-signed SSL certificate")) {
+    Path store = site.ssl_keystore;
+    if (!ui.yesno(!Files.exists(store),
+        "Create new self-signed SSL certificate")) {
       return;
     }
 
@@ -167,15 +169,17 @@
     final String dname =
         "CN=" + hostname + ",OU=Gerrit Code Review,O=" + domainOf(hostname);
 
-    final File tmpdir = new File(site.etc_dir, "tmp.sslcertgen");
-    if (!tmpdir.mkdir()) {
-      throw die("Cannot create directory " + tmpdir);
+    Path tmpdir = site.etc_dir.toPath().resolve("tmp.sslcertgen");
+    try {
+      Files.createDirectory(tmpdir);
+    } catch (IOException e) {
+      throw die("Cannot create directory " + tmpdir, e);
     }
     chmod(0600, tmpdir);
 
-    final File tmpstore = new File(tmpdir, "keystore");
+    Path tmpstore = tmpdir.resolve("keystore");
     Runtime.getRuntime().exec(new String[] {"keytool", //
-        "-keystore", tmpstore.getAbsolutePath(), //
+        "-keystore", tmpstore.toAbsolutePath().toString(), //
         "-storepass", ssl_pass, //
         "-genkeypair", //
         "-alias", hostname, //
@@ -186,11 +190,15 @@
     }).waitFor();
     chmod(0600, tmpstore);
 
-    if (!tmpstore.renameTo(store)) {
-      throw die("Cannot rename " + tmpstore + " to " + store);
+    try {
+      Files.move(tmpstore, store);
+    } catch (IOException e) {
+      throw die("Cannot rename " + tmpstore + " to " + store, e);
     }
-    if (!tmpdir.delete()) {
-      throw die("Cannot delete " + tmpdir);
+    try {
+      Files.delete(tmpdir);
+    } catch (IOException e) {
+      throw die("Cannot delete " + tmpdir, e);
     }
   }
 
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java
index ed18d73..acefaa7 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java
@@ -18,6 +18,8 @@
 import static com.google.gerrit.pgm.init.api.InitUtil.die;
 import static com.google.gerrit.pgm.init.api.InitUtil.hostname;
 
+import static java.nio.file.Files.exists;
+
 import com.google.gerrit.pgm.init.api.ConsoleUI;
 import com.google.gerrit.pgm.init.api.InitStep;
 import com.google.gerrit.pgm.init.api.Section;
@@ -29,9 +31,10 @@
 import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
 
-import java.io.File;
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
 
 /** Initialize the {@code sshd} configuration section. */
 @Singleton
@@ -74,9 +77,9 @@
     port = ui.readInt(port, "Listen on port");
     sshd.set("listenAddress", SocketUtil.format(hostname, port));
 
-    if (site.ssh_rsa.exists() || site.ssh_dsa.exists()) {
+    if (exists(site.ssh_rsa) || exists(site.ssh_dsa)) {
       libraries.bouncyCastleSSL.downloadRequired();
-    } else if (!site.ssh_key.exists()) {
+    } else if (!exists(site.ssh_key)) {
       libraries.bouncyCastleSSL.downloadOptional();
     }
 
@@ -90,9 +93,9 @@
   }
 
   private void generateSshHostKeys() throws InterruptedException, IOException {
-    if (!site.ssh_key.exists() //
-        && !site.ssh_rsa.exists() //
-        && !site.ssh_dsa.exists()) {
+    if (!exists(site.ssh_key) //
+        && !exists(site.ssh_rsa) //
+        && !exists(site.ssh_dsa)) {
       System.err.print("Generating SSH host key ...");
       System.err.flush();
 
@@ -108,7 +111,7 @@
             "-t", "rsa", //
             "-P", "", //
             "-C", comment, //
-            "-f", site.ssh_rsa.getAbsolutePath() //
+            "-f", site.ssh_rsa.toAbsolutePath().toString() //
             }).waitFor();
 
         System.err.print(" dsa...");
@@ -118,7 +121,7 @@
             "-t", "dsa", //
             "-P", "", //
             "-C", comment, //
-            "-f", site.ssh_dsa.getAbsolutePath() //
+            "-f", site.ssh_dsa.toAbsolutePath().toString() //
             }).waitFor();
 
       } else {
@@ -128,28 +131,34 @@
         // short period of time. We try to reduce that risk by creating
         // the key within a temporary directory.
         //
-        final File tmpdir = new File(site.etc_dir, "tmp.sshkeygen");
-        if (!tmpdir.mkdir()) {
-          throw die("Cannot create directory " + tmpdir);
+        Path tmpdir = site.etc_dir.toPath().resolve("tmp.sshkeygen");
+        try {
+          Files.createDirectory(tmpdir);
+        } catch (IOException e) {
+          throw die("Cannot create directory " + tmpdir, e);
         }
         chmod(0600, tmpdir);
 
-        final File tmpkey = new File(tmpdir, site.ssh_key.getName());
-        final SimpleGeneratorHostKeyProvider p;
+        Path tmpkey = tmpdir.resolve(site.ssh_key.getFileName().toString());
+        SimpleGeneratorHostKeyProvider p;
 
         System.err.print(" rsa(simple)...");
         System.err.flush();
         p = new SimpleGeneratorHostKeyProvider();
-        p.setPath(tmpkey.getAbsolutePath());
+        p.setPath(tmpkey.toAbsolutePath().toString());
         p.setAlgorithm("RSA");
         p.loadKeys(); // forces the key to generate.
         chmod(0600, tmpkey);
 
-        if (!tmpkey.renameTo(site.ssh_key)) {
-          throw die("Cannot rename " + tmpkey + " to " + site.ssh_key);
+        try {
+          Files.move(tmpkey, site.ssh_key);
+        } catch (IOException e) {
+          throw die("Cannot rename " + tmpkey + " to " + site.ssh_key, e);
         }
-        if (!tmpdir.delete()) {
-          throw die("Cannot delete " + tmpdir);
+        try {
+          Files.delete(tmpdir);
+        } catch (IOException e) {
+          throw die("Cannot delete " + tmpdir, e);
         }
       }
       System.err.println(" done");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
index 44f0340..18dd6f5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
@@ -50,11 +50,11 @@
   public final File secure_config;
   public final File contact_information_pub;
 
-  public final File ssl_keystore;
-  public final File ssh_key;
-  public final File ssh_rsa;
-  public final File ssh_dsa;
-  public final File peer_keys;
+  public final Path ssl_keystore;
+  public final Path ssh_key;
+  public final Path ssh_rsa;
+  public final Path ssh_dsa;
+  public final Path peer_keys;
 
   public final Path site_css;
   public final Path site_header;
@@ -90,13 +90,13 @@
     secure_config = new File(etc_dir, "secure.config");
     contact_information_pub = new File(etc_dir, "contact_information.pub");
 
-    ssl_keystore = new File(etc_dir, "keystore");
-    ssh_key = new File(etc_dir, "ssh_host_key");
-    ssh_rsa = new File(etc_dir, "ssh_host_rsa_key");
-    ssh_dsa = new File(etc_dir, "ssh_host_dsa_key");
-    peer_keys = new File(etc_dir, "peer_keys");
-
     Path etcDirPath = etc_dir.toPath();
+    ssl_keystore = etcDirPath.resolve("keystore");
+    ssh_key = etcDirPath.resolve("ssh_host_key");
+    ssh_rsa = etcDirPath.resolve("ssh_host_rsa_key");
+    ssh_dsa = etcDirPath.resolve("ssh_host_dsa_key");
+    peer_keys = etcDirPath.resolve("peer_keys");
+
     site_css = etcDirPath.resolve(CSS_FILENAME);
     site_header = etcDirPath.resolve(HEADER_FILENAME);
     site_footer = etcDirPath.resolve(FOOTER_FILENAME);
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
index 93d2e5b..b72ab27 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
@@ -14,6 +14,9 @@
 
 package com.google.gerrit.sshd;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.gerrit.common.FileUtil;
 import com.google.gerrit.reviewdb.client.AccountSshKey;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PeerDaemonUser;
@@ -33,10 +36,10 @@
 import org.slf4j.LoggerFactory;
 
 import java.io.BufferedReader;
-import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.security.KeyPair;
 import java.security.PublicKey;
 import java.util.Collection;
@@ -170,56 +173,50 @@
   }
 
   private static class PeerKeyCache {
-    private final File path;
+    private final Path path;
     private final long modified;
     final Set<PublicKey> keys;
 
-    PeerKeyCache(final File path) {
+    PeerKeyCache(Path path) {
       this.path = path;
-      this.modified = path.lastModified();
+      this.modified = FileUtil.lastModified(path);
       this.keys = read(path);
     }
 
-    private static Set<PublicKey> read(File path) {
-      try {
-        final BufferedReader br = new BufferedReader(new FileReader(path));
-        try {
-          final Set<PublicKey> keys = new HashSet<>();
-          String line;
-          while ((line = br.readLine()) != null) {
-            line = line.trim();
-            if (line.startsWith("#") || line.isEmpty()) {
-              continue;
-            }
-
-            try {
-              byte[] bin = Base64.decodeBase64(line.getBytes("ISO-8859-1"));
-              keys.add(new Buffer(bin).getRawPublicKey());
-            } catch (RuntimeException e) {
-              logBadKey(path, line, e);
-            } catch (SshException e) {
-              logBadKey(path, line, e);
-            }
+    private static Set<PublicKey> read(Path path) {
+      try (BufferedReader br = Files.newBufferedReader(path, UTF_8)) {
+        final Set<PublicKey> keys = new HashSet<>();
+        String line;
+        while ((line = br.readLine()) != null) {
+          line = line.trim();
+          if (line.startsWith("#") || line.isEmpty()) {
+            continue;
           }
-          return Collections.unmodifiableSet(keys);
-        } finally {
-          br.close();
+
+          try {
+            byte[] bin = Base64.decodeBase64(line.getBytes("ISO-8859-1"));
+            keys.add(new Buffer(bin).getRawPublicKey());
+          } catch (RuntimeException e) {
+            logBadKey(path, line, e);
+          } catch (SshException e) {
+            logBadKey(path, line, e);
+          }
         }
+        return Collections.unmodifiableSet(keys);
       } catch (FileNotFoundException noFile) {
         return Collections.emptySet();
-
       } catch (IOException err) {
         log.error("Cannot read " + path, err);
         return Collections.emptySet();
       }
     }
 
-    private static void logBadKey(File path, String line, Exception e) {
+    private static void logBadKey(Path path, String line, Exception e) {
       log.warn("Invalid key in " + path + ":\n  " + line, e);
     }
 
     boolean isCurrent() {
-      return path.lastModified() == modified;
+      return modified == FileUtil.lastModified(path);
     }
 
     PeerKeyCache reload() {
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java
index 241f853..3e6e2f5 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java
@@ -24,7 +24,8 @@
 import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
 
-import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -38,29 +39,29 @@
 
   @Override
   public KeyPairProvider get() {
-    final File objKey = site.ssh_key;
-    final File rsaKey = site.ssh_rsa;
-    final File dsaKey = site.ssh_dsa;
+    Path objKey = site.ssh_key;
+    Path rsaKey = site.ssh_rsa;
+    Path dsaKey = site.ssh_dsa;
 
     final List<String> stdKeys = new ArrayList<>(2);
-    if (rsaKey.exists()) {
-      stdKeys.add(rsaKey.getAbsolutePath());
+    if (Files.exists(rsaKey)) {
+      stdKeys.add(rsaKey.toAbsolutePath().toString());
     }
-    if (dsaKey.exists()) {
-      stdKeys.add(dsaKey.getAbsolutePath());
+    if (Files.exists(dsaKey)) {
+      stdKeys.add(dsaKey.toAbsolutePath().toString());
     }
 
-    if (objKey.exists()) {
+    if (Files.exists(objKey)) {
       if (stdKeys.isEmpty()) {
         SimpleGeneratorHostKeyProvider p = new SimpleGeneratorHostKeyProvider();
-        p.setPath(objKey.getAbsolutePath());
+        p.setPath(objKey.toAbsolutePath().toString());
         return p;
 
       } else {
         // Both formats of host key exist, we don't know which format
         // should be authoritative. Complain and abort.
         //
-        stdKeys.add(objKey.getAbsolutePath());
+        stdKeys.add(objKey.toAbsolutePath().toString());
         throw new ProvisionException("Multiple host keys exist: " + stdKeys);
       }