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; 033 034import org.jivesoftware.smackx.ox.store.abstr.AbstractOpenPgpTrustStore; 035import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore; 036import org.jivesoftware.smackx.ox.util.Util; 037 038import org.jxmpp.jid.BareJid; 039import org.pgpainless.key.OpenPgpV4Fingerprint; 040 041/** 042 * Implementation of the {@link OpenPgpTrustStore} which stores information in a directory structure. 043 * 044 * <pre> 045 * {@code 046 * <basePath>/ 047 * <userjid@server.tld>/ 048 * <fingerprint>.trust // Trust record for a key 049 * } 050 * </pre> 051 */ 052public class FileBasedOpenPgpTrustStore extends AbstractOpenPgpTrustStore { 053 054 private static final Logger LOGGER = Logger.getLogger(FileBasedOpenPgpTrustStore.class.getName()); 055 056 private final File basePath; 057 058 public static String TRUST_RECORD(OpenPgpV4Fingerprint fingerprint) { 059 return fingerprint.toString() + ".trust"; 060 } 061 062 public FileBasedOpenPgpTrustStore(File basePath) { 063 this.basePath = basePath; 064 } 065 066 @Override 067 protected Trust readTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException { 068 File file = getTrustPath(owner, fingerprint); 069 BufferedReader reader = null; 070 try { 071 InputStream inputStream = FileUtils.prepareFileInputStream(file); 072 InputStreamReader isr = new InputStreamReader(inputStream, Util.UTF8); 073 reader = new BufferedReader(isr); 074 075 Trust trust = null; 076 String line; int lineNr = 0; 077 while ((line = reader.readLine()) != null) { 078 lineNr++; 079 try { 080 trust = Trust.valueOf(line); 081 break; 082 } catch (IllegalArgumentException e) { 083 LOGGER.log(Level.WARNING, "Skipping invalid trust record in line " + lineNr + " \"" + line 084 + "\" of file " + file.getAbsolutePath()); 085 } 086 } 087 return trust != null ? trust : Trust.undecided; 088 } catch (IOException e) { 089 if (e instanceof FileNotFoundException) { 090 return Trust.undecided; 091 } 092 throw e; 093 } finally { 094 CloseableUtil.maybeClose(reader, LOGGER); 095 } 096 } 097 098 @Override 099 protected void writeTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) throws IOException { 100 File file = getTrustPath(owner, fingerprint); 101 102 if (trust == null || trust == Trust.undecided) { 103 FileUtils.maybeDeleteFileOrThrow(file); 104 } 105 106 FileUtils.maybeCreateFileWithParentDirectories(file); 107 108 BufferedWriter writer = null; 109 try { 110 OutputStream outputStream = FileUtils.prepareFileOutputStream(file); 111 OutputStreamWriter osw = new OutputStreamWriter(outputStream, Util.UTF8); 112 writer = new BufferedWriter(osw); 113 114 writer.write(trust.toString()); 115 } finally { 116 CloseableUtil.maybeClose(writer, LOGGER); 117 } 118 } 119 120 private File getTrustPath(BareJid owner, OpenPgpV4Fingerprint fingerprint) { 121 return new File(FileBasedOpenPgpStore.getContactsPath(basePath, owner), TRUST_RECORD(fingerprint)); 122 } 123}