Skip to content

Commit

Permalink
Merge branch 'next' into m3u-player-prevent-flickering
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneBab committed Oct 17, 2021
2 parents 75eb96c + e58cbf3 commit 3bbd0e4
Show file tree
Hide file tree
Showing 32 changed files with 1,212 additions and 118 deletions.
35 changes: 35 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Security
========

Freenet requires different security considerations than other projects.

Any vulnerability that can correlate your activity with easily observable behavior of your node is critical.

This specifically means:

- any way to crash Freenet when accessing some known content is serious.
- if you can get Freenet or the browser opening a site from Freenet to make a request to some clearnet server depending on the content being accessed, this is serious.

More so if the vulnerability affects the **friend-to-friend** mode.

There are known unfixable attacks against opennet (Sybil attacks cannot be prevented completely, only their impact reduced).

There are no known unfixable identification-attacks against friend-to-friend mode, except if your friends' nodes attack you.

Attacks we know about are detailed on the opennet attacks and the major attacks page:

- [Attack in General](https://github.com/freenet/wiki/wiki/Major-Attacks)
- [Attacks against Opennet](https://github.com/freenet/wiki/wiki/Opennet-Attacks)

Reporting Security Issues
-------------------------

Please report security issues to [email protected]
encrypting to all PGP/gnupg keys from our [Keyring](https://freenetproject.org/assets/keyring.gpg).

Please do not file public reports of security problems that could be
used to connect the pseudonyms of users with the nodes they run. If
you find those, please send them to the email address above so they
can be resolved and the fix released before the vulnerability gets
someone in danger.

2 changes: 1 addition & 1 deletion src/freenet/client/ArchiveManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ public void run() {
}
} catch (IOException ioe) {
throw new ArchiveFailureException("An IOE occured: "+ioe.getMessage(), ioe);
}finally {
} finally {
Closer.close(is);
}
}
Expand Down
18 changes: 12 additions & 6 deletions src/freenet/clients/http/ContentFilterToadlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,20 @@ private HTMLNode createContent(PageMaker pageMaker, ToadletContext ctx) {

// display in browser or save to disk
filterForm.addChild("input",
new String[] { "type", "name", "value" },
new String[] { "radio", "result-handling", ResultHandling.DISPLAY.toString() });
filterForm.addChild("#", l10n("displayResultLabel"));
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "result-handling", ResultHandling.DISPLAY.toString(), "result-handling-display" });
filterForm.addChild("label",
new String[] { "for" },
new String[] { "result-handling-display" },
l10n("displayResultLabel"));
filterForm.addChild("br");
filterForm.addChild("input",
new String[] { "type", "name", "value" },
new String[] { "radio", "result-handling", ResultHandling.SAVE.toString() });
filterForm.addChild("#", l10n("saveResultLabel"));
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "result-handling", ResultHandling.SAVE.toString(), "result-handling-save" });
filterForm.addChild("label",
new String[] { "for" },
new String[] { "result-handling-save" },
l10n("saveResultLabel"));
filterForm.addChild("br");
filterForm.addChild("br");

Expand Down
72 changes: 64 additions & 8 deletions src/freenet/clients/http/DiagnosticToadlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import java.io.File;
import java.io.IOException;
import java.lang.management.*;
import java.net.URI;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.*;

import freenet.client.HighLevelSimpleClient;
import freenet.client.async.PersistenceDisabledException;
Expand All @@ -29,6 +33,8 @@
import freenet.node.PeerNodeStatus;
import freenet.node.RequestTracker;
import freenet.node.Version;
import freenet.node.diagnostics.*;
import freenet.node.diagnostics.threads.*;
import freenet.node.stats.DataStoreInstanceType;
import freenet.node.stats.DataStoreStats;
import freenet.node.stats.StatsNotAvailableException;
Expand Down Expand Up @@ -410,19 +416,69 @@ public int compare(PeerNodeStatus firstNode, PeerNodeStatus secondNode) {
textBuilder.append("\n");

// drawThreadPriorityStatsBox
textBuilder.append("Threads:\n");
int[] activeThreadsByPriority = stats.getActiveThreadsByPriority();
int[] waitingThreadsByPriority = stats.getWaitingThreadsByPriority();
for(int i=0; i<activeThreadsByPriority.length; i++) {
textBuilder.append(l10n("running")).append(": ").append(String.valueOf(activeThreadsByPriority[i])).append(" (").append(String.valueOf(i+1)).append(")\n");
textBuilder.append(l10n("waiting")).append(": ").append(String.valueOf(waitingThreadsByPriority[i])).append(" (").append(String.valueOf(i+1)).append(")\n");
if (node.isNodeDiagnosticsEnabled()) {
textBuilder.append(threadsStats());
textBuilder.append("\n");
}
textBuilder.append("\n");
}

this.writeTextReply(ctx, 200, "OK", textBuilder.toString());
}

/**
* Retrieves ThreadDiagnostics (through NodeDiagnostics) to display
* thread information (id, name, group, % cpu, etc).
* @return Thread information in tab separated format.
*/
private StringBuilder threadsStats() {
StringBuilder sb = new StringBuilder();

ThreadDiagnostics threadDiagnostics = node
.getNodeDiagnostics()
.getThreadDiagnostics();

NodeThreadSnapshot threadSnapshot = threadDiagnostics.getThreadSnapshot();

double wallTime = TimeUnit.MILLISECONDS.toNanos(
threadSnapshot.getInterval()
);

List<NodeThreadInfo> threads = threadSnapshot.getThreads();
threads.sort(Comparator.comparing(NodeThreadInfo::getCpuTime).reversed());

sb.append(String.format("Threads (%d):%n", threads.size()));

// Thread ID, Job ID, Name, Priority, Group (system, main), Status, % CPU
sb.append(
String.format(
"%10s %15s %-90s %5s %10s %-20s %-5s%n",
"Thread ID",
"Job ID",
"Name",
"Prio.",
"Group",
"Status",
"% CPU"
)
);

for (NodeThreadInfo thread : threads) {
String line = String.format(
"%10s %15s %-90s %5s %10s %-20s %.2f%n",
thread.getId(),
thread.getJobId(),
thread.getName().substring(0, Math.min(90, thread.getName().length())),
thread.getPrio(),
thread.getGroupName().substring(0, Math.min(10, thread.getGroupName().length())),
thread.getState(),
thread.getCpuTime() / wallTime * 100
);
sb.append(line);
}

return sb;
}

private int getPeerStatusCount(PeerNodeStatus[] peerNodeStatuses, int status) {
int count = 0;
for (PeerNodeStatus peerNodeStatus: peerNodeStatuses) {
Expand Down Expand Up @@ -471,4 +527,4 @@ private String l10n(String key, String[] patterns, String[] values) {
public String path() {
return TOADLET_URL;
}
}
}
55 changes: 36 additions & 19 deletions src/freenet/clients/http/FileInsertWizardToadlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,33 +88,42 @@ private HTMLNode createInsertBox (PageMaker pageMaker, ToadletContext ctx, boole
NETWORK_THREAT_LEVEL seclevel = core.node.securityLevels.getNetworkThreatLevel();
HTMLNode insertForm = ctx.addFormChild(insertContent, QueueToadlet.PATH_UPLOADS, "queueInsertForm");
HTMLNode input = insertForm.addChild("input",
new String[] { "type", "name", "value" },
new String[] { "radio", "keytype", "CHK" });
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "keytype", "CHK", "keytypeChk" });
if ((!rememberedLastTime && seclevel == NETWORK_THREAT_LEVEL.LOW) ||
(rememberedLastTime && wasCanonicalLastTime && seclevel != NETWORK_THREAT_LEVEL.MAXIMUM)) {
input.addAttribute("checked", "checked");
}
insertForm.addChild("b", l10n("insertCanonicalTitle"));
insertForm.addChild("label",
new String[] { "for" },
new String[] { "keytypeChk" }
).addChild("b", l10n("insertCanonicalTitle"));
insertForm.addChild("#", ": "+l10n("insertCanonical"));
if(isAdvancedModeEnabled)
insertForm.addChild("#", " "+l10n("insertCanonicalAdvanced"));
insertForm.addChild("br");
input = insertForm.addChild("input",
new String[] { "type", "name", "value" },
new String[] { "radio", "keytype", "SSK" });
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "keytype", "SSK", "keytypeSsk" });
if (seclevel == NETWORK_THREAT_LEVEL.MAXIMUM || (rememberedLastTime && !wasCanonicalLastTime)) {
input.addAttribute("checked", "checked");
}
insertForm.addChild("b", l10n("insertRandomTitle"));
insertForm.addChild("label",
new String[] { "for" },
new String[] { "keytypeSsk" }
).addChild("b", l10n("insertRandomTitle"));
insertForm.addChild("#", ": "+l10n("insertRandom"));
if(isAdvancedModeEnabled)
insertForm.addChild("#", " "+l10n("insertRandomAdvanced"));
if (isAdvancedModeEnabled) {
insertForm.addChild("br");
insertForm.addChild("input",
new String[] { "type", "name", "value" },
new String[] { "radio", "keytype", "specify" });
insertForm.addChild("b", l10n("insertSpecificKeyTitle"));
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "keytype", "specify", "keytypeSpecify" });
insertForm.addChild("label",
new String[] { "for" },
new String[] { "keytypeSpecify" }
).addChild("b", l10n("insertSpecificKeyTitle"));
insertForm.addChild("#", ": "+l10n("insertSpecificKey")+" ");
insertForm.addChild("input",
new String[] { "type", "name", "value" },
Expand All @@ -124,10 +133,12 @@ private HTMLNode createInsertBox (PageMaker pageMaker, ToadletContext ctx, boole
insertForm.addChild("br");
insertForm.addChild("br");
insertForm.addChild("input",
new String[] { "type", "name", "checked" },
new String[] { "checkbox", "compress", "checked" });
insertForm.addChild("#", ' ' +
NodeL10n.getBase().getString("QueueToadlet.insertFileCompressLabel"));
new String[] { "type", "name", "checked", "id" },
new String[] { "checkbox", "compress", "checked", "checkboxCompress" });
insertForm.addChild("label",
new String[] { "for" },
new String[] { "checkboxCompress" },
' ' + NodeL10n.getBase().getString("QueueToadlet.insertFileCompressLabel"));
} else {
insertForm.addChild("input",
new String[] { "type", "name", "value" },
Expand Down Expand Up @@ -195,14 +206,20 @@ private HTMLNode createFilterBox (PageMaker pageMaker, ToadletContext ctx) {

// display in browser or save to disk
insertForm.addChild("input",
new String[] { "type", "name", "value" },
new String[] { "radio", "result-handling", ResultHandling.DISPLAY.toString() });
insertForm.addChild("#", ContentFilterToadlet.l10n("displayResultLabel"));
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "result-handling", ResultHandling.DISPLAY.toString(), "resHandlingDisplay" });
insertForm.addChild("label",
new String[] { "for" },
new String[] { "resHandlingDisplay" },
ContentFilterToadlet.l10n("displayResultLabel"));
insertForm.addChild("br");
insertForm.addChild("input",
new String[] { "type", "name", "value" },
new String[] { "radio", "result-handling", ResultHandling.SAVE.toString() });
insertForm.addChild("#", ContentFilterToadlet.l10n("saveResultLabel"));
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "result-handling", ResultHandling.SAVE.toString(), "resHandlingSave" });
insertForm.addChild("label",
new String[] { "for" },
new String[] { "resHandlingSave" },
ContentFilterToadlet.l10n("saveResultLabel"));
insertForm.addChild("br");
insertForm.addChild("br");

Expand Down
38 changes: 28 additions & 10 deletions src/freenet/clients/http/PproxyToadlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -569,17 +569,25 @@ private void showOfficialPluginLoader(ToadletContext toadletContext, HTMLNode co

boolean loadFromWeb = pm.loadOfficialPluginsFromWeb();

HTMLNode input = addOfficialForm.addChild("input", new String[] { "type", "name", "value" },
new String[] { "radio", "pluginSource", "freenet" });
HTMLNode input = addOfficialForm.addChild("input",
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "pluginSource", "freenet", "pluginSourceFreenet" });
if(!loadFromWeb)
input.addAttribute("checked", "true");
addOfficialForm.addChild("#", l10n("pluginSourceFreenet"));
addOfficialForm.addChild("label",
new String[] { "for" },
new String[] { "pluginSourceFreenet" },
l10n("pluginSourceFreenet"));
addOfficialForm.addChild("br");
input = addOfficialForm.addChild("input", new String[] { "type", "name", "value" },
new String[] { "radio", "pluginSource", "https" });
input = addOfficialForm.addChild("input",
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "pluginSource", "https", "pluginSourceHTTPS" });
if(loadFromWeb)
input.addAttribute("checked", "true");
addOfficialForm.addChild("#", l10n("pluginSourceHTTPS"));
addOfficialForm.addChild("label",
new String[] { "for" },
new String[] { "pluginSourceHTTPS" },
l10n("pluginSourceHTTPS"));
addOfficialForm.addChild("#", " ");
if(node.getOpennet() == null)
addOfficialForm.addChild("b").addChild("font", "color", "red", l10n("pluginSourceHTTPSWarning"));
Expand All @@ -602,8 +610,13 @@ private void showOfficialPluginLoader(ToadletContext toadletContext, HTMLNode co
continue;
}
HTMLNode pluginNode = pluginGroupNode.addChild("div", "class", "plugin");
HTMLNode option = pluginNode.addChild("input", new String[] { "type", "name", "value" }, new String[] { "radio", "plugin-name", pluginDescription.name });
option.addChild("i", pluginDescription.getLocalisedPluginName());
HTMLNode option = pluginNode.addChild("input",
new String[] { "type", "name", "value", "id" },
new String[] { "radio", "plugin-name", pluginDescription.name, "radioPlugin" + pluginDescription.name });
option.addChild("label",
new String[] { "for" },
new String[] { "radioPlugin" + pluginDescription.name }
).addChild("i", pluginDescription.getLocalisedPluginName());
if(pluginDescription.deprecated)
option.addChild("b", " ("+l10n("loadLabelDeprecated")+")");
if(pluginDescription.experimental)
Expand Down Expand Up @@ -639,8 +652,13 @@ private void showUnofficialPluginLoader(ToadletContext toadletContext, HTMLNode
addOtherForm.addChild("#", " ");
addOtherForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "submit-other", l10n("Load") });
addOtherForm.addChild("br");
addOtherForm.addChild("input", new String[] { "type", "name", "checked" }, new String[] { "checkbox", "fileonly", "checked" });
addOtherForm.addChild("#", " " + l10n("fileonly"));
addOtherForm.addChild("input",
new String[] { "type", "name", "checked", "id" },
new String[] { "checkbox", "fileonly", "checked", "fileonly" });
addOtherForm.addChild("label",
new String[] { "for" },
new String[] { "fileonly" },
" " + l10n("fileonly"));
}

private void showFreenetPluginLoader(ToadletContext toadletContext, HTMLNode contentNode) {
Expand Down
27 changes: 18 additions & 9 deletions src/freenet/clients/http/QueueToadlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -2011,22 +2011,31 @@ private HTMLNode createBulkDownloadForm(ToadletContext ctx, PageMaker pageMaker)
} else {
downloadForm.addChild("br");
downloadForm.addChild("input",
new String[] { "type", "value", "name" },
new String[] { "radio", "disk", "target" },
new String[] { "type", "value", "name", "id" },
new String[] { "radio", "disk", "target", "bulkDownloadSelectOptionDisk" }
//Nicer spacing for radio button
' '+l10n("bulkDownloadSelectOptionDisk")+' ');
).addChild("label",
new String[] { "for" },
new String[] { "bulkDownloadSelectOptionDisk" },
' '+l10n("bulkDownloadSelectOptionDisk")+' ');
selectLocation(downloadForm);
downloadForm.addChild("br");
downloadForm.addChild("input",
new String[] { "type", "value", "name", "checked" },
new String[] { "radio", "direct", "target", "checked" },
' '+l10n("bulkDownloadSelectOptionDirect")+' ');
new String[] { "type", "value", "name", "checked", "id" },
new String[] { "radio", "direct", "target", "checked", "bulkDownloadSelectOptionDirect" }
).addChild("label",
new String[] { "for" },
new String[] { "bulkDownloadSelectOptionDirect" },
' '+l10n("bulkDownloadSelectOptionDirect")+' ');
}
HTMLNode filterControl = downloadForm.addChild("div", l10n("filterData"));
filterControl.addChild("input",
new String[] { "type", "name", "value", "checked" },
new String[] { "checkbox", "filterData", "filterData", "checked"});
filterControl.addChild("#", l10n("filterDataMessage"));
new String[] { "type", "name", "value", "checked", "id" },
new String[] { "checkbox", "filterData", "filterData", "checked", "filterDataMessage"});
filterControl.addChild("label",
new String[] { "for" },
new String[] { "filterDataMessage" },
l10n("filterDataMessage"));
downloadForm.addChild("br");
downloadForm.addChild("input",
new String[] { "type", "name", "value" },
Expand Down
Loading

0 comments on commit 3bbd0e4

Please sign in to comment.