use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class NewsFetcher method persistCRLEntries.
/**
* Output any updated CRL entries
*
* @since 0.9.26
*/
private void persistCRLEntries(List<CRLEntry> entries) {
File dir = new SecureFile(_context.getConfigDir(), "certificates");
if (!dir.exists() && !dir.mkdir()) {
_log.error("Failed to create CRL directory " + dir);
return;
}
dir = new SecureFile(dir, "revocations");
if (!dir.exists() && !dir.mkdir()) {
_log.error("Failed to create CRL directory " + dir);
return;
}
int i = 0;
for (CRLEntry e : entries) {
if (e.id == null || e.data == null) {
if (_log.shouldWarn())
_log.warn("Bad CRL entry received");
continue;
}
byte[] bid = DataHelper.getUTF8(e.id);
byte[] hash = new byte[32];
_context.sha().calculateHash(bid, 0, bid.length, hash, 0);
String name = "crl-" + Base64.encode(hash) + ".crl";
File f = new File(dir, name);
if (f.exists() && f.lastModified() >= e.updated)
continue;
OutputStream out = null;
try {
byte[] data = DataHelper.getUTF8(e.data);
// test for validity
CertUtil.loadCRL(new ByteArrayInputStream(data));
out = new SecureFileOutputStream(f);
out.write(data);
} catch (GeneralSecurityException gse) {
_log.error("Bad CRL", gse);
} catch (IOException ioe) {
_log.error("Failed to write CRL", ioe);
} finally {
if (out != null)
try {
out.close();
} catch (IOException ioe) {
}
}
f.setLastModified(e.updated);
i++;
}
if (i > 0)
_log.logAlways(Log.WARN, "Stored " + i + " new CRL " + (i > 1 ? "entries" : "entry"));
}
use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class Snark method gotMetaInfo.
/**
* Called when the PeerCoordinator got the MetaInfo via magnet.
* CoordinatorListener.
* Create the storage, tell SnarkManager, and give the storage
* back to the coordinator.
*
* @throws RuntimeException via fatal()
* @since 0.8.4
*/
public void gotMetaInfo(PeerCoordinator coordinator, MetaInfo metainfo) {
try {
String base = Storage.filterName(metainfo.getName());
File baseFile;
if (_util.getFilesPublic())
baseFile = new File(rootDataDir, base);
else
baseFile = new SecureFile(rootDataDir, base);
// The following two may throw IOE...
storage = new Storage(_util, baseFile, metainfo, this, false);
storage.check();
// ... so don't set meta until here
meta = metainfo;
if (completeListener != null) {
String newName = completeListener.gotMetaInfo(this);
if (newName != null)
torrent = newName;
// else some horrible problem
}
coordinator.setStorage(storage);
} catch (IOException ioe) {
if (storage != null) {
try {
storage.close();
} catch (IOException ioee) {
}
// clear storage, we have a mess if we have non-null storage and null metainfo,
// as on restart, Storage.reopen() will throw an ioe
storage = null;
}
// TODO we're still in an inconsistent state, won't work if restarted
// (PeerState "disconnecting seed that connects to seeds"
fatal("Could not create data files", ioe);
}
}
use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class GeneralHelper method deleteTunnel.
/**
* Stop the tunnel, delete from config,
* rename the private key file if in the default directory
*
* @param privKeyFile The priv key file name from the tunnel edit form. Can
* be null if not known.
*/
public static List<String> deleteTunnel(I2PAppContext context, TunnelControllerGroup tcg, int tunnel, String privKeyFile) {
List<String> msgs;
TunnelController cur = getController(tcg, tunnel);
if (cur == null) {
msgs = new ArrayList<String>();
msgs.add("Invalid tunnel number");
return msgs;
}
msgs = tcg.removeController(cur);
msgs.addAll(saveConfig(context, tcg));
// Rename private key file if it was a default name in
// the default directory, so it doesn't get reused when a new
// tunnel is created.
// Use configured file name if available, not the one from the form.
String pk = cur.getPrivKeyFile();
if (pk == null)
pk = privKeyFile;
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat") && ((!TunnelController.isClient(cur.getType())) || cur.getPersistentClientKey())) {
File pkf = new File(context.getConfigDir(), pk);
if (pkf.exists()) {
String name = cur.getName();
if (name == null) {
name = cur.getDescription();
if (name == null) {
name = cur.getType();
if (name == null)
name = Long.toString(context.clock().now());
}
}
name = name.replace(' ', '_').replace(':', '_').replace("..", "_").replace('/', '_').replace('\\', '_');
name = "i2ptunnel-deleted-" + name + '-' + context.clock().now() + "-privkeys.dat";
File backupDir = new SecureFile(context.getConfigDir(), TunnelController.KEY_BACKUP_DIR);
File to;
if (backupDir.isDirectory() || backupDir.mkdir())
to = new File(backupDir, name);
else
to = new File(context.getConfigDir(), name);
boolean success = FileUtil.rename(pkf, to);
if (success)
msgs.add("Private key file " + pkf.getAbsolutePath() + " renamed to " + to.getAbsolutePath());
}
}
return msgs;
}
use of net.i2p.util.SecureFile in project i2p.i2p-bote by i2p.
the class I2PBote method saveLocalDestinationKeys.
/**
* Writes private + public keys for the local destination out to a file.
* @param keyFile
* @param localDestinationArray
* @throws DataFormatException
* @throws IOException
*/
private void saveLocalDestinationKeys(File keyFile, byte[] localDestinationArray) throws DataFormatException, IOException {
keyFile = new SecureFile(keyFile.getAbsolutePath());
if (keyFile.exists()) {
File oldKeyFile = new File(keyFile.getPath() + "_backup");
if (!keyFile.renameTo(oldKeyFile))
log.error("Cannot rename destination key file <" + keyFile.getAbsolutePath() + "> to <" + oldKeyFile.getAbsolutePath() + ">");
} else if (!keyFile.createNewFile())
log.error("Cannot create destination key file: <" + keyFile.getAbsolutePath() + ">");
BufferedWriter fileWriter = new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(keyFile)));
try {
fileWriter.write(Base64.encode(localDestinationArray));
} finally {
fileWriter.close();
}
}
use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class PluginUpdateRunner method processFinal.
/**
* @param pubkey null OK for su3
* @since 0.9.15
*/
private void processFinal(File to, File appDir, String url, Properties props, String sudVersion, String pubkey, String signer) {
boolean update = false;
String appName = props.getProperty("name");
String version = props.getProperty("version");
if (appName == null || version == null || appName.length() <= 0 || version.length() <= 0 || appName.indexOf('<') >= 0 || appName.indexOf('>') >= 0 || version.indexOf('<') >= 0 || version.indexOf('>') >= 0 || appName.startsWith(".") || appName.indexOf('/') >= 0 || appName.indexOf('\\') >= 0) {
to.delete();
statusDone("<b>" + _t("Plugin from {0} has invalid name or version", url) + "</b>");
return;
}
if (!version.equals(sudVersion)) {
to.delete();
statusDone("<b>" + _t("Plugin {0} has mismatched versions", appName) + "</b>");
return;
}
// set so notifyComplete() will work
_appName = appName;
_newVersion = version;
String minVersion = PluginStarter.stripHTML(props, "min-i2p-version");
if (minVersion != null && VersionComparator.comp(CoreVersion.VERSION, minVersion) < 0) {
to.delete();
statusDone("<b>" + _t("This plugin requires I2P version {0} or higher", minVersion) + "</b>");
return;
}
minVersion = PluginStarter.stripHTML(props, "min-java-version");
if (minVersion != null && VersionComparator.comp(System.getProperty("java.version"), minVersion) < 0) {
to.delete();
statusDone("<b>" + _t("This plugin requires Java version {0} or higher", minVersion) + "</b>");
return;
}
boolean wasRunning = false;
File destDir = new SecureDirectory(appDir, appName);
if (destDir.exists()) {
if (Boolean.valueOf(props.getProperty("install-only")).booleanValue()) {
to.delete();
statusDone("<b>" + _t("Downloaded plugin is for new installs only, but the plugin is already installed", url) + "</b>");
return;
}
// compare previous version
File oldPropFile = new File(destDir, "plugin.config");
Properties oldProps = new OrderedProperties();
try {
DataHelper.loadProps(oldProps, oldPropFile);
} catch (IOException ioe) {
to.delete();
statusDone("<b>" + _t("Installed plugin does not contain the required configuration file", url) + "</b>");
return;
}
String oldPubkey = oldProps.getProperty("key");
String oldKeyName = oldProps.getProperty("signer");
String oldAppName = oldProps.getProperty("name");
if ((pubkey != null && !pubkey.equals(oldPubkey)) || (!signer.equals(oldKeyName)) || (!appName.equals(oldAppName))) {
to.delete();
statusDone("<b>" + _t("Signature of downloaded plugin does not match installed plugin") + "</b>");
return;
}
String oldVersion = oldProps.getProperty("version");
if (oldVersion == null || VersionComparator.comp(oldVersion, version) >= 0) {
to.delete();
statusDone("<b>" + _t("Downloaded plugin version {0} is not newer than installed plugin", version) + "</b>");
return;
}
minVersion = PluginStarter.stripHTML(props, "min-installed-version");
if (minVersion != null && VersionComparator.comp(minVersion, oldVersion) > 0) {
to.delete();
statusDone("<b>" + _t("Plugin update requires installed plugin version {0} or higher", minVersion) + "</b>");
return;
}
String maxVersion = PluginStarter.stripHTML(props, "max-installed-version");
if (maxVersion != null && VersionComparator.comp(maxVersion, oldVersion) < 0) {
to.delete();
statusDone("<b>" + _t("Plugin update requires installed plugin version {0} or lower", maxVersion) + "</b>");
return;
}
oldVersion = RouterConsoleRunner.jettyVersion();
minVersion = PluginStarter.stripHTML(props, "min-jetty-version");
if (minVersion != null && VersionComparator.comp(minVersion, oldVersion) > 0) {
to.delete();
statusDone("<b>" + _t("Plugin requires Jetty version {0} or higher", minVersion) + "</b>");
return;
}
String blacklistVersion = PluginStarter.jetty9Blacklist.get(appName);
if (blacklistVersion != null && VersionComparator.comp(version, blacklistVersion) <= 0) {
to.delete();
statusDone("<b>" + _t("Plugin requires Jetty version {0} or lower", "8.9999") + "</b>");
return;
}
maxVersion = PluginStarter.stripHTML(props, "max-jetty-version");
if (maxVersion != null && VersionComparator.comp(maxVersion, oldVersion) < 0) {
to.delete();
statusDone("<b>" + _t("Plugin requires Jetty version {0} or lower", maxVersion) + "</b>");
return;
}
// do we defer extraction and installation?
if (Boolean.valueOf(props.getProperty("router-restart-required")).booleanValue()) {
// Yup!
try {
if (!FileUtil.copy(to, (new SecureFile(new SecureFile(appDir.getCanonicalPath() + "/" + appName + "/" + ZIP).getCanonicalPath())), true, true)) {
to.delete();
statusDone("<b>" + _t("Cannot copy plugin to directory {0}", destDir.getAbsolutePath()) + "</b>");
return;
}
} catch (Throwable t) {
to.delete();
_log.error("Error copying plugin {0}", t);
return;
}
// we don't need the original file anymore.
to.delete();
statusDone("<b>" + _t("Plugin will be installed on next restart.") + ' ' + appName + ' ' + version + "</b>");
return;
}
if (PluginStarter.isPluginRunning(appName, _context)) {
wasRunning = true;
try {
if (!PluginStarter.stopPlugin(_context, appName)) {
// failed, ignore
}
} catch (Throwable e) {
// no updateStatus() for this one
_log.error("Error stopping plugin " + appName, e);
}
}
update = true;
} else {
if (Boolean.valueOf(props.getProperty("update-only")).booleanValue()) {
to.delete();
statusDone("<b>" + _t("Plugin is for upgrades only, but the plugin is not installed") + ". " + appName + ' ' + version + "</b>");
return;
}
if (!destDir.mkdir()) {
to.delete();
statusDone("<b>" + _t("Cannot create plugin directory {0}", destDir.getAbsolutePath()) + "</b>");
return;
}
}
// Finally, extract the zip to the plugin directory
if (!FileUtil.extractZip(to, destDir, Log.WARN)) {
to.delete();
statusDone("<b>" + _t("Failed to install plugin in {0}", destDir.getAbsolutePath()) + "</b>");
return;
}
_updated = true;
to.delete();
// install != update. Changing the user's settings like this is probabbly a bad idea.
if (Boolean.valueOf(props.getProperty("dont-start-at-install")).booleanValue()) {
statusDone("<b>" + _t("Plugin {0} installed", appName + ' ' + version) + "</b>");
if (!update) {
Properties pluginProps = PluginStarter.pluginProperties();
pluginProps.setProperty(PluginStarter.PREFIX + appName + PluginStarter.ENABLED, "false");
PluginStarter.storePluginProperties(pluginProps);
}
} else if (wasRunning || PluginStarter.isPluginEnabled(appName)) {
// start everything unless it was disabled and not running before
try {
if (PluginStarter.startPlugin(_context, appName)) {
String linkName = PluginStarter.stripHTML(props, "consoleLinkName_" + Messages.getLanguage(_context));
if (linkName == null)
linkName = PluginStarter.stripHTML(props, "consoleLinkName");
String linkURL = PluginStarter.stripHTML(props, "consoleLinkURL");
String link;
if (linkName != null && linkURL != null)
link = "<a target=\"_blank\" href=\"" + linkURL + "\"/>" + linkName + ' ' + version + "</a>";
else
link = appName + ' ' + version;
statusDone("<b>" + _t("Plugin {0} installed and started", link) + "</b>");
} else
statusDone("<b>" + _t("Plugin {0} installed but failed to start, check logs", appName + ' ' + version) + "</b>");
} catch (Throwable e) {
statusDone("<b>" + _t("Plugin {0} installed but failed to start", appName + ' ' + version) + ": " + e + "</b>");
_log.error("Error starting plugin " + appName + ' ' + version, e);
}
} else {
statusDone("<b>" + _t("Plugin {0} installed", appName + ' ' + version) + "</b>");
}
}
Aggregations