From 635535aac2b831b0dbb00beb08e3b05ecb735d61 Mon Sep 17 00:00:00 2001 From: jrandom <jrandom> Date: Thu, 6 May 2004 07:35:44 +0000 Subject: [PATCH] implement keyfile persistence (storing name=privKeyDataBase64\n for each name) filename specified on the command line: SAMBridge [keyfile [listenHost] listenPortNum [ name=val]*] --- apps/sam/java/src/net/i2p/sam/SAMBridge.java | 83 ++++++++++++++++++-- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/apps/sam/java/src/net/i2p/sam/SAMBridge.java b/apps/sam/java/src/net/i2p/sam/SAMBridge.java index 018655d8b8..3ead182f22 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMBridge.java +++ b/apps/sam/java/src/net/i2p/sam/SAMBridge.java @@ -9,6 +9,11 @@ package net.i2p.sam; */ import java.io.IOException; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.FileNotFoundException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; @@ -16,6 +21,7 @@ import java.util.Properties; import java.util.Map; import java.util.HashMap; import java.util.Collections; +import java.util.Iterator; import net.i2p.data.Destination; import net.i2p.data.DataFormatException; @@ -24,6 +30,7 @@ import net.i2p.data.SigningPrivateKey; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.I2PAppContext; /** * SAM bridge implementation. @@ -31,10 +38,14 @@ import net.i2p.util.Log; * @author human */ public class SAMBridge implements Runnable { - private final static Log _log = new Log(SAMBridge.class); private ServerSocket serverSocket; private Properties i2cpProps; + /** + * filename in which the name to private key mapping should + * be stored (and loaded from) + */ + private String persistFilename; /** * app designated destination name to the base64 of the I2P formatted * destination keys (Destination+PrivateKey+SigningPrivateKey) @@ -43,7 +54,8 @@ public class SAMBridge implements Runnable { private boolean acceptConnections = true; - private final static int SAM_LISTENPORT = 7656; + private static final int SAM_LISTENPORT = 7656; + public static final String DEFAULT_SAM_KEYFILE = "sam.keys"; private SAMBridge() {} @@ -53,8 +65,11 @@ public class SAMBridge implements Runnable { * @param listenHost hostname to listen for SAM connections on ("0.0.0.0" for all) * @param listenPort port number to listen for SAM connections on * @param i2cpProps set of I2CP properties for finding and communicating with the router + * @param persistFile location to store/load named keys to/from */ - public SAMBridge(String listenHost, int listenPort, Properties i2cpProps) { + public SAMBridge(String listenHost, int listenPort, Properties i2cpProps, String persistFile) { + persistFilename = persistFile; + loadKeys(); try { if ( (listenHost != null) && !("0.0.0.0".equals(listenHost)) ) { serverSocket = new ServerSocket(listenPort, 0, InetAddress.getByName(listenHost)); @@ -114,6 +129,57 @@ public class SAMBridge implements Runnable { */ public void addKeystream(String name, String stream) { nameToPrivKeys.put(name, stream); + storeKeys(); + } + + /** + * Load up the keys from the persistFilename + * + */ + private synchronized void loadKeys() { + Map keys = new HashMap(16); + FileInputStream in = null; + try { + in = new FileInputStream(persistFilename); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line = null; + while ( (line = reader.readLine()) != null) { + int eq = line.indexOf('='); + String name = line.substring(0, eq); + String privKeys = line.substring(eq+1); + keys.put(name, privKeys); + } + } catch (FileNotFoundException fnfe) { + _log.warn("Key file does not exist at " + persistFilename); + } catch (IOException ioe) { + _log.error("Unable to read the keys from " + persistFilename, ioe); + } finally { + if (in != null) try { in.close(); } catch (IOException ioe) {} + } + nameToPrivKeys = Collections.synchronizedMap(keys); + } + + /** + * Store the current keys to disk in the location specified on creation + * + */ + private synchronized void storeKeys() { + FileOutputStream out = null; + try { + out = new FileOutputStream(persistFilename); + for (Iterator iter = nameToPrivKeys.keySet().iterator(); iter.hasNext(); ) { + String name = (String)iter.next(); + String privKeys = (String)nameToPrivKeys.get(name); + out.write(name.getBytes()); + out.write('='); + out.write(privKeys.getBytes()); + out.write('\n'); + } + } catch (IOException ioe) { + _log.error("Error writing out the SAM keys to " + persistFilename, ioe); + } finally { + if (out != null) try { out.close(); } catch (IOException ioe) {} + } } /** @@ -125,15 +191,17 @@ public class SAMBridge implements Runnable { * depth, etc. */ public static void main(String args[]) { + String keyfile = DEFAULT_SAM_KEYFILE; int port = SAM_LISTENPORT; String host = "0.0.0.0"; Properties opts = null; if (args.length > 0) { - int portIndex = 0; + keyfile = args[0]; + int portIndex = 1; try { port = Integer.parseInt(args[portIndex]); } catch (NumberFormatException nfe) { - host = args[0]; + host = args[1]; portIndex++; try { port = Integer.parseInt(args[portIndex]); @@ -144,7 +212,7 @@ public class SAMBridge implements Runnable { } opts = parseOptions(args, portIndex+1); } - SAMBridge bridge = new SAMBridge(host, port, opts); + SAMBridge bridge = new SAMBridge(host, port, opts, keyfile); I2PThread t = new I2PThread(bridge, "SAMListener"); t.start(); } @@ -167,7 +235,8 @@ public class SAMBridge implements Runnable { } private static void usage() { - System.err.println("Usage: SAMBridge [listenHost listenPortNum[ name=val]*]"); + System.err.println("Usage: SAMBridge [keyfile [listenHost] listenPortNum[ name=val]*]"); + System.err.println(" keyfile: location to persist private keys (default sam.keys)"); System.err.println(" listenHost: interface to listen on (0.0.0.0 for all interfaces)"); System.err.println(" listenPort: port to listen for SAM connections on (default 7656)"); System.err.println(" name=val: options to pass when connecting via I2CP, such as "); -- GitLab