FileBasedOpenPgpTrustStore.java

  1. /**
  2.  *
  3.  * Copyright 2018 Paul Schaub.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.ox.store.filebased;

  18. import java.io.BufferedReader;
  19. import java.io.BufferedWriter;
  20. import java.io.File;
  21. import java.io.FileNotFoundException;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.io.InputStreamReader;
  25. import java.io.OutputStream;
  26. import java.io.OutputStreamWriter;
  27. import java.util.logging.Level;
  28. import java.util.logging.Logger;

  29. import org.jivesoftware.smack.util.CloseableUtil;
  30. import org.jivesoftware.smack.util.FileUtils;

  31. import org.jivesoftware.smackx.ox.store.abstr.AbstractOpenPgpTrustStore;
  32. import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
  33. import org.jivesoftware.smackx.ox.util.Util;

  34. import org.jxmpp.jid.BareJid;
  35. import org.pgpainless.key.OpenPgpV4Fingerprint;

  36. /**
  37.  * Implementation of the {@link OpenPgpTrustStore} which stores information in a directory structure.
  38.  *
  39.  * <pre>
  40.  * {@code
  41.  * <basePath>/
  42.  *     <userjid@server.tld>/
  43.  *         <fingerprint>.trust      // Trust record for a key
  44.  * }
  45.  * </pre>
  46.  */
  47. public class FileBasedOpenPgpTrustStore extends AbstractOpenPgpTrustStore {

  48.     private static final Logger LOGGER = Logger.getLogger(FileBasedOpenPgpTrustStore.class.getName());

  49.     private final File basePath;

  50.     public static String TRUST_RECORD(OpenPgpV4Fingerprint fingerprint) {
  51.         return fingerprint.toString() + ".trust";
  52.     }

  53.     public FileBasedOpenPgpTrustStore(File basePath) {
  54.         this.basePath = basePath;
  55.     }

  56.     @Override
  57.     protected Trust readTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException {
  58.         File file = getTrustPath(owner, fingerprint);
  59.         BufferedReader reader = null;
  60.         try {
  61.             InputStream inputStream = FileUtils.prepareFileInputStream(file);
  62.             InputStreamReader isr = new InputStreamReader(inputStream, Util.UTF8);
  63.             reader = new BufferedReader(isr);

  64.             Trust trust = null;
  65.             String line; int lineNr = 0;
  66.             while ((line = reader.readLine()) != null) {
  67.                 lineNr++;
  68.                 try {
  69.                     trust = Trust.valueOf(line);
  70.                     break;
  71.                 } catch (IllegalArgumentException e) {
  72.                     LOGGER.log(Level.WARNING, "Skipping invalid trust record in line " + lineNr + " \"" + line
  73.                             + "\" of file " + file.getAbsolutePath());
  74.                 }
  75.             }
  76.             return trust != null ? trust : Trust.undecided;
  77.         } catch (IOException e) {
  78.             if (e instanceof FileNotFoundException) {
  79.                 return Trust.undecided;
  80.             }
  81.             throw e;
  82.         } finally {
  83.             CloseableUtil.maybeClose(reader, LOGGER);
  84.         }
  85.     }

  86.     @Override
  87.     protected void writeTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) throws IOException {
  88.         File file = getTrustPath(owner, fingerprint);

  89.         if (trust == null || trust == Trust.undecided) {
  90.             FileUtils.maybeDeleteFileOrThrow(file);
  91.         }

  92.         FileUtils.maybeCreateFileWithParentDirectories(file);

  93.         BufferedWriter writer = null;
  94.         try {
  95.             OutputStream outputStream = FileUtils.prepareFileOutputStream(file);
  96.             OutputStreamWriter osw = new OutputStreamWriter(outputStream, Util.UTF8);
  97.             writer = new BufferedWriter(osw);

  98.             writer.write(trust.toString());
  99.         } finally {
  100.             CloseableUtil.maybeClose(writer, LOGGER);
  101.         }
  102.     }

  103.     private File getTrustPath(BareJid owner, OpenPgpV4Fingerprint fingerprint) {
  104.         return new File(FileBasedOpenPgpStore.getContactsPath(basePath, owner), TRUST_RECORD(fingerprint));
  105.     }
  106. }