Change setting so that the private key isn't displayed unless except when you enter it.
diff --git a/src/fniki/wiki/ArchiveManager.java b/src/fniki/wiki/ArchiveManager.java
--- a/src/fniki/wiki/ArchiveManager.java
+++ b/src/fniki/wiki/ArchiveManager.java
@@ -75,14 +75,23 @@ public class ArchiveManager {
FreenetIO.setDebugOutput(out);
}
- public void setPrivateSSK(String value) {
+ private static void validatePrivateSSK(String value) {
if (!value.startsWith("SSK@") || !value.endsWith(",AQECAAE/")) {
throw new IllegalArgumentException("That doesn't look like a private SSK. " +
"Did you forget the trailing '/'?");
}
+ }
+
+ public void setPrivateSSK(String value) {
+ validatePrivateSSK(value);
mPrivateSSK = value;
}
+ public String invertPrivateSSK(String value, int timeoutMs) throws IOException {
+ validatePrivateSSK(value);
+ return (new FreenetIO(mFcpHost, mFcpPort)).invertPrivateSSK(value, timeoutMs);
+ }
+
public String getPrivateSSK() { return mPrivateSSK; }
public String getParentUri() { return mParentUri; }
diff --git a/src/fniki/wiki/WikiApp.java b/src/fniki/wiki/WikiApp.java
--- a/src/fniki/wiki/WikiApp.java
+++ b/src/fniki/wiki/WikiApp.java
@@ -68,9 +68,13 @@ public class WikiApp implements ChildCon
ArchiveManager.FMS_GROUP,
ArchiveManager.BISS_NAME);
+ // Time to wait for FCP before giving up on inverting private key.
+ private final static int INVERT_TIMEOUT_MS = 30 * 1000;
+
// Delegate to implement link, image and macro handling in wikitext.
private final FreenetWikiTextParser.ParserDelegate mParserDelegate;
+ // ChildContainers for non-modal UI elements.
private final ChildContainer mDefaultRedirect;
private final ChildContainer mGotoRedirect;
private final ChildContainer mQueryError;
@@ -100,7 +104,6 @@ public class WikiApp implements ChildCon
private String mFormPassword;
private int mListenPort = LISTEN_PORT;
-
// final because it is called from the ctor.
private final void resetContentFilter() {
mFilter = ContentFilterFactory.create(mFproxyPrefix, containerPrefix());
@@ -295,7 +298,6 @@ public class WikiApp implements ChildCon
sb.append("{ERROR PROCESSING TITLEINDEX MACRO}");
return true;
}
-
return true;
}
@@ -402,7 +404,7 @@ public class WikiApp implements ChildCon
// Can return an invalid configuration. e.g. if fms id and private ssk are not set.
public Configuration getConfiguration() {
// Converts null values to ""
- return new Configuration(getInt("listen_port", LISTEN_PORT), //DCI: clean up magic numbers
+ return new Configuration(getInt("listen_port", LISTEN_PORT),
mArchiveManager.getFcpHost(),
mArchiveManager.getFcpPort(),
getString("fproxy_prefix", FPROXY_PREFIX),
@@ -417,6 +419,29 @@ public class WikiApp implements ChildCon
public Configuration getDefaultConfiguration() { return DEFAULT_CONFIG; }
+ public String getPublicFmsId(String fmsId, String privateSSK) {
+ if (fmsId == null || privateSSK == null || fmsId.indexOf("@") != -1) {
+ return "???";
+ }
+ try {
+ try {
+ String publicKey = mArchiveManager.invertPrivateSSK(privateSSK, INVERT_TIMEOUT_MS);
+ int pos = publicKey.indexOf(",");
+ if (pos == -1 || pos < 5) {
+ return "???";
+ }
+ return fmsId + publicKey.substring("SSK".length(), pos);
+
+ } catch (IllegalArgumentException iae) {
+ // Was called with an invalid privateSSK value
+ return "???";
+ }
+ } catch (IOException ioe) {
+ logError("getPublicFmsId failed", ioe);
+ return "???";
+ }
+ }
+
// For setting data from forms and restoring saved settings.
// throws unchecked Configuration.ConfigurationException
public void setConfiguration(Configuration config) {
diff --git a/src/fniki/wiki/WikiContext.java b/src/fniki/wiki/WikiContext.java
--- a/src/fniki/wiki/WikiContext.java
+++ b/src/fniki/wiki/WikiContext.java
@@ -44,6 +44,14 @@ public interface WikiContext extends Req
Configuration getConfiguration();
Configuration getDefaultConfiguration();
+ // Returns a public fmsId.
+ // e.g. djk@isFiaD04zgAgnrEC5XJt1i4IE7AkNPqhBG5bONi6Yks
+ //
+ // fmsId is the human readable part, can be null
+ // private SSK is the private SSK for the FMS identity.
+ // This can return "???" on failure or if the args are null.
+ String getPublicFmsId(String fmsId, String privateSSK);
+
// throws unchecked Configuration.ConfigurationException
void setConfiguration(Configuration config);
diff --git a/src/fniki/wiki/child/SettingConfig.java b/src/fniki/wiki/child/SettingConfig.java
--- a/src/fniki/wiki/child/SettingConfig.java
+++ b/src/fniki/wiki/child/SettingConfig.java
@@ -44,10 +44,13 @@ public class SettingConfig implements Mo
private boolean mFinished = false;
private Configuration mConfig;
+ private String mPrivateSSK = "";
+ private String mPublicFmsId = "???";
private String mMsg = "";
// Doesn't validate.
- private static Configuration parseConfigFromPost(Query query, int listenPort) {
+ private Configuration parseConfigFromPost(WikiContext context, Query query,
+ int listenPort, String oldSSK) {
boolean allowImages = false;
if (query.containsKey("images")) {
allowImages = true;
@@ -66,6 +69,13 @@ public class SettingConfig implements Mo
// NOP
}
+ String newSSK = query.get("fmsssk");
+ if (newSSK == null || newSSK.equals("")) {
+ newSSK = oldSSK;
+ } else {
+ mPublicFmsId = context.getPublicFmsId(query.get("fmsid"), mPrivateSSK);
+ }
+
Configuration config = new Configuration(listenPort,
query.get("fcphost"),
fcpPort,
@@ -74,7 +84,7 @@ public class SettingConfig implements Mo
query.get("fmshost"),
fmsPort,
query.get("fmsid"),
- query.get("fmsssk"),
+ newSSK,
query.get("fmsgroup"),
query.get("wikiname"));
return config;
@@ -87,7 +97,7 @@ public class SettingConfig implements Mo
// Pop a save-as dialog for configuration.
try {
// Save any changes the user made.
- mConfig = parseConfigFromPost(query, context.getInt("listen_port", 8083));
+ mConfig = parseConfigFromPost(context, query, context.getInt("listen_port", 8083), mPrivateSSK);
mConfig.validate();
// Force browser to save the config file to disk.
@@ -113,6 +123,8 @@ public class SettingConfig implements Mo
Configuration config = Configuration.fromStringRep(query.get("upload"));
config.validate();
mConfig = config;
+ mPrivateSSK = mConfig.mFmsSsk;
+ mPublicFmsId = context.getPublicFmsId(mConfig.mFmsId, mConfig.mFmsSsk);
mMsg = "Imported configuration!";
return;
} catch (Configuration.ConfigurationException cfe) {
@@ -138,8 +150,8 @@ public class SettingConfig implements Mo
return;
}
- mConfig = parseConfigFromPost(query, context.getInt("listen_port", 8083));
-
+ mConfig = parseConfigFromPost(context, query, context.getInt("listen_port", 8083), mPrivateSSK);
+
try {
mConfig.validate();
context.setConfiguration(mConfig);
@@ -174,8 +186,8 @@ public class SettingConfig implements Mo
mConfig.mFproxyPrefix,
mConfig.mFmsHost,
mConfig.mFmsPort,
- mConfig.mFmsSsk,
mConfig.mFmsId,
+ mPublicFmsId,
mConfig.mFmsGroup,
mConfig.mWikiName,
mConfig.mAllowImages ? "checked" : "",
@@ -195,6 +207,8 @@ public class SettingConfig implements Mo
public void entered(WikiContext context) {
mFinished = false;
mConfig = context.getConfiguration();
+ mPrivateSSK = mConfig.mFmsSsk;
+ mPublicFmsId = context.getPublicFmsId(mConfig.mFmsId, mConfig.mFmsSsk);
mMsg = "";
}
@@ -242,13 +256,17 @@ public class SettingConfig implements Mo
sb.append(" </tr>\n");
sb.append(" <tr>\n");
sb.append(" <td>FMS Private SSK</td>\n");
- sb.append(" <td><input type=\"text\" name=\"fmsssk\" size=\"128\" value=\"%s\" /> </td>\n");
+ sb.append(" <td><input type=\"text\" name=\"fmsssk\" size=\"128\" value=\"\" /> </td>\n");
sb.append(" </tr>\n");
sb.append(" <tr>\n");
- sb.append(" <td>FMS ID</td>\n");
+ sb.append(" <td>FMS name</td>\n");
sb.append(" <td><input type=\"text\" name=\"fmsid\" value=\"%s\" /> </td>\n");
sb.append(" </tr>\n");
sb.append(" <tr>\n");
+ sb.append(" <td>Full FMS ID</td>\n");
+ sb.append(" <td><input type=\"text\" name=\"fmsfull\" size=\"64\" readonly=\"readonly\" value=\"%s\" /> </td>\n");
+ sb.append(" </tr>\n");
+ sb.append(" <tr>\n");
sb.append(" <td>FMS Group</td>\n");
sb.append(" <td><input type=\"text\" name=\"fmsgroup\" value=\"%s\" /> </td>\n");
sb.append(" </tr>\n");