forked from I2P_Developers/i2p.i2p
Add AUTH commands: ENABLE, DISABLE, ADD, REMOVE
Store changes to config file
This commit is contained in:
@@ -58,6 +58,7 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
private final int _listenPort;
|
||||
private final Properties i2cpProps;
|
||||
private final boolean _useSSL;
|
||||
private final File _configFile;
|
||||
private volatile Thread _runner;
|
||||
|
||||
/**
|
||||
@@ -117,6 +118,7 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
if (_useSSL && !SystemVersion.isJava7())
|
||||
throw new IllegalArgumentException("SSL requires Java 7 or higher");
|
||||
persistFilename = options.keyFile;
|
||||
_configFile = options.configFile;
|
||||
nameToPrivKeys = new HashMap<String,String>(8);
|
||||
_handlers = new HashSet<Handler>(8);
|
||||
this.i2cpProps = options.opts;
|
||||
@@ -140,7 +142,8 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
* @param persistFile location to store/load named keys to/from
|
||||
* @throws RuntimeException if a server socket can't be opened
|
||||
*/
|
||||
public SAMBridge(String listenHost, int listenPort, boolean isSSL, Properties i2cpProps, String persistFile) {
|
||||
public SAMBridge(String listenHost, int listenPort, boolean isSSL, Properties i2cpProps,
|
||||
String persistFile, File configFile) {
|
||||
_log = I2PAppContext.getGlobalContext().logManager().getLog(SAMBridge.class);
|
||||
_mgr = null;
|
||||
_listenHost = listenHost;
|
||||
@@ -150,6 +153,7 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
throw new IllegalArgumentException("SSL requires Java 7 or higher");
|
||||
this.i2cpProps = i2cpProps;
|
||||
persistFilename = persistFile;
|
||||
_configFile = configFile;
|
||||
nameToPrivKeys = new HashMap<String,String>(8);
|
||||
_handlers = new HashSet<Handler>(8);
|
||||
loadKeys();
|
||||
@@ -451,7 +455,8 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
public static void main(String args[]) {
|
||||
try {
|
||||
Options options = getOptions(args);
|
||||
SAMBridge bridge = new SAMBridge(options.host, options.port, options.isSSL, options.opts, options.keyFile);
|
||||
SAMBridge bridge = new SAMBridge(options.host, options.port, options.isSSL, options.opts,
|
||||
options.keyFile, options.configFile);
|
||||
bridge.startThread();
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
@@ -490,10 +495,12 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
private final int port;
|
||||
private final Properties opts;
|
||||
private final boolean isSSL;
|
||||
private final File configFile;
|
||||
|
||||
public Options(String host, int port, boolean isSSL, Properties opts, String keyFile) {
|
||||
public Options(String host, int port, boolean isSSL, Properties opts, String keyFile, File configFile) {
|
||||
this.host = host; this.port = port; this.opts = opts; this.keyFile = keyFile;
|
||||
this.isSSL = isSSL;
|
||||
this.configFile = configFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,7 +621,7 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
if (remaining > 0) {
|
||||
parseOptions(args, startOpts, opts);
|
||||
}
|
||||
return new Options(host, port, isSSL, opts, keyfile);
|
||||
return new Options(host, port, isSSL, opts, keyfile, file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -742,4 +749,9 @@ public class SAMBridge implements Runnable, ClientApp {
|
||||
changeState(STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.22 */
|
||||
public void saveConfig() throws IOException {
|
||||
DataHelper.storeProps(i2cpProps, _configFile);
|
||||
}
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.PasswordManager;
|
||||
|
||||
/**
|
||||
* Class able to handle a SAM version 3 client connection.
|
||||
@@ -425,6 +426,8 @@ class SAMv3Handler extends SAMv1Handler
|
||||
} else if (domain.equals("RAW")) {
|
||||
// TODO not yet overridden, ID is ignored, most recent RAW session is used
|
||||
canContinue = execRawMessage(opcode, props);
|
||||
} else if (domain.equals("AUTH")) {
|
||||
canContinue = execAuthMessage(opcode, props);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Unrecognized message domain: \""
|
||||
@@ -889,5 +892,40 @@ class SAMv3Handler extends SAMv1Handler
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.22 */
|
||||
private boolean execAuthMessage(String opcode, Properties props) {
|
||||
if (opcode.equals("ENABLE")) {
|
||||
i2cpProps.setProperty(SAMBridge.PROP_AUTH, "true");
|
||||
} else if (opcode.equals("DISABLE")) {
|
||||
i2cpProps.setProperty(SAMBridge.PROP_AUTH, "false");
|
||||
} else if (opcode.equals("ADD")) {
|
||||
String user = props.getProperty("USER");
|
||||
String pw = props.getProperty("PASSWORD");
|
||||
if (user == null || pw == null)
|
||||
return writeString("AUTH STATUS RESULT=I2P_ERROR MESSAGE=\"USER and PASSWORD required\"\n");
|
||||
String prop = SAMBridge.PROP_PW_PREFIX + user + SAMBridge.PROP_PW_SUFFIX;
|
||||
if (i2cpProps.containsKey(prop))
|
||||
return writeString("AUTH STATUS RESULT=I2P_ERROR MESSAGE=\"user " + user + " already exists\"\n");
|
||||
PasswordManager pm = new PasswordManager(I2PAppContext.getGlobalContext());
|
||||
String shash = pm.createHash(pw);
|
||||
i2cpProps.setProperty(prop, shash);
|
||||
} else if (opcode.equals("REMOVE")) {
|
||||
String user = props.getProperty("USER");
|
||||
if (user == null)
|
||||
return writeString("AUTH STATUS RESULT=I2P_ERROR MESSAGE=\"USER required\"\n");
|
||||
String prop = SAMBridge.PROP_PW_PREFIX + user + SAMBridge.PROP_PW_SUFFIX;
|
||||
if (!i2cpProps.containsKey(prop))
|
||||
return writeString("AUTH STATUS RESULT=I2P_ERROR MESSAGE=\"user " + user + " not found\"\n");
|
||||
i2cpProps.remove(prop);
|
||||
} else {
|
||||
return writeString("AUTH STATUS RESULT=I2P_ERROR MESSAGE=\"Unknown AUTH command\"\n");
|
||||
}
|
||||
try {
|
||||
bridge.saveConfig();
|
||||
return writeString("AUTH STATUS RESULT=OK\n");
|
||||
} catch (IOException ioe) {
|
||||
return writeString("AUTH STATUS RESULT=I2P_ERROR MESSAGE=\"Config save failed: " + ioe + "\"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user