001/** 002 * 003 * Copyright 2018 Paul Schaub. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.ox.store.filebased; 018 019import java.io.BufferedReader; 020import java.io.BufferedWriter; 021import java.io.File; 022import java.io.FileNotFoundException; 023import java.io.IOException; 024import java.io.InputStream; 025import java.io.InputStreamReader; 026import java.io.OutputStream; 027import java.io.OutputStreamWriter; 028import java.util.logging.Level; 029import java.util.logging.Logger; 030 031import org.jivesoftware.smack.util.CloseableUtil; 032import org.jivesoftware.smack.util.FileUtils; 033import org.jivesoftware.smackx.ox.store.abstr.AbstractOpenPgpTrustStore; 034import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore; 035import org.jivesoftware.smackx.ox.util.Util; 036 037import org.jxmpp.jid.BareJid; 038import org.pgpainless.key.OpenPgpV4Fingerprint; 039 040/** 041 * Implementation of the {@link OpenPgpTrustStore} which stores information in a directory structure. 042 * 043 * <pre> 044 * {@code 045 * <basePath>/ 046 * <userjid@server.tld>/ 047 * <fingerprint>.trust // Trust record for a key 048 * } 049 * </pre> 050 */ 051public class FileBasedOpenPgpTrustStore extends AbstractOpenPgpTrustStore { 052 053 private static final Logger LOGGER = Logger.getLogger(FileBasedOpenPgpTrustStore.class.getName()); 054 055 private final File basePath; 056 057 public static String TRUST_RECORD(OpenPgpV4Fingerprint fingerprint) { 058 return fingerprint.toString() + ".trust"; 059 } 060 061 public FileBasedOpenPgpTrustStore(File basePath) { 062 this.basePath = basePath; 063 } 064 065 @Override 066 protected Trust readTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException { 067 File file = getTrustPath(owner, fingerprint); 068 BufferedReader reader = null; 069 try { 070 InputStream inputStream = FileUtils.prepareFileInputStream(file); 071 InputStreamReader isr = new InputStreamReader(inputStream, Util.UTF8); 072 reader = new BufferedReader(isr); 073 074 Trust trust = null; 075 String line; int lineNr = 0; 076 while ((line = reader.readLine()) != null) { 077 lineNr++; 078 try { 079 trust = Trust.valueOf(line); 080 break; 081 } catch (IllegalArgumentException e) { 082 LOGGER.log(Level.WARNING, "Skipping invalid trust record in line " + lineNr + " \"" + line 083 + "\" of file " + file.getAbsolutePath()); 084 } 085 } 086 return trust != null ? trust : Trust.undecided; 087 } catch (IOException e) { 088 if (e instanceof FileNotFoundException) { 089 return Trust.undecided; 090 } 091 throw e; 092 } finally { 093 CloseableUtil.maybeClose(reader, LOGGER); 094 } 095 } 096 097 @Override 098 protected void writeTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) throws IOException { 099 File file = getTrustPath(owner, fingerprint); 100 101 if (trust == null || trust == Trust.undecided) { 102 FileUtils.maybeDeleteFileOrThrow(file); 103 } 104 105 FileUtils.maybeCreateFileWithParentDirectories(file); 106 107 BufferedWriter writer = null; 108 try { 109 OutputStream outputStream = FileUtils.prepareFileOutputStream(file); 110 OutputStreamWriter osw = new OutputStreamWriter(outputStream, Util.UTF8); 111 writer = new BufferedWriter(osw); 112 113 writer.write(trust.toString()); 114 } finally { 115 CloseableUtil.maybeClose(writer, LOGGER); 116 } 117 } 118 119 private File getTrustPath(BareJid owner, OpenPgpV4Fingerprint fingerprint) { 120 return new File(FileBasedOpenPgpStore.getContactsPath(basePath, owner), TRUST_RECORD(fingerprint)); 121 } 122}