/** * @author Matt Williams, Dirk Bergstrom * * Keyring for webOS - Easy password management on your phone. * Copyright (C) 2009-2010, Dirk Bergstrom, keyring@otisbean.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.otisbean.keyring.converters; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.Date; import java.util.Hashtable; import com.otisbean.keyring.Item; import com.otisbean.keyring.Ring; /** * Export CodeWallet Pro export format as Keyring for webOS. * * @author Matt Williams, Dirk Bergstrom */ public class CodeWalletExportConverter extends Converter { public CodeWalletExportConverter() { needsInputFilePassword = false; } public Ring convert(String inFile, String inPassword, String outPassword) throws Exception { Collection<String[]> entries = readInputFile(inFile); Ring ring = new Ring(outPassword); Date now = new Date(); int exported = 0; for (String[] entry : entries) { String name = entry[0]; String category = entry[1]; String account = entry[2]; String password = entry[3]; String notes = entry[4]; String url = entry[5]; /* Pretend that each item was created when it was imported. */ long changed = now.getTime(); ring.addItem(new Item(ring, account, password, url, notes, name, category, changed, changed, changed)); exported++; } return ring; } private Collection<String[]> readInputFile(String inFile) throws Exception { Hashtable<String, String[]> cards = new Hashtable<String, String[]>(); try { Reader fr = getReader(inFile); BufferedReader br = new BufferedReader(fr); String thisline = br.readLine(); if (thisline == null) { throw new Exception("Input file is empty!"); } boolean readingName = false; boolean entryStart = false; boolean entryEnd = false; String[] thisEntry = new String[] { "", "", "", "", "", "" }; String thisCategory = ""; while (thisline != null) { if (thisline.startsWith("*-----")) { entryStart = true; if (entryEnd) { entryEnd = false; thisEntry = new String[] { "", "", "", "", "", "" }; } } else if (thisline.length() == 0 || thisline.equals("<No Information>")) { if (entryStart) { entryEnd = true; readingName = true; } } else if (entryStart) { if (readingName && !thisline.startsWith("Folder: ")) { thisEntry[0] = thisline; readingName = false; } else if (thisline.startsWith("Folder: ")) { thisCategory = thisline.substring(thisline .indexOf(": ") + 2); /* After reading folder name, next useful entry is next * card name */ readingName = true; } else if (thisline.toLowerCase().startsWith("user id: ")) { thisEntry[2] = thisline.substring(thisline .indexOf(": ") + 2); } else if (thisline.toLowerCase().startsWith("password: ")) { thisEntry[3] = thisline.substring(thisline .indexOf(": ") + 2); } else if (thisline.toLowerCase().startsWith("url: ") || thisline.toLowerCase().startsWith("web site: ") || thisline.toLowerCase().startsWith("website: ")) { thisEntry[5] = thisline.substring(thisline .indexOf(": ") + 2); } else { // Anything else, write to the notes field. thisEntry[4] += thisline + "\n"; } } if (entryStart && entryEnd) { thisEntry[1] = thisCategory; if (cards.containsKey(thisEntry[0])) { logError("WARNING: Duplicate entry, skipping: [" + thisEntry[0] + "]"); } else { cards.put(thisEntry[0], thisEntry); // entries.add(thisEntry); } entryStart = false; } thisline = br.readLine(); } br.close(); br = null; fr.close(); fr = null; } catch (Exception ex) { logError("Exception processing input file:" + ex.getMessage()); throw ex; } // return entries; return cards.values(); } private String detectEncoding(InputStream is) { String encoding = System.getProperty("file.encoding"); try { byte[] bytes = new byte[2];// {0,0}; is.read(bytes); if (bytes[0] == 0) { encoding = "UTF-16BE"; } else if (bytes[1] == 0) { encoding = "UTF-16LE"; } else if (bytes[0] < 0) { encoding = "UTF-16"; } } catch (Exception ex) { logError("Error detecting file encoding, using default."); } return encoding; } private Reader getReader(String infileName) throws FileNotFoundException { // InputStreamReader on a FileInputStream try { FileInputStream fis = new FileInputStream(infileName); String encoding = detectEncoding(fis); fis.close(); log("Using " + encoding + " encoding to read input file \"" + infileName + "\""); return new InputStreamReader(new FileInputStream(infileName), encoding); } catch (UnsupportedEncodingException ex) { return new FileReader(infileName); } catch (IOException ex) { return new FileReader(infileName); } } }