93 Commits
0.2 ... 0.3.8

Author SHA1 Message Date
a6d97dc00a version bump 2019-11-03 00:42:12 +01:00
92a908907b A lot of bugfixing around the initial dialog and portchecking of the i2p console 2019-11-01 22:02:41 +01:00
b40d5578f8 Fixes noscript issue 2019-10-27 13:44:01 +01:00
199f3b839e Add services 2019-10-27 13:32:53 +01:00
dbf0d53e5c Make the progress dialog show until console is up 2019-10-27 13:31:47 +01:00
00f3ac2afb Adding waitForPortToOpen function 2019-10-27 13:25:43 +01:00
32bb96b18e Adding reseed and restart methods 2019-10-27 12:55:23 +01:00
52c3c6a6c2 Merge remote-tracking branch 'upstream/master' 2019-10-27 12:53:54 +01:00
301bcf6d33 Adding json rpc client for use with i2p control 2019-10-27 12:49:02 +01:00
b52f7f7510 Merge pull request #3 from eyedeekay/master
Minor tweak to the about:i2p display
2019-10-18 10:18:58 +02:00
idk
116f787d25 Minor tweak to the about:i2p display 2019-09-16 13:02:14 -04:00
abc0ce454f Re-adding temporary fix for jetty 2019-09-15 18:25:57 +02:00
b90ed676fd version bump 2019-09-14 23:04:28 +02:00
91b0d0500e Update port numbers 2019-09-14 23:03:41 +02:00
1cafe3fd25 version bump 2019-09-13 12:07:12 +02:00
3a1ce635b1 Adding missing functions 2019-09-12 22:59:05 +02:00
506f675664 Adding missing functions 2019-09-12 22:58:42 +02:00
822fd90f6d function for listing addons 2019-09-12 22:58:16 +02:00
953da8a8e2 Added missing functions etc 2019-09-12 22:50:10 +02:00
ee146800ee Integration with the delay dialog 2019-09-12 22:49:23 +02:00
8ef76f4ebb Added progress dialog aka delay the user dialog 2019-09-12 22:48:07 +02:00
348846f5d3 Misc refactoring and fixes 2019-09-11 22:29:21 +02:00
e42e60276b Refactor away some duplicated code 2019-09-11 22:28:41 +02:00
235bbda10b Bugfixes, cleanup and improvements for the launcher part of the code 2019-09-11 00:04:59 +02:00
ced728b0f4 Functions for reading the router log files 2019-09-10 22:03:22 +02:00
015fa2166b version bump 2019-09-10 22:02:58 +02:00
637ff45592 Misc 2019-09-10 17:45:01 +02:00
78959d60c7 Use the subprocess as indicator for console 2019-09-10 17:44:40 +02:00
00283bde24 Write webapps.config as well 2019-09-10 07:15:57 +02:00
2c0666dcf2 Router config: routerconsole.welcomeWizardComplete=true 2019-09-10 05:56:47 +02:00
b06dded801 Router config: router.startup.jetty9.migrated=true 2019-09-10 05:53:53 +02:00
4bed82f527 Use different i2cp port 2019-09-10 05:52:26 +02:00
ed36de6cae Merge branch 'master' of github.com:mikalv/i2pbutton 2019-09-10 01:04:28 +02:00
676c2348d8 Use more secure permissions 2019-09-10 01:03:34 +02:00
e7d888c776 Merge pull request #2 from eyedeekay/master
Fix links on about:i2p to correspond to i2p browser router console
2019-09-09 05:12:25 +02:00
idk
6adb55d048 correct the links on the about:i2p page and direct new users to the router console for now 2019-09-08 22:56:36 -04:00
idk
4a680de5a2 Merge branch 'master' of https://github.com/mikalv/i2pbutton 2019-09-08 22:08:07 -04:00
79a32618f8 version bump 2019-09-09 03:16:54 +02:00
8d249f4831 omfg 2019-09-09 03:16:23 +02:00
67ed95fc25 version bump 2019-09-09 03:01:08 +02:00
5b6504a11d Temporary jetty fix 2019-09-09 02:54:05 +02:00
832c79f4b5 Make webapps, docs and hosts.txt get copied to config directory when it don't exists 2019-09-09 02:47:16 +02:00
988047ec4e Correct /tunnel/clients/ 2019-09-09 01:39:45 +02:00
6fa1736321 version bump 2019-09-09 01:05:14 +02:00
890438ffe9 Fixed a issue with launching router on osx 2019-09-09 01:04:56 +02:00
ebf6f2577a Use self to avoid error 2019-09-09 00:48:19 +02:00
d3b043fc23 version bump 2019-09-07 23:04:12 +02:00
a9e70d19a7 small cleanup 2019-09-07 23:03:55 +02:00
4e6117faf9 Merge pull request #1 from eyedeekay/master
Update about:i2p and browser onboarding text
2019-09-07 22:26:22 +02:00
idk
c19ea1d76c Merge branch 'master' of https://github.com/mikalv/i2pbutton 2019-09-06 13:25:41 -04:00
idk
015e20c06a put the rest of the URLs into the dtd 2019-09-05 16:42:55 -04:00
idk
96ad84bf2c make it so links to the project site can honor localizations 2019-09-05 16:33:48 -04:00
idk
45b13ef209 more straightforward language on intro page 2019-09-05 14:16:21 -04:00
idk
fbf7ced2c7 more straightforward language on intro page 2019-09-05 14:04:06 -04:00
idk
d2403362ba ucomment the un-used slides 2019-09-05 13:55:18 -04:00
idk
fe23ea2047 update onboarding content without adding or removing slides. The order makes sense now. 2019-09-05 13:49:43 -04:00
5b01b19688 Improvements to config manager + run checks for config files and write them before executing the router subprocess 2019-09-05 01:24:36 +02:00
7664b3530d Misc 2019-09-04 22:37:13 +02:00
87faaa3e74 Misc cleanup + change of default ports to not crash with already existing i2p install 2019-09-04 22:22:10 +02:00
e66bc441d3 Use already set preference 2019-09-04 22:00:39 +02:00
13eaf1f035 Cleanup + added i2p console port to preferences 2019-09-04 21:57:56 +02:00
8106f114ca Cleanup + made firefox spawn i2p on linux 2019-09-04 21:35:51 +02:00
idk
e796ce750f update about:i2p text and onboarding text 2019-09-04 15:02:36 -04:00
idk
7301cbd7ba Merge branch 'master' of https://github.com/mikalv/i2pbutton 2019-09-04 14:44:39 -04:00
3bb805b40c Windows will now run i2p 2019-09-04 19:31:04 +02:00
4a880b973d More fixes 2019-09-03 18:48:30 +02:00
60c455b6af Make paths resolve correctly on windows and linux 2019-09-03 16:50:26 +02:00
9dc5b365ed Bump version to 0.3.0 2019-09-02 22:54:48 +02:00
d754930a66 Change the default preferences to start i2p and shut it down with the browser 2019-09-02 17:26:39 +02:00
0a7a44e05c Initial work for making the browser launch the i2p router 2019-09-02 12:41:59 +02:00
76c4d07a21 Logger updates 2019-08-31 02:29:41 +02:00
idk
721a3b9242 update the content on the about:i2p page 2019-08-28 18:47:39 -04:00
idk
1886a5ffc9 update the content on the about:i2p page 2019-08-28 16:52:29 -04:00
idk
40d97cd420 update the content on the about:i2p page 2019-08-28 16:25:06 -04:00
9fa2ff01b7 i2pcookie stuff 2019-07-26 01:58:04 +02:00
364adf0c8b Make the extensions.i2pbutton.start_i2p preference actually work 2019-07-26 01:57:47 +02:00
3c200e80fb Update package files 2019-07-26 01:57:22 +02:00
3153ee6442 security prefs module 2019-07-26 01:56:59 +02:00
d7f2e84c02 i2pbutton missing functions etc 2019-07-26 01:56:45 +02:00
6993346862 preferences updated 2019-07-26 01:56:17 +02:00
26919254a6 More initial preferences added. 2019-07-25 00:24:35 +02:00
4c0df6593d Noscript control 2019-07-24 03:57:15 +02:00
65e183e129 menu overlay and preferences 2019-07-24 03:03:23 +02:00
e1c719d5e6 Cookie control 2019-07-24 03:03:07 +02:00
61d896354a Mini bump 2019-07-20 09:34:02 +02:00
f38b0b29b2 Misc changes 2019-07-20 09:23:22 +02:00
be15eef145 Search plugins of i2p search engines that seems up 2019-07-20 09:21:26 +02:00
ad295b5007 Merge branch 'master' of github.com:mikalv/i2pbutton 2019-07-20 09:19:33 +02:00
81cdb918b2 Preferences update 2019-07-20 09:19:26 +02:00
56c4187687 Update browserOnboarding.properties
Remove ddg onion text.
2019-07-11 19:38:03 +02:00
fec6e62941 Improvements, ensure the router is only executed once 2019-06-12 20:55:28 +02:00
9ee26aadf4 Implementation of I2P Process Service which is capable to launch a jlinked i2p 2019-06-12 20:05:04 +02:00
8d971606cf corrections in strings 2019-06-10 08:31:05 +02:00
38 changed files with 4219 additions and 439 deletions

View File

@ -15,6 +15,7 @@ overlay chrome://browser/content/aboutDialog.xul chrome://i2pbutton/content/abou
# UI customization
overlay chrome://browser/content/browser.xul chrome://i2pbutton/content/menu-items-overlay.xul
overlay chrome://browser/content/browser.xul chrome://i2pbutton/content/menu-overlay.xul
# Strings for the about:ibupdate page
override chrome://browser/locale/aboutIBUpdate.dtd chrome://i2pbutton/locale/aboutIBUpdate.dtd
@ -43,6 +44,17 @@ contract @geti2p.net/i2pbutton-i2pCheckService;1 {5d57312b-5d8c-4169-b4af-e80d6a
component {f36d72c9-9718-4134-b550-e109638331d7} components/i2pbutton-logger.js
contract @geti2p.net/i2pbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d7}
component {E2AA62BB-AFD0-4D94-9408-90CE39784086} components/router-config-manager.js
contract @geti2p.net/i2pbutton-router-config-mgr;1 {E2AA62BB-AFD0-4D94-9408-90CE39784086}
component {f77babef-dead-b00b-beff-babe6c9afda7} components/i2p-router-process.js
contract @geti2p.net/i2pbutton-process-service;1 {f77babef-dead-b00b-beff-babe6c9afda7}
component {aa132730-beef-dead-babe-0800200c9a66} components/about-outproxies.js
contract @geti2p.net/i2pbutton-about-outproxies;1 {aa132730-beef-dead-babe-0800200c9a66}
category profile-after-change I2PProcessService @geti2p.net/i2pbutton-process-service;1
category profile-after-change CookieJarSelector @geti2p.net/cookie-jar-selector;1
category profile-after-change StartupObserver @geti2p.net/startup-observer;1

View File

@ -99,7 +99,7 @@ var AboutI2pListener = {
onLocaleChange: function(aLocale) {
// Display the Tor Browser product name and version.
// Display the I2P Browser product name and version.
try {
const kBrandBundle = "chrome://branding/locale/brand.properties";
let brandBundle = Cc["@mozilla.org/intl/stringbundle;1"]

View File

@ -33,25 +33,36 @@ window.addEventListener("pageshow", function() {
<div class='content'>
<div class='section-header'>
<h1>&aboutI2p.browser_name;</h1>
</div>
</div>
<div id="i2pbrowser-version"></div>
<p>
&aboutI2p.browser_name; ( &aboutI2p.browser_short_name; ) &aboutI2p.browser_description;
&aboutI2p.browser_name; ( &aboutI2p.browser_short_name; ) &aboutI2p.browser_description; <br />
&aboutI2p.startup; <a href="&aboutI2p.routerconsole;">&aboutI2p.rc;</a> &aboutI2p.startup_b;
<h3>&aboutI2p.links;</h3>
<p>
&aboutI2p.source;: <a href="https://github.com/mikalv/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3">https://github.com/mikalv/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3</a><br />
&aboutI2p.bug_tracker;: <a href="https://trac.i2p2.de/">https://trac.i2p2.de/</a><br />
&aboutI2p.build_scripts;: <a href="https://github.com/mikalv/i2p-browser-build-scripts">https://github.com/mikalv/i2p-browser-build-scripts</a><br />
&aboutI2p.i2pbutton_source;: <a href="https://github.com/mikalv/i2pbutton">https://github.com/mikalv/i2pbutton</a><br />
<ul>
<li>&aboutI2p.source;: <a href="&aboutI2p.github;/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3">&aboutI2p.github;/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3</a></li>
<li>&aboutI2p.design;: <a href="&aboutI2p.github;/i2p-browser-design-docs">&aboutI2p.github;/i2p-browser-design-docs</a></li>
<li>&aboutI2p.bug_tracker;: <a href="&aboutI2p.trac;/">&aboutI2p.trac;/</a></li>
<li>&aboutI2p.build_scripts;: <a href="&aboutI2p.github;/i2p-browser-build-scripts">&aboutI2p.github;/i2p-browser-build-scripts</a></li>
<li>&aboutI2p.i2pbutton_source;: <a href="&aboutI2p.github;/i2pbutton">&aboutI2p.github;/i2pbutton</a></li>
<li><em>&aboutI2p.donate;: <a href="&aboutI2p.site;/get-involved/donate">&aboutI2p.supportus;</a></em></li>
</ul>
</p>
&aboutI2p.warn_experimental;
</p>
<p>
&aboutI2p.refresh_text; <a href="about:i2p">&aboutI2p.refresh_link;</a>
<!--<p class="hideIfI2POn">&aboutI2p.warn_not_running; <a href="about:i2p">&aboutI2p.refresh_text;</a> &aboutI2p.reccommend_not_running;</p>-->
<p class="hideIfI2PConsoleOff">&aboutI2p.all_checks_ok;</p>
<p class="hideIfI2PConsoleOff">
<ul>
<li>&aboutI2p.i2ptunnel_visit_msg; <a href="&aboutI2p.routerconsole;/i2ptunnelmgr">&aboutI2p.i2ptunnel;</a></li>
<li>&aboutI2p.email_visit_msg; <a href="&aboutI2p.routerconsole;/webmail">&aboutI2p.email;</a></li>
<li>&aboutI2p.torrent_visit_msg; <a href="&aboutI2p.routerconsole;/torrents">&aboutI2p.torrent;</a></li>
<li>&aboutI2p.console_visit_msg; <a href="&aboutI2p.routerconsole;">&aboutI2p.console;</a></li>
</ul>
</p>
<p class="hideIfI2POn">&aboutI2p.warn_not_running;</p>
<p class="hideIfI2POff">&aboutI2p.all_checks_ok;</p>
<p class="hideIfI2PConsoleOff">&aboutI2p.console_visit_msg; <a href="http://127.0.0.1:7657">&aboutI2p.console;</a></p>
</div>
</div>
</div>

View File

@ -5,7 +5,7 @@
<overlay id="i2pbutton-extensions-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox id="plugin-enable-button" class="alert-container" flex="1"
<!-- <vbox id="plugin-enable-button" class="alert-container" flex="1"
hidden="true">
<spacer class="alert-spacer-before"/>
<vbox class="alert">
@ -23,6 +23,6 @@
tooltiptext="&plugins.installed.disable.tip;"
command="cmd_pluginDisable"/>
<spacer flex="5000"/>
</vbox>
</vbox>-->
</overlay>

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
class="toolbarbutton-1 chromeclass-toolbar-additional"
type="menu"
orient="horizontal"
label="I2pbutton"
label="I2Pbutton"
tooltiptext="&i2pbutton.button.tooltip;"
menu="i2pbutton-context-menu"
context="i2pbutton-context-menu"/>

View File

@ -1,5 +1,4 @@
var m_ib_i2plog = Components.classes["@geti2p.net/i2pbutton-logger;1"]
.getService(Components.interfaces.nsISupports).wrappedJSObject;
let m_ib_i2plog = Components.classes["@geti2p.net/i2pbutton-logger;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
var m_ib_string_bundle = i2pbutton_get_stringbundle();
@ -13,6 +12,8 @@ function i2pbutton_log(nLevel, sMsg) {
return true;
}
function i2pbutton_init_security_ui() {}
// get a preferences branch object
// FIXME: this is lame.
function i2pbutton_get_prefbranch(branch_name) {

View File

@ -0,0 +1,383 @@
var cookiesTree = null;
var prefs = null;
var cookies = [];
var protectedCookies = [];
var deletedCookies = [];
var lastCookieSortColumn = "";
var lastCookieSortAscending = false;
var cookiemanager = null;
var selector = null;
//custom tree view, this is how we dynamically add the cookies
var cookiesTreeView = {
rowCount : 0,
setTree : function(tree){},
getImageSrc : function(row,column) {},
getProgressMode : function(row,column) {},
getCellValue : function(row,column) {},
getCellText : function(row,column){
var rv="";
switch (column.id) {
case "domainCol" : rv = cookies[row].rawHost; break;
case "nameCol" : rv = cookies[row].name; break;
case "lockCol" : rv = cookies[row].isProtected; break;
case "pathCol" : rv = cookies[row].path; break;
}
return rv;
},
isSeparator : function(index) {return false;},
isSorted: function() { return false; },
isContainer : function(index) {return false;},
cycleHeader : function(column, aElt) {},
getRowProperties : function(row,column,prop){},
getColumnProperties : function(column,columnElement,prop){},
getCellProperties : function(row,column,prop) {}
};
// XXX: Must match the definition in cookie-jar-selector :/
function Cookie(number,name,value,isDomain,host,rawHost,HttpOnly,path,isSecure,isSession,
expires,isProtected) {
this.number = number;
this.name = name;
this.value = value;
this.isDomain = isDomain;
this.host = host;
this.rawHost = rawHost;
this.isHttpOnly = HttpOnly;
this.path = path;
this.isSecure = isSecure;
this.isSession = isSession;
this.expires = expires;
this.isProtected = isProtected;
}
function initDialog() {
cookiesTree = document.getElementById("cookiesTree");
prefs =Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
selector = Components.classes["@geti2p.net/cookie-jar-selector;1"]
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
//init cookie manager
cookiemanager = Components.classes["@mozilla.org/cookiemanager;1"].getService();
cookiemanager = cookiemanager.QueryInterface(Components.interfaces.nsICookieManager);
var enumerator = cookiemanager.enumerator;
var count = 0;
getProtectedCookies();
while (enumerator.hasMoreElements()) {
var nextCookie = enumerator.getNext();
if (!nextCookie) break;
nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);
var host = nextCookie.host;
var isProt = checkIfProtected(nextCookie.name, host, nextCookie.path);
//populate list
cookies[count] =
new Cookie(count++, nextCookie.name, nextCookie.value, nextCookie.isDomain, host,
(host.charAt(0)==".") ? host.substring(1,host.length) : host, nextCookie.isHttpOnly,
nextCookie.path, nextCookie.isSecure, nextCookie.isSession, nextCookie.expires,
isProt);
}
//apply custom view
cookiesTreeView.rowCount = cookies.length;
cookiesTree.treeBoxObject.view = cookiesTreeView;
document.getElementById('defaultCookieGroup').selectedIndex = prefs.getBoolPref("extensions.i2pbutton.cookie_auto_protect")? 0 : 1;
}
function protectCookie()
{
ProtectInTree(cookiesTree, cookiesTreeView,
cookies, "protectCookie", "unprotectCookie", "removeCookie");
}
function unprotectCookie() {
UnProtectInTree(cookiesTree, cookiesTreeView,
cookies, "protectCookie", "unprotectCookie", "removeCookie");
}
function checkIfProtected(name, host, path)
{
for (var i = 0; i < protectedCookies.length; i++)
{
var cookie = protectedCookies[i];
if (cookie.name == name && cookie.host == host && cookie.path == path)
return true;
}
return false;
}
function itemSelected() {
var selections = getTreeSelections(cookiesTree);
if (selections.length) {
//DY - check if (the last in list) selection is protected/unprotected, set buttons
if (cookies[selections[(selections.length)-1]].isProtected) {
document.getElementById("removeCookie").disabled = true;
document.getElementById("unprotectCookie").disabled = false;
document.getElementById("protectCookie").disabled = true;
} else {
document.getElementById("removeCookie").disabled = false;
document.getElementById("unprotectCookie").disabled = true;
document.getElementById("protectCookie").disabled = false;
}
}
}
function acceptDialog() {
FinalizeCookieDeletions();
var protectedcount = 0;
var protcookies = [];
for (var i = 0; i < cookies.length; i++)
{
if (cookies[i].isProtected)
{
protcookies[protectedcount] = cookies[i];
protectedcount++;
}
}
selector.protectCookies(protcookies);
//output protected cookies
prefs.setBoolPref("extensions.i2pbutton.cookie_auto_protect",document.getElementById('saveAllCookies').selected);
}
function CookieColumnSort(column) {
lastCookieSortAscending =
SortTree(cookiesTree, cookiesTreeView, cookies,
column, lastCookieSortColumn, lastCookieSortAscending);
lastCookieSortColumn = column;
}
function DeleteCookie() {
//DY - check if any selection is protected
var selections = getTreeSelections(cookiesTree);
var protect = false;
var i;
for (i=0; i<selections.length; i++) {
if (cookies[selections[i]].isProtected) {
protect = true;
}
}
if (!protect && i>0 ) {
DeleteSelectedItemFromTree(cookiesTree, cookiesTreeView,
cookies, deletedCookies,
"removeCookie", "removeAllCookies",
"protectCookie", "unprotectCookie");
if (!cookies.length) {
;//ClearCookieProperties();
}
}
}
function getProtectedCookies()
{
var gotCookies = selector.getProtectedCookies("tor");
if (gotCookies == null)
return;
protectedCookies = gotCookies;
}
//Tree Utils
function SortTree(tree, view, table, column, lastSortColumn, lastSortAscending, updateSelection) {
// remember which item was selected so we can restore it after the sort
var selections = getTreeSelections(tree);
var selectedNumber = selections.length ? table[selections[0]].number : -1;
// determine if sort is to be ascending or descending
var ascending = (column == lastSortColumn) ? !lastSortAscending : true;
// do the sort or re-sort
var compareFunc = function compare(first, second) {
if (column=="isProtected") {
return second[column].toString().localeCompare(first[column].toString());
} else {
return first[column].toLowerCase().localeCompare(second[column].toLowerCase());
}
}
table.sort(compareFunc);
if (!ascending)
table.reverse();
// restore the selection
var selectedRow = -1;
if (selectedNumber>=0 && updateSelection) {
for (var s=0; s<table.length; s++) {
if (table[s].number == selectedNumber) {
// update selection
// note: we need to deselect before reselecting in order to trigger ...Selected()
tree.view.selection.select(-1);
tree.view.selection.select(s);
selectedRow = s;
break;
}
}
}
// display the results
tree.treeBoxObject.invalidate();
if (selectedRow >= 0) {
tree.treeBoxObject.ensureRowIsVisible(selectedRow)
}
return ascending;
}
function FinalizeCookieDeletions() {
for (var c=0; c<deletedCookies.length; c++) {
cookiemanager.remove(deletedCookies[c].host,
deletedCookies[c].name,
deletedCookies[c].path,
false);
}
deletedCookies.length = 0;
}
function getTreeSelections(tree) {
var selections = [];
var select;
select = tree.view.selection;
if (select) {
var count = select.getRangeCount();
var min = new Object();
var max = new Object();
for (var i=0; i<count; i++) {
select.getRangeAt(i, min, max);
for (var k=min.value; k<=max.value; k++) {
if (k != -1) {
selections[selections.length] = k;
}
}
}
}
return selections;
}
function ProtectInTree
(tree, view, table, protButton, unprotButton, removeButton) {
var selections = getTreeSelections(tree);
for (var s=selections.length-1; s>= 0; s--) {
var i = selections[s];
table[i].isProtected = true;
}
//update tree view
tree.treeBoxObject.invalidate();
//DY - Update selections
tree.treeBoxObject.ensureRowIsVisible(selections[0]);
// disable/enable buttons
document.getElementById(unprotButton).disabled = false;
document.getElementById(protButton).disabled = true;
document.getElementById(removeButton).disabled = true;
}
function UnProtectInTree
(tree, view, table, protButton, unprotButton, removeButton) {
var selections = getTreeSelections(tree);
for (var s=selections.length-1; s>= 0; s--) {
var i = selections[s];
table[i].isProtected = false;
}
//update tree view
tree.treeBoxObject.invalidate();
//DY - Update selections
tree.treeBoxObject.ensureRowIsVisible(selections[0]);
// disable/enable buttons
document.getElementById(unprotButton).disabled = true;
document.getElementById(protButton).disabled = false;
document.getElementById(removeButton).disabled = false;
}
function DeleteAllCookies() {
DeleteAllFromTree(cookiesTree, cookiesTreeView,
cookies, deletedCookies,
"removeCookie", "removeAllCookies",
"protectCookie", "unprotectCookie");
}
function DeleteSelectedItemFromTree
(tree, view, table, deletedTable, removeButton, removeAllButton, protButton, unprotButton) {
var selections = getTreeSelections(tree);
tree.view.selection.clearSelection();
// remove selected items from list (by setting them to null) and place in deleted list
for (var s=selections.length-1; s>= 0; s--) {
var i = selections[s];
deletedTable[deletedTable.length] = table[i];
table[i] = null;
}
// collapse list by removing all the null entries
for (var j=0; j<table.length; j++) {
if (table[j] == null) {
var k = j;
while ((k < table.length) && (table[k] == null)) {
k++;
}
table.splice(j, k-j);
view.rowCount -= k - j;
tree.treeBoxObject.rowCountChanged(j, j - k);
}
}
//DY - update selection and/or buttons
if (table.length) {
//DY - update selection to previous (first of) selected position or bottom
var nextSelection = (selections[0] < table.length) ? selections[0] : table.length-1;
tree.view.selection.select(nextSelection);
tree.treeBoxObject.ensureRowIsVisible(nextSelection);
if (table[nextSelection].isProtected) {
document.getElementById(unprotButton).disabled = false;
document.getElementById(protButton).disabled = true;
} else {
document.getElementById(unprotButton).disabled = true;
document.getElementById(protButton).disabled = false;
}
} else {
// disable buttons
document.getElementById(removeButton).disabled = true;
document.getElementById(removeAllButton).disabled = true;
document.getElementById(unprotButton).disabled = true;
document.getElementById(protButton).disabled = true;
}
}
function DeleteAllFromTree
(tree, view, table, deletedTable, removeButton, removeAllButton, protButton, unprotButton) {
// remove items from table and place in deleted table
for (var i=0; i<table.length; i++) {
//DY - only if unprotected
if (!table[i].isProtected) {
deletedTable[deletedTable.length] = table[i];
table[i] = null;
}
}
tree.view.selection.clearSelection();
//DY - fix up tree
// collapse list by removing all the null entries
for (var j=0; j<table.length; j++) {
if (table[j] == null) {
var k = j;
while ((k < table.length) && (table[k] == null)) {
k++;
}
table.splice(j, k-j);
view.rowCount -= k - j;
tree.treeBoxObject.rowCountChanged(j, j - k);
}
}
// update selection and/or buttons
if (table.length) {
// update selection to top
tree.view.selection.select(0);
tree.treeBoxObject.ensureRowIsVisible(0);
//if it exists is must already be protected
document.getElementById(unprotButton).disabled = false;
document.getElementById(protButton).disabled = true;
} else {
// disable all buttons
document.getElementById(removeButton).disabled = true;
document.getElementById(removeAllButton).disabled = true;
document.getElementById(unprotButton).disabled = true;
document.getElementById(protButton).disabled = true;
}
}

View File

@ -0,0 +1,71 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://i2pbutton/skin/i2pbutton.css" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://i2pbutton/locale/i2pbutton.dtd">
<dialog id="TorCookieDialog"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&i2pbutton.cookiedialog.title;"
buttons="accept,cancel"
style="width: 30em;"
onload="initDialog();"
ondialogaccept="acceptDialog();"
persist="screenX screenY width height">
<script src="chrome://i2pbutton/content/i2pbutton.js" type="application/x-javascript"/>
<script src="chrome://i2pbutton/content/i2pcookie.js" type="application/x-javascript"/>
<stringbundleset id="i2pbutton-stringbundleset">
<stringbundle id="i2pbutton-bundle" src="chrome://i2pbutton/locale/i2pbutton.properties"/>
</stringbundleset>
<label value=""/>
<separator class="thin"/>
<vbox flex="1">
<tree id="cookiesTree" flex="1" style="height: 10em;"
onkeypress="return;//do this later"
onselect="itemSelected();"
hidecolumnpicker="true">
<treecols>
<treecol id="lockCol" label="&i2pbutton.cookiedialog.lockCol;" flex="1"
onclick="CookieColumnSort('isProtected', true);" persist="width"/>
<splitter class="tree-splitter"/>
<treecol id="domainCol" label="&i2pbutton.cookiedialog.domainCol;" flex="2"
onclick="CookieColumnSort('rawHost', true);" persist="width"/>
<splitter class="tree-splitter"/>
<treecol id="nameCol" label="&i2pbutton.cookiedialog.nameCol;" flex="1"
onclick="CookieColumnSort('name', true);" persist="width"/>
<treecol id="pathCol" label="&i2pbutton.cookiedialog.pathCol;" flex="1"
onclick="CookieColumnSort('path', true);" persist="width"/>
</treecols>
<treechildren/>
</tree>
</vbox>
<groupbox>
<hbox>
<vbox>
<button id="protectCookie" disabled="true"
label="&i2pbutton.cookiedialog.protectCookie;"
oncommand="protectCookie();"/>
<button id="removeCookie" disabled="true"
label="&i2pbutton.cookiedialog.removeCookie;"
oncommand="DeleteCookie();"/>
</vbox>
<vbox>
<button id="unprotectCookie" disabled="true"
label="&i2pbutton.cookiedialog.unprotectCookie;"
oncommand="unprotectCookie();"/>
<button id="removeAllCookies"
label="&i2pbutton.cookiedialog.removeAllBut;"
oncommand="DeleteAllCookies();"/>
</vbox>
</hbox>
<hbox>
<radiogroup id="defaultCookieGroup">
<radio id="saveAllCookies" label="&i2pbutton.cookiedialog.saveAllCookies;" />
<radio id="donnotsaveCookies" label="&i2pbutton.cookiedialog.doNotSaveAllCookies;" />
</radiogroup>
</hbox>
</groupbox>
</dialog>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- Mode: HTML -*- -->
<!DOCTYPE overlay SYSTEM "chrome://i2pbutton/locale/aboutI2p.dtd">
<overlay id="i2pbutton-menu-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<menupopup id="menu_HelpPopup">
<!-- Bug 18905: Hide unused help menu items -->
<menuitem id="menu_openHelp" removeelement="true"/>
<menuitem id="menu_openTour" removeelement="true"/>
<menuitem id="healthReport" removeelement="true"/>
<menuitem id="feedbackPage" removeelement="true"/>
<menuitem id="helpSafeMode" removeelement="true"/>
<menuitem id="menu_HelpPopup_reportPhishingtoolmenu" removeelement="true"/>
<menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu" removeelement="true"/>
<!-- dummy elements to avoid 'getElementById' errors -->
<box id="feedbackPage"/>
<box id="helpSafeMode"/>
<box id="menu_HelpPopup_reportPhishingtoolmenu"/>
<box id="menu_HelpPopup_reportPhishingErrortoolmenu"/>
<!-- Add I2P Browser manual link -->
<!--<menuitem name="i2pBrowserUserManual"
id="i2pBrowserUserManual"
position="1"
label="&aboutI2p.i2pbrowser_user_manual.label;"
accesskey="&aboutI2p.i2pbrowser_user_manual.accesskey;"
oncommand="gBrowser.selectedTab = gBrowser.addTab('https://geti2p.net/en/browser/' + Services.locale.getRequestedLocale())" />-->
</menupopup>
</overlay>

View File

@ -20,18 +20,17 @@
accesskey="&i2pbutton.context_menu.new_identity_key;"
insertafter="context-stop"
oncommand="i2pbutton_new_identity()"/>
<menuseparator/>
<menuitem id="i2pbutton-cookie-protector"
label="&i2pbutton.context_menu.cookieProtections;"
accesskey="&i2pbutton.context_menu.cookieProtections.key;"
insertafter="context-stop"
insertafter="i2pbutton-new-identity"
hidden="true"
oncommand="i2pbutton_open_cookie_dialog()"/>
<menuseparator id="i2pbutton-checkForUpdateSeparator"/>
<menuitem id="i2pbutton-checkForUpdate"
label="&i2pbutton.context_menu.downloadUpdate;"
accesskey="&i2pbutton.context_menu.downloadUpdate.key;"
insertafter="context-stop"
insertafter="i2pbutton-cookie-protector"
oncommand="i2pbutton_check_for_update()"/>
</vbox>
</hbox>

View File

@ -0,0 +1,83 @@
<!DOCTYPE overlay SYSTEM "chrome://i2pbutton/locale/i2pbutton.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<head>
<title>&i2pbutton.prefs.security_settings;</title>
<link type="text/css" rel="stylesheet" charset="UTF-8" href="chrome://i2pbutton/skin/preferences.css"/>
<script type="text/javascript" src="i2pbutton_util.js"></script>
<style>
</style>
</head>
<body onload="i2pbutton_init_security_ui()">
<div class="wrapper outer-wrapper">
<div class="title">
&i2pbutton.prefs.sec_caption;
</div>
<div class="wrapper inner-wrapper">
<input id="i2pbutton_sec_slider" type="range" min="1" max="3" list="datalist" onchange="i2pbutton_set_slider(parseInt(this.value, 10))"/>
<datalist id="datalist">
<option onclick="i2pbutton_set_slider(1)">
&i2pbutton.prefs.sec_standard_label;
</option>
<option onclick="i2pbutton_set_slider(2)">
&i2pbutton.prefs.sec_safer_label;
</option>
<option onclick="i2pbutton_set_slider(3)">
&i2pbutton.prefs.sec_safest_label;
</option>
</datalist>
<div class="description-wrapper">
<div id="desc_safest" class="description">
<p class="slider-text-size slider-text-weight">
&i2pbutton.prefs.sec_safest_description;
</p>
<p class="slider-text-size slider-text-weight">
&i2pbutton.prefs.sec_safest_list_label;
</p>
<p class="slider-text-size">
&i2pbutton.prefs.sec_js_disabled;
</p>
<p class="slider-text-size">
&i2pbutton.prefs.sec_limit_graphics_and_typography;
</p>
<p class="slider-text-size">
&i2pbutton.prefs.sec_click_to_play_media;
</p>
<a id="link_safest" class="text-link">
&i2pbutton.prefs.sec_learn_more_label;
</a>
</div>
<div id="desc_safer" class="description">
<p class="slider-text-size slider-text-weight">
&i2pbutton.prefs.sec_safer_description;
</p>
<p class="slider-text-size slider-text-weight">
&i2pbutton.prefs.sec_safer_list_label;
</p>
<p class="slider-text-size">
&i2pbutton.prefs.sec_js_on_https_sites_only;
</p>
<p class="slider-text-size">
&i2pbutton.prefs.sec_limit_typography;
</p>
<p class="slider-text-size">
&i2pbutton.prefs.sec_click_to_play_media;
</p>
<a id="link_safer" class="text-link">
&i2pbutton.prefs.sec_learn_more_label;
</a>
</div>
<div id="desc_standard" class="description">
<p class="slider-text-size slider-text-weight">
&i2pbutton.prefs.sec_standard_description;
</p>
<a id="link_standard" class="text-link">
&i2pbutton.prefs.sec_learn_more_label;
</a>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,216 @@
const Cc = Components.classes
const Ci = Components.interfaces
const Cu = Components.utils
const kI2PProcessExitedTopic = "I2PProcessExited"
const kBootstrapStatusTopic = "I2PBootstrapStatus"
const kI2PBootstrapErrorTopic = "I2PBootstrapError"
const kI2PLogHasWarnOrErrTopic = "I2PLogHasWarnOrErr"
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
const I2PLauncherLogger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
var gObsSvc
var gOpenerCallbackFunc // Set when opened from network settings.
var gIsInitialBootstrap
var gInitialPanelID
function closeThisWindow(reason) {
dump('closeThisWindow\n')
window.close()
}
function initDialog()
{
// If i2p bootstrap has already finished, just close the progress dialog.
// This situation can occur if bootstrapping is very fast and/or if this
// window opens s vlowly (observed with Adblock Plus installed).
try
{
let processSvc = Cc["@geti2p.net/i2pbutton-process-service;1"].getService(Ci.nsISupports).wrappedJSObject
if (processSvc.I2PIsBootstrapDone || processSvc.I2PBootstrapErrorOccurred)
{
closeThisWindow(processSvc.I2PIsBootstrapDone)
return
}
}
catch (e) { dump(`${e}\n`) }
try
{
gObsSvc = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
gObsSvc.addObserver(gObserver, kI2PProcessExitedTopic, false)
gObsSvc.addObserver(gObserver, kBootstrapStatusTopic, false)
gObsSvc.addObserver(gObserver, kI2PBootstrapErrorTopic, false)
gObsSvc.addObserver(gObserver, kI2PLogHasWarnOrErrTopic, false)
var isBrowserStartup = false
if (window.arguments)
{
let wargs = window.arguments || window.arguments.wrappedJSObject
isBrowserStartup = wargs[0]
dump(`window.arguments = ${wargs}\n`)
dump(`window.arguments.length = ${wargs.length}\n`)
if (window.arguments.length > 1)
gInitialPanelID = window.arguments[1]
}
if (gOpenerCallbackFunc)
{
// Dialog was opened from network settings: hide Open Settings button.
var extraBtn = document.documentElement.getButton("extra2")
extraBtn.setAttribute("hidden", true)
}
else
{
// Dialog was not opened from network settings: change Cancel to Quit.
var cancelBtn = document.documentElement.getButton("cancel")
var quitKey = (LauncherUtil.isWindows) ? "quit_win" : "quit"
cancelBtn.label = 'Cancel'//LauncherUtil.getLocalizedString(quitKey)
}
// If opened during browser startup, display the "please wait" message.
if (isBrowserStartup)
{
var pleaseWait = document.getElementById("progressPleaseWait")
if (pleaseWait)
pleaseWait.removeAttribute("hidden")
}
// Test if the i2p console port is open or not
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
LauncherUtil.waitForPortToOpen(consolePort, () => {
var meter = document.getElementById("progressMeter")
if (meter) {
meter.value = meter.value + 30
}
setTimeout(() => {
window.close()
}, 5000)
})
}
catch (e) {
dump(`Error: ${e}\n`)
}
dump('initDialog done\n')
}
function onCancel() {
//
dump('onCancel\n')
cleanup()
}
function cleanup()
{
if (gObsSvc)
{
gObsSvc.removeObserver(gObserver, kI2PProcessExitedTopic)
gObsSvc.removeObserver(gObserver, kBootstrapStatusTopic)
gObsSvc.removeObserver(gObserver, kI2PBootstrapErrorTopic)
gObsSvc.removeObserver(gObserver, kI2PLogHasWarnOrErrTopic)
}
}
function onOpenSettings()
{
//stopI2PBootstrap()
//cleanup()
window.close()
}
function stopI2PBootstrap()
{
// Tell i2p to disable use of the network; this should stop the bootstrap
// process.
const kErrorPrefix = "Setting DisableNetwork=1 failed: ";
try
{
var settings = {};
settings["DisableNetwork"] = true;
var errObj = {};
I2PLauncherLogger.log(5, kErrorPrefix + errObj.details);
}
catch(e)
{
I2PLauncherLogger.log(5, kErrorPrefix + e);
}
}
var gObserver = {
// nsIObserver implementation.
observe: function(aSubject, aTopic, aParam)
{
if ((kI2PProcessExitedTopic == aTopic) ||
(kI2PBootstrapErrorTopic == aTopic))
{
// In these cases, an error alert will be displayed elsewhere so it is
// best to close this window.
// TODO: provide a way to access tor log e.g., leave this dialog open
// and display the open settings button or provide a way to do
// that from our error alerts.
if (kI2PBootstrapErrorTopic == aTopic)
stopI2PBootstrap();
cleanup();
window.close();
}
else if (kBootstrapStatusTopic == aTopic)
{
var statusObj = aSubject.wrappedJSObject
var labelText = LauncherUtil.getLocalizedBootstrapStatus(statusObj, "TAG")
var percentComplete = (statusObj.PROGRESS) ? statusObj.PROGRESS : 0
var meter = document.getElementById("progressMeter")
if (meter)
meter.value = percentComplete
var bootstrapDidComplete = (percentComplete >= 100)
if (percentComplete >= 100)
{
// To ensure that 100% progress is displayed, wait a short while
// before closing this window.
window.setTimeout(function() { closeThisWindow(true) }, 250)
}
else if (statusObj._errorOccurred)
{
var s = LauncherUtil.getLocalizedBootstrapStatus(statusObj, "REASON");
if (s)
labelText = s;
if (meter)
meter.setAttribute("hidden", true);
var pleaseWait = document.getElementById("progressPleaseWait");
if (pleaseWait)
pleaseWait.setAttribute("hidden", true);
}
var desc = document.getElementById("progressDesc");
if (labelText && desc)
desc.textContent = labelText;
}
else if (kI2PLogHasWarnOrErrTopic == aTopic)
{
var extra2Btn = document.documentElement.getButton("extra2");
var clz = extra2Btn.getAttribute("class");
extra2Btn.setAttribute("class", clz ? clz + " i2pWarning" : "i2pWarning");
// TODO: show error / warning message in this dialog?
}
},
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0"?>
<!--
- Copyright (c) 2019, The Invisible Internet Project.
- See LICENSE for licensing information.
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://i2pbutton/skin/progress.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://i2pbutton/locale/progress.dtd">
<dialog id="I2PProgress"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&i2pprogress.dialog.title;"
windowtype="I2PLauncher:Progress"
persist="screenX screenY"
buttons="cancel"
buttonlabelextra2="&i2pprogress.openSettings;"
ondialogcancel="onCancel();"
ondialogextra2="onOpenSettings();"
onload="initDialog();"> <!-- extra2 was removed from buttons for now. -->
<script type="application/x-javascript"
src="chrome://i2pbutton/content/progress.js"/>
<vbox>
<hbox>
<vbox>
<spacer flex="1" />
<image id="ibb-icon" />
<spacer flex="1" />
</vbox>
<separator orient="vertical" />
<vbox flex="1">
<label id="progressHeading" value="&i2pprogress.heading;" />
<description id="progressDesc" />
</vbox>
</hbox>
<progressmeter id="progressMeter" mode="determined" value="0" max="100" />
<description id="progressPleaseWait"
hidden="true">&i2pprogress.pleaseWait;</description>
</vbox>
</dialog>

View File

@ -5,21 +5,36 @@
<!ENTITY aboutI2p.browser_name "The Invisible Internet Browser">
<!ENTITY aboutI2p.browser_short_name "I2P Browser">
<!ENTITY aboutI2p.browser_description "is preconfigured to search for content on the I2P network. In this release, I2P Browser does not launch its own router and is dependent on having the I2P router pre installed and running. The I2P Browser is preconfigured with default router settings.">
<!ENTITY aboutI2p.browser_description "is preconfigured to get your content using the anonymous and private I2P network. In this release, I2P Browser bundles it's own I2P Router, which starts and stops when you open and close the browser application. It does not require an existing I2P router installed.">
<!ENTITY aboutI2p.donate "Donate">
<!ENTITY aboutI2p.supportus "Support I2P development">
<!ENTITY aboutI2p.warn_not_running "It currently seems like your router is NOT running :( However, if you just started the router, please try again in two minutes cause it need time to start.">
<!ENTITY aboutI2p.warn_not_running "It currently seems like your router is NOT running :(">
<!ENTITY aboutI2p.reccommend_not_running "If you just started the router, it may take up to 2 minutes for the router to start the proxy.">
<!ENTITY aboutI2p.all_checks_ok "Super! The browser detected I2P running in background! :)">
<!ENTITY aboutI2p.warn_experimental "This is a experimental sub-project of I2P.">
<!ENTITY aboutI2p.console_visit_msg "It seems like your console is up, click the to visit:">
<!ENTITY aboutI2p.warn_experimental "This is a experimental sub-project of I2P. It is currently Beta software.">
<!ENTITY aboutI2p.console_visit_msg "It seems like your console is up, click to visit:">
<!ENTITY aboutI2p.i2ptunnel_visit_msg "I2P has a web-based interface for configuring .i2p services like web sites, to set up your own web sites, go here:">
<!ENTITY aboutI2p.email_visit_msg "I2P also bundles a webmail client which can be used to access in-I2P e-mail. To use it, go here:">
<!ENTITY aboutI2p.torrent_visit_msg "I2P is capable of anonymous Peer-to-Peer file sharing, to use the built-in bittorrent client go here:">
<!ENTITY aboutI2p.console "Console">
<!ENTITY aboutI2p.torrent "Torrents">
<!ENTITY aboutI2p.i2ptunnel "Tunnels">
<!ENTITY aboutI2p.email "E-Mail">
<!ENTITY aboutI2p.i2pbutton_source "I2P Button source">
<!ENTITY aboutI2p.build_scripts "Build scripts">
<!ENTITY aboutI2p.source "Source">
<!ENTITY aboutI2p.bug_tracker "Bugtracker">
<!ENTITY aboutI2p.build_scripts "Build scripts to compile from source">
<!ENTITY aboutI2p.source "Browse the source code">
<!ENTITY aboutI2p.bug_tracker "Submit a Bug Report">
<!ENTITY aboutI2p.links "Links">
<!ENTITY aboutI2p.refresh_text "Click the link to refresh the page (In case the router is starting up):">
<!ENTITY aboutI2p.design "Design Document">
<!ENTITY aboutI2p.refresh_text "Try refreshing the page.">
<!ENTITY aboutI2p.refresh_link "Refresh">
<!ENTITY aboutI2p.getInvolved.label "Get Involved »">
<!ENTITY aboutI2p.getInvolved.link "https://geti2p.net/en/get-involved">
<!ENTITY aboutI2p.site "http://i2p-projekt.i2p/en">
<!ENTITY aboutI2p.routerconsole "http://localhost:7647">
<!ENTITY aboutI2p.github "https://github.com/mikalv">
<!ENTITY aboutI2p.trac "http://trac.i2p2.i2p">
<!ENTITY aboutI2p.startup "Sometimes it takes a minute or two for I2P to get started for the first time. While you wait, visit the">
<!ENTITY aboutI2p.startup_b "to get acquainted with all the capabilities of I2P.">
<!ENTITY aboutI2p.rc "Router Console">

View File

@ -1,44 +1,53 @@
# vim: set sw=2 sts=2 ts=8 et:
onboarding.tour-i2p-welcome=Welcome
onboarding.tour-i2p-welcome.title=Youre ready.
onboarding.tour-i2p-welcome.description=I2P Browser offers the highest standard of privacy and security while browsing the web. Youre now protected against tracking, surveillance, and censorship. This quick onboarding will show you how.
onboarding.tour-i2p-welcome.title=Welcome to I2P Browser
onboarding.tour-i2p-welcome.description=I2P Browser allows you to surf the internet using the private and secure I2P network. When using it, you are protected against tracking, surveillance, and censorship as a first-class participant in the I2P network.
# onboarding.tour-i2p-welcome.description-suffix=I2P Browser isolates cookies and deletes your browser history after your session. These modifications ensure your privacy and security are protected in the browser.
onboarding.tour-i2p-welcome.next-button=Go to Privacy
onboarding.tour-i2p-privacy=Privacy
onboarding.tour-i2p-privacy.title=Snub trackers and snoopers.
onboarding.tour-i2p-privacy.description=I2P Browser isolates cookies and deletes your browser history after your session. These modifications ensure your privacy and security are protected in the browser. Click I2P Network to learn how we protect you on the network level.
onboarding.tour-i2p-privacy.button=Go to I2P Network
onboarding.tour-i2p-privacy.title=Stay in control of your Data
onboarding.tour-i2p-privacy.description=I2P Browser isolates cookies and deletes your browser history after your session. These modifications ensure your privacy and security are protected in the browser.
onboarding.tour-i2p-privacy.button=Go to Security and Experience
onboarding.tour-i2p-network=I2P Network
# This slide is not currently use in the I2P Browser Onboarding slideshow
#onboarding.tour-i2p-network=I2P Network
onboarding.tour-i2p-network.title=Travel a decentralized network.
onboarding.tour-i2p-network.description=I2P Browser connects you to the I2P network run by thousands of volunteers around the world. Unlike a VPN, theres no one point of failure or centralized entity you need to trust in order to enjoy the internet privately.
onboarding.tour-i2p-network.button=Go to Tunnel Display
# End
# This slide is not currently use in the I2P Browser Onboarding slideshow
onboarding.tour-i2p-circuit-display=Tunnel Display
onboarding.tour-i2p-circuit-display.title=See your path.
onboarding.tour-i2p-circuit-display.description=For each domain you visit, your traffic is relayed and encrypted in a tunnel across three I2P routers around the world. Currently displaying this information is still under development.
onboarding.tour-i2p-circuit-display.button=Sorry, come back later.
onboarding.tour-i2p-circuit-display.next-button=Go to Security
# end
onboarding.tour-i2p-security=Security
onboarding.tour-i2p-security=Security and Experience
onboarding.tour-i2p-security.title=Choose your experience.
onboarding.tour-i2p-security.description=We also provide you with additional settings for bumping up your browser security. Our Security Settings allow you to block elements that could be used to attack your computer. Click below to see what the different options do.
onboarding.tour-i2p-security.description-suffix=Note: By default, NoScript and HTTPS Everywhere are not included on the toolbar, but you can customize your toolbar to add them.
onboarding.tour-i2p-security.description=We also provide you with additional settings for bumping up your browser security. Our Security Settings allow you to block elements that could be used to attack your computer. Click below to see what the different options do.\n Note: By default, NoScript and HTTPS Everywhere are not included on the toolbar, but you can customize your toolbar to add them.
onboarding.tour-i2p-security.description-suffix=With all the security and privacy features provided by I2P, your experience while browsing the internet may be a little different. Things may be a bit slower, and depending on your security level, some elements may not work or load. You may also be asked to prove you are a human and not a robot.
onboarding.tour-i2p-security-level.button=See Your Security Level
onboarding.tour-i2p-security-level.next-button=Go to Experience Tips
onboarding.tour-i2p-expect-differences=Experience Tips
onboarding.tour-i2p-expect-differences.title=Expect some differences.
onboarding.tour-i2p-expect-differences.description=With all the security and privacy features provided by I2P, your experience while browsing the internet may be a little different. Things may be a bit slower, and depending on your security level, some elements may not work or load. You may also be asked to prove you are a human and not a robot.
onboarding.tour-i2p-expect-differences.button=See FAQs
onboarding.tour-i2p-expect-differences.next-button=Go to Hidden Services
onboarding.tour-i2p-expect-differences.button=Done
# onboarding.tour-i2p-expect-differences.button=See FAQs
onboarding.tour-i2p-expect-differences.next-button=Done
# onboarding.tour-i2p-expect-differences.next-button=Go to Hidden Services
onboarding.tour-i2p-onion-services=Hidden Services
onboarding.tour-i2p-onion-services.title=Be extra protected.
onboarding.tour-i2p-onion-services.description=Hidden services are sites that end with a .i2p that provide extra protections to publishers and visitors, including added safeguards against censorship. Onion services allow anyone to provide content and services anonymously. Click below to visit the DuckDuckGo onion site.
onboarding.tour-i2p-onion-services.button=Visit an Hidden
onboarding.tour-i2p-onion-services.next-button=Done
# This slide is not currently use in the I2P Browser Onboarding slideshow
#onboarding.tour-i2p-onion-services=Hidden Services
#onboarding.tour-i2p-onion-services.title=Be extra protected.
#onboarding.tour-i2p-onion-services.description=Hidden services are sites that end with a .i2p that provide extra protections to publishers and visitors, including added safeguards against censorship. Onion services allow anyone to provide content and services anonymously.
#onboarding.tour-i2p-onion-services.button=Visit an Hidden
#onboarding.tour-i2p-onion-services.next-button=Done
# End
onboarding.overlay-icon-tooltip-updated2=See what's new\nin %S
onboarding.tour-i2p-update.prefix-new=New

View File

@ -15,7 +15,7 @@ i2pbutton.panel.label.disabled = I2P Disabled
i2pbutton.panel.label.enabled = I2P Enabled
extensions.i2pbutton@geti2p.net.description = i2pbutton provides a button to configure I2P settings and quickly and easily clear private browsing data.
i2pbutton.popup.external.title = Download an external file type?
i2pbutton.popup.external.app = Tor Browser cannot display this file. You will need to open it with another application.\n\n
i2pbutton.popup.external.app = I2P Browser cannot display this file. You will need to open it with another application.\n\n
i2pbutton.popup.external.note = Some types of files can cause applications to connect to the Internet without using I2P.\n\n
i2pbutton.popup.external.suggest = To be safe, you should only open downloaded files while offline, or use a I2P Live CD such as Tails.\n
i2pbutton.popup.launch = Download file
@ -24,12 +24,12 @@ i2pbutton.popup.dontask = Automatically download files from now on
i2pbutton.popup.no_newnym = i2pbutton cannot safely give you a new identity. It does not have access to the I2P Control Port.\n\nAre you running I2P Browser Bundle?
i2pbutton.security_settings.menu.title = Security Settings
i2pbutton.title.prompt_i2pbrowser = Important i2pbutton Information
i2pbutton.popup.prompt_i2pbrowser = i2pbutton works differently now: you can't turn it off any more.\n\nWe made this change because it isn't safe to use i2pbutton in a browser that's also used for non-Tor browsing. There were too many bugs there that we couldn't fix any other way.\n\nIf you want to keep using Firefox normally, you should uninstall i2pbutton and download Tor Browser Bundle. The privacy properties of Tor Browser are also superior to those of normal Firefox, even when Firefox is used with i2pbutton.\n\nTo remove i2pbutton, go to Tools->Addons->Extensions and then click the Remove button next to i2pbutton.
i2pbutton.popup.prompt_i2pbrowser = i2pbutton works differently now: you can't turn it off any more.\n\nWe made this change because it isn't safe to use i2pbutton in a browser that's also used for non-I2P browsing. There were too many bugs there that we couldn't fix any other way.\n\nIf you want to keep using Firefox normally, you should uninstall i2pbutton and download I2P Browser Bundle. The privacy properties of I2P Browser are also superior to those of normal Firefox, even when Firefox is used with i2pbutton.\n\nTo remove i2pbutton, go to Tools->Addons->Extensions and then click the Remove button next to i2pbutton.
i2pbutton.popup.short_i2pbrowser = Important i2pbutton Information!\n\ni2pbutton is now always enabled.\n\nClick on the i2pbutton for more information.
i2pbutton.popup.confirm_plugins = Plugins such as Flash can harm your privacy and anonymity.\n\nThey can also bypass I2P to reveal your current location and IP address.\n\nAre you sure you want to enable plugins?\n\n
i2pbutton.popup.never_ask_again = Never ask me again
i2pbutton.popup.confirm_newnym = Tor Browser will close all windows and tabs. All website sessions will be lost.\n\nRestart I2P Browser now to reset your identity?\n\n
i2pbutton.popup.confirm_newnym = I2P Browser will close all windows and tabs. All website sessions will be lost.\n\nRestart I2P Browser now to reset your identity?\n\n
i2pbutton.maximize_warning = Maximizing I2P Browser can allow websites to determine your monitor size, which can be used to track you. We recommend that you leave I2P Browser windows in their original default size.

View File

@ -0,0 +1,4 @@
<!ENTITY i2pprogress.dialog.title "Starting the I2P router">
<!ENTITY i2pprogress.openSettings "Settings">
<!ENTITY i2pprogress.heading "I2P Browser">
<!ENTITY i2pprogress.pleaseWait "Please wait while the router establish a connection to the I2P network. This may take several minutes">

View File

@ -72,3 +72,6 @@ body:not([i2pconsoleon]) .hideIfI2PConsoleOff {
display: none;
}
ul {
margin-left: 2rem;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2019, The Invisible Internet Project.
* See LICENSE for licensing information.
*
* vim: set sw=2 sts=2 ts=8 et syntax=css:
*/
dialog {
width: 400px;
}
#progressHeading {
font-size: 110%;
margin: 8px 0px 8px 0px;
font-weight: bold;
}
#progressPleaseWait {
font-size: 110%;
margin-bottom: 15px;
}
#ibb-icon {
list-style-image: url("chrome://i2pbutton/skin/default48.png");
width: 48px;
height: 48px;
}
#progressDesc {
height: 48px;
}
#progressMeter {
margin-bottom: 16px;
}
.i2pWarning {
list-style-image: url("chrome://i2pbutton/skin/warning.png");
}
/* Ensure that our caution icon is always shown on GTK-based platforms. */
.i2pWarning .button-icon {
display: inline !important;
}

BIN
src/chrome/skin/warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -9,12 +9,11 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
function IBI2PCheckService() {
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"]
.getService(Ci.nsISupports).wrappedJSObject;
this._logger.log(3, "I2pbutton I2P Check Service initialized");
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
this._logger.info("I2pbutton I2P Check Service initialized")
this._statusOfI2PCheck = this.kCheckNotInitiated;
this.wrappedJSObject = this;
this._statusOfI2PCheck = this.kCheckNotInitiated
this.wrappedJSObject = this
}
IBI2PCheckService.prototype =
@ -36,13 +35,15 @@ IBI2PCheckService.prototype =
isConsoleWorking: false,
isProxyWorking: false,
isInProgressOfTestingConsole: false,
isInProgressOfTestingProxy: false,
wrappedJSObject: null,
_logger: null,
_statusOfI2PCheck: 0, // this.kCheckNotInitiated,
// make this an nsIClassInfo object
flags: Ci.nsIClassInfo.DOM_OBJECT,
// make this an singleton object
flags: Ci.nsIClassInfo.SINGLETON,
// method of nsIClassInfo
classDescription: kMODULE_NAME,
@ -72,42 +73,48 @@ IBI2PCheckService.prototype =
init: function () {
let self = this
this.isInProgressOfTestingConsole = true
let req = this.createCheckConsoleRequest(true)
req.onreadystatechange = function (event) {
if (req.readyState === 4) {
self.parseCheckConsoleResponse(req)
self.isInProgressOfTestingConsole = false
}
}
req.send(null)
this.isInProgressOfTestingProxy = true
let proxyReq = this.createCheckProxyRequest(true)
proxyReq.onreadystatechange = function (event) {
if (proxyReq.readyState === 4) {
self.parseCheckProxyResponse(proxyReq)
self.isInProgressOfTestingConsole = false
}
}
proxyReq.send(null)
},
_createRequest: function(url, aAsync, mimetype) {
Cu.importGlobalProperties(["XMLHttpRequest"]);
let req = new XMLHttpRequest();
req.open('GET', url, aAsync);
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
req.overrideMimeType(mimetype);
req.timeout = 120000; // Wait at most two minutes for a response.
return req;
Cu.importGlobalProperties(["XMLHttpRequest"])
let req = new XMLHttpRequest()
req.open('GET', url, aAsync)
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE
req.overrideMimeType(mimetype)
req.timeout = 120000 // Wait at most two minutes for a response.
return req
},
createCheckConsoleRequest: function(aAsync)
{
let url = 'http://localhost:7657/netdb?r=.';
return this._createRequest(url, aAsync, "text/html");
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let port = prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
let url = `http://localhost:${port}/netdb?r=.`
return this._createRequest(url, aAsync, "text/html")
},
createCheckProxyRequest: function(aAsync) {
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
let url = prefs.getCharPref("extensions.i2pbutton.test_url");
return this._createRequest(url, aAsync, "application/json");
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let url = prefs.getCharPref("extensions.i2pbutton.test_url")
return this._createRequest(url, aAsync, "application/json")
},
parseCheckConsoleResponse: function(aReq)
@ -115,7 +122,7 @@ IBI2PCheckService.prototype =
let ret = 0;
if(aReq.status == 200) {
if(!aReq.response) {
this._logger.log(5, "Check failed! Not text/html!");
this._logger.log(5, "Check failed! Not text/html!")
this._statusOfI2PCheck = this.kCheckFailed
ret = 1;
} else {
@ -141,7 +148,7 @@ IBI2PCheckService.prototype =
if(aReq.status == 200) {
console.log(aReq)
if(!aReq.response) {
this._logger.log(5, "Check failed! Not text/html!");
this._logger.log(5, "Check failed! Not text/html!")
this._statusOfI2PCheck = this.kCheckFailed
ret = 1;
} else {
@ -182,5 +189,5 @@ IBI2PCheckService.prototype =
}
};
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var NSGetFactory = XPCOMUtils.generateNSGetFactory([IBI2PCheckService]);
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
var NSGetFactory = XPCOMUtils.generateNSGetFactory([IBI2PCheckService])

View File

@ -0,0 +1,718 @@
// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
const Cc = Components.classes
const Ci = Components.interfaces
const Cr = Components.results
const Cu = Components.utils
// ctypes can be disabled at build time
try { Cu.import("resource://gre/modules/ctypes.jsm") } catch(e) {}
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
Cu.import("resource://gre/modules/Services.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
//let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
const timer = Cc["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer)
let routerStateLoglines = [
'Router state change from STARTING_1 to STARTING_2',
'Router state change from STARTING_2 to STARTING_3',
'Router state change from STARTING_3 to NETDB_READY',
'Router state change from NETDB_READY to RUNNING'
]
function setTimeout(fn, sleep) {
let event = {
notify: fn
}
return timer.initWithCallback(event, sleep, Components.interfaces.nsITimer.TYPE_ONE_SHOT)
}
function I2PProcessService()
{
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
this._config_checker = Cc["@geti2p.net/i2pbutton-router-config-mgr;1"].getService(Ci.nsISupports).wrappedJSObject
this._logger.log(3, "I2pbutton I2P Router Process Service initialized")
this.wrappedJSObject = this
}
I2PProcessService.prototype =
{
kContractID : "@geti2p.net/i2pbutton-process-service;1",
kServiceName : "I2P Launcher Process Service",
kClassID: Components.ID("{f77babef-dead-b00b-beff-babe6c9afda7}"),
kI2PLauncherExtPath: "i2pbutton@geti2p.net", // This could vary.
kPrefPromptAtStartup: "extensions.i2pbutton.prompt_at_startup",
kWizardProgressPageID: "progress",
kInitialControlConnDelayMS: 25,
kMaxControlConnRetryMS: 2000, // Retry at least every 2 seconds.
kControlConnTimeoutMS: 5*60*1000, // Wait at most 5 minutes for i2p to start.
kStatusUnknown: 0, // I2P process status.
kStatusStarting: 1,
kStatusRunning: 2,
kStatusExited: 3, // Exited or failed to start.
kI2PImplJava: "i2pj",
kI2PImplCpp: "i2pd",
kI2PProcessDidNotStartTopic: "I2PProcessDidNotStart",
kI2PBootstrapErrorTopic: "I2PBootstrapError",
// nsISupports implementation.
QueryInterface: function(aIID)
{
if (!aIID.equals(Ci.nsISupports) &&
!aIID.equals(Ci.nsIFactory) &&
!aIID.equals(Ci.nsIObserver) &&
!aIID.equals(Ci.nsIClassInfo))
{
throw Cr.NS_ERROR_NO_INTERFACE;
}
return this;
},
// nsIFactory implementation.
createInstance: function(aOuter, aIID)
{
if (null != aOuter)
throw Cr.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(aIID);
},
init: function(aWindow) {},
uninit: function unit() {},
lockFactory: function(aDoLock) {},
// nsIObserver implementation.
observe: function(aSubject, aTopic, aParam)
{
const kUserQuitTopic = "I2PUserRequestedQuit"
const kBootstrapStatusTopic = "I2PBootstrapStatus"
if (!this.mObsSvc)
{
this.mObsSvc = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
}
if ("profile-after-change" == aTopic)
{
this.mObsSvc.addObserver(this, "quit-application-granted", false)
this.mObsSvc.addObserver(this, kUserQuitTopic, false)
this.mObsSvc.addObserver(this, kBootstrapStatusTopic, false)
const self = this
//this._logger.log(3, 'Checking if a console is already up (an router already running)')
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let shouldShowDelayUserDialog = prefs.getBoolPref("extensions.i2pbutton.delay_user_with_dialog", true)
let canStartPromise = self._config_checker.ensure_config()
canStartPromise.then(() => {
self._logger.log(3, 'Starting the router')
self.I2PStartAndControlI2P(true)
})
try {
if (shouldShowDelayUserDialog) {
self.openWaitForRouterDialog()
setTimeout(() => {
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
progressmeter.value = progressmeter.value + 35
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
text.value = 'Waiting for the router to open the console and proxy port.'
}, 5000)
}
} catch (err) {
self._logger.log(5, `Unknown error while executing delay user dialog: ${err}`)
}
// After the router process is spawned.
/*if (self.mDelayUserDialog) {
setTimeout(() => {
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
progressmeter.value = progressmeter.value + 35
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
text.value = 'Waiting for the router to open the console and proxy port.'
}, 5000)
}*/
/*this._isConsoleRunning(function(res) {
if (res!=4) {
// Yes, 4 is success
} else {
self._logger.log(3, 'Already found a router, won\'t launch.')
}
})*/
}
else if ("quit-application-granted" == aTopic)
{
this.mIsQuitting = true;
this.mObsSvc.removeObserver(this, "quit-application-granted");
this.mObsSvc.removeObserver(this, kUserQuitTopic);
this.mObsSvc.removeObserver(this, kBootstrapStatusTopic);
if (this.mI2PProcess)
{
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let shouldKillRouter = prefs.getBoolPref("extensions.i2pbutton.kill_router_on_exit", true)
if (shouldKillRouter) this.mI2PProcess.kill()
this._logger.log(4, "Disconnecting from i2p process (pid " + this.mI2PProcess.pid + ")")
this.mI2PProcess = null
}
}
else if (("process-failed" == aTopic) || ("process-finished" == aTopic))
{
if (this.mControlConnTimer)
{
this.mControlConnTimer.cancel();
this.mControlConnTimer = null;
}
this.mI2PProcess = null;
this.mI2PProcessStatus = this.kStatusExited;
this.mIsBootstrapDone = false;
this.mObsSvc.notifyObservers(null, "I2PProcessExited", null)
if (this.mIsQuitting)
{
LauncherUtil.cleanupTempDirectories()
}
else
{
var defaultBtnLabel = LauncherUtil.getLocalizedString("restart_i2p");
var cancelBtnLabel = "OK";
try
{
const kSysBundleURI = "chrome://global/locale/commonDialogs.properties"
var sysBundle = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService).createBundle(kSysBundleURI)
cancelBtnLabel = sysBundle.GetStringFromName(cancelBtnLabel)
} catch(e) {}
this._logger.log(3, 'The router stopped..')
/*if (LauncherUtil.showConfirm(null, s, defaultBtnLabel, cancelBtnLabel) && !this.mIsQuitting)
{
this.I2PStartAndControlI2P(false);
}*/
}
}
else if ("timer-callback" == aTopic)
{
if (aSubject == this.mControlConnTimer)
{
this.mObsSvc.notifyObservers(null, "I2PProcessIsReady", null)
}
} else if (kBootstrapStatusTopic == aTopic) {
this._processBootstrapStatus(aSubject.wrappedJSObject)
} else if (kUserQuitTopic == aTopic) {
this.mQuitSoon = true
}
},
canUnload: function(aCompMgr) { return true; },
// nsIClassInfo implementation.
getInterfaces: function(aCount)
{
var iList = [ Ci.nsISupports,
Ci.nsIFactory,
Ci.nsIObserver,
Ci.nsIClassInfo ];
aCount.value = iList.length;
return iList;
},
getHelperForLanguage: function (aLanguage) { return null; },
contractID: this.kContractID,
classDescription: this.kServiceName,
classID: this.kClassID,
flags: Ci.nsIClassInfo.SINGLETON,
classInfo : XPCOMUtils.generateCI({
classID: this.kClassID,
contractID: this.kContractID,
classDescription: this.kServiceName,
interfaces: [
Ci.nsISupports,
Ci.nsIFactory,
Ci.nsIObserver,
Ci.nsIClassInfo
],
flags: Ci.nsIClassInfo.SINGLETON
}),
// Hack to get us registered early to observe recovery
_xpcom_categories: [{category:"profile-after-change"}],
// Public Properties and Methods ///////////////////////////////////////////
get I2PProcessStatus()
{
return this.mI2PProcessStatus;
},
get I2PIsBootstrapDone()
{
return this.mIsBootstrapDone;
},
get I2PBootstrapErrorOccurred()
{
},
openWaitForRouterDialog: function() {
const self = this
//var win = ww.openWindow(null, "chrome://i2pbutton/content/progress.xul", "wizard", "chrome,dialog=no,modal,centerscreen", {blabla:0})
const ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService(Components.interfaces.nsIWindowWatcher)
self.mDelayUserDialog = ww.openWindow(
null,
"chrome://i2pbutton/content/progress.xul",
"startingrouter",
"chrome,dialog=no,modal,centerscreen",
[true])
this._logger.log(3, 'After open wait for router dialog')
setTimeout(() => {
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
progressmeter.value = progressmeter.value + 15
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
text.hidden = false
}, 1000)
return self.mDelayUserDialog
},
getWrapperLog: function() {
let wrapperLogFile = LauncherUtil.dataDirectoryObject
wrapperLogFile.append('I2P')
wrapperLogFile.append('wrapper.log')
return this._getFileAsString(wrapperLogFile)
},
getLogsLogTxt: function() {
let logTxtFile = LauncherUtil.dataDirectoryObject
logTxtFile.append('I2P')
logTxtFile.append('logs')
logTxtFile.append('log-0.txt')
return this._getFileAsString(logTxtFile)
},
retrieveBootstrapStatus: function() {},
I2PStartAndControlI2P: function()
{
this._startI2P()
let isRunningI2P = (this.mI2PProcessStatus == this.kStatusStarting) || (this.mI2PProcessStatus == this.kStatusRunning)
this._controlI2P(isRunningI2P)
},
I2PClearBootstrapError: function()
{
this.mBootstrapErrorOccurred = false
this.mLastI2PWarningPhase = null
this.mLastI2PWarningReason = null
},
// Private Member Variables ////////////////////////////////////////////////
mI2PProcessStatus: 0, // kStatusUnknown
mIsBootstrapDone: false,
mBootstrapErrorOccurred: false,
mIsQuitting: false,
mObsSvc: null,
mI2PUseImpl: this.kI2PImplJava,
mI2PProcess: null, // nsIProcess
mI2PProcessStartTime: null, // JS Date.now()
mControlConnTimer: null,
mControlConnDelayMS: 0,
mQuitSoon: false, // Quit was requested by the user; do so soon.
mLastI2PWarningPhase: null,
mLastI2PWarningReason: null,
mDefaultPreferencesAreLoaded: false,
mDelayUserDialog: null,
// Private Methods /////////////////////////////////////////////////////////
_resetLogFiles: function() {
let wrapperLogFile = LauncherUtil.dataDirectoryObject
wrapperLogFile.append('I2P')
wrapperLogFile.append('wrapper.log')
if (wrapperLogFile.exists()) wrapperLogFile.remove(false)
let logTxtFile = LauncherUtil.dataDirectoryObject
logTxtFile.append('I2P')
logTxtFile.append('logs')
logTxtFile.append('log-0.txt')
if (logTxtFile.exists()) logTxtFile.remove(false)
},
_startI2P: function()
{
this.mI2PProcessStatus = this.kStatusUnknown;
// Avoid starting the router if extensions.i2pbutton.start_i2p is set to false.
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
let shouldStart = prefs.getBoolPref("extensions.i2pbutton.start_i2p")
if (!shouldStart) return
try
{
// Ideally, we would cd to the Firefox application directory before
// starting i2p (but we don't know how to do that). Instead, we
// rely on the IBB launcher to start Firefox from the right place.
// Get the I2P data directory first so it is created before we try to
// construct paths to files that will be inside it.
let dataDir = LauncherUtil.getI2PConfigPath(true)
let exeFile = LauncherUtil.getI2PBinary()
this._logger.log(3, `Datadir => ${dataDir.path}\nExeFile => ${exeFile.path}`)
var detailsKey;
if (!exeFile)
detailsKey = "i2p_missing";
else if (!dataDir)
detailsKey = "datadir_missing";
if (detailsKey)
{
var details = LauncherUtil.getLocalizedString(detailsKey);
var key = "unable_to_start_i2p";
var err = LauncherUtil.getFormattedLocalizedString(key, [details], 1);
this._notifyUserOfError(err, null, this.kI2PProcessDidNotStartTopic);
return;
}
this._resetLogFiles()
let args = LauncherUtil.getRouterDefaultArgs()
// Set an environment variable that points to the I2P data directory.
let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment)
env.set('I2P_BROWSER_I2P_DATA_DIR', dataDir.path)
// On Windows, prepend the I2P program directory to PATH. This is
// needed so that pluggable transports can find OpenSSL DLLs, etc.
// See https://trac.torproject.org/projects/tor/ticket/10845
if (LauncherUtil.isWindows)
{
var path = exeFile.parent.path
if (env.exists("PATH"))
path += ";" + env.get("PATH")
env.set("PATH", path)
}
this.mI2PProcessStatus = this.kStatusStarting
this._logger.log(3, `Trying to start with ${args}`)
this._logger.log(2, "Starting " + exeFile.path)
var p = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess)
p.init(exeFile)
for (var i = 0; i < args.length; ++i)
this._logger.log(2, ` ${args[i]}`)
// Possible fix for Windows and cmd.exe window spawn.
p.startHidden = true
p.noShell = true
p.runwAsync(args, args.length, this, false)
this.mI2PProcess = p
this.mI2PProcessStartTime = Date.now()
}
catch (e)
{
this.mI2PProcessStatus = this.kStatusExited
//var s = LauncherUtil.getLocalizedString("i2p_failed_to_start");
this._notifyUserOfError('Failed to start the I2P router', null, this.kI2PProcessDidNotStartTopic);
this._logger.log(4, "_startI2P error: ", e)
}
}, // _startI2P()
_isConsoleRunning: function(callback) {
let checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
let obsSvc = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
let req = checkSvc.createCheckConsoleRequest(true)
const self = this
req.onreadystatechange = function(event) {
if (req.readyState === 4) {
// Done
let result = checkSvc.parseCheckConsoleResponse(req)
self.mIsBootstrapDone = true
self.mI2PProcessStatus = self.kStatusRunning
self._processBootstrapStatus({ PROGRESS: 100, message: 'The router has succcessfully started.' })
var statusObj = { bootstrap: 'done', success: true }
statusObj.wrappedJSObject = statusObj
obsSvc.notifyObservers(statusObj, "I2PBootstrapStatus", null)
callback(result)
}
}
req.send(null)
},
_processBootstrapStatus: function(aStatusObj)
{
if (!aStatusObj)
return
if (100 == aStatusObj.PROGRESS)
{
this.mIsBootstrapDone = true
this.mBootstrapErrorOccurred = false
LauncherUtil.setBoolPref(this.kPrefPromptAtStartup, false)
}
else
{
this.mIsBootstrapDone = false
if (aStatusObj._errorOccurred)
{
this.mBootstrapErrorOccurred = true
LauncherUtil.setBoolPref(this.kPrefPromptAtStartup, true)
let phase = LauncherUtil.getLocalizedBootstrapStatus(aStatusObj, "TAG")
let reason = LauncherUtil.getLocalizedBootstrapStatus(aStatusObj, "REASON")
let details = LauncherUtil.getFormattedLocalizedString(
"i2p_bootstrap_failed_details", [phase, reason], 2)
I2PLauncherLogger.log(5, "I2P bootstrap error: [" + aStatusObj.TAG +
"/" + aStatusObj.REASON + "] " + details);
if ((aStatusObj.TAG != this.mLastI2PWarningPhase) ||
(aStatusObj.REASON != this.mLastI2PWarningReason))
{
this.mLastI2PWarningPhase = aStatusObj.TAG
this.mLastI2PWarningReason = aStatusObj.REASON
let msg = LauncherUtil.getLocalizedString("i2p_bootstrap_failed")
this._notifyUserOfError(msg, details, this.kI2PBootstrapErrorTopic)
}
}
}
}, // _processBootstrapStatus()
_controlI2P: function(aIsRunningI2P)
{
try
{
if (aIsRunningI2P)
this._monitorI2PProcessStartup()
// If the user pressed "Quit" within settings/progress, exit.
if (this.mQuitSoon)
this._quitApp()
}
catch (e)
{
this.mI2PProcessStatus = this.kStatusExited
var s = LauncherUtil.getLocalizedString("i2p_control_failed")
this._notifyUserOfError(s, null, null)
this._logger.log(4, "_controlI2P error: ", e)
}
}, // controlI2P()
_quitApp: function()
{
try
{
this.mQuitSoon = false;
if (this.mI2PProcess != null) {
this.mI2PProcess.kill()
}
let asSvc = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
let flags = asSvc.eAttemptQuit;
asSvc.quit(flags);
}
catch (e)
{
this._logger.log(4, "unable to quit", e);
}
},
_monitorI2PProcessStartup: function()
{
this.mControlConnDelayMS = this.kInitialControlConnDelayMS
this.mControlConnTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer)
this.mControlConnTimer.init(this, this.mControlConnDelayMS, this.mControlConnTimer.TYPE_ONE_SHOT)
},
_notifyUserOfError: function(aMessage, aDetails, aNotifyTopic)
{
let errorObj = { handled: false, message: aMessage }
if (aDetails)
errorObj.details = aDetails
if (aNotifyTopic)
{
// Give other code an opportunity to handle this error, e.g., if the
// network settings window is open, errors are displayed using an
// overlaid XUL element.
errorObj.wrappedJSObject = errorObj
this.mObsSvc.notifyObservers(errorObj, aNotifyTopic, null)
}
if (!errorObj.handled)
{
let msg = aMessage
if (aDetails)
msg += "\n\n" + aDetails
LauncherUtil.showAlert(null, msg)
}
},
_getpid: function()
{
// Use nsIXULRuntime.processID if it is available.
var pid = 0;
try
{
var xreSvc = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
pid = xreSvc.processID;
}
catch (e)
{
this._logger.log(2, "failed to get process ID via XUL runtime:", e);
}
// Try libc.getpid() via js-ctypes.
if (!pid) try
{
var getpid;
if (LauncherUtil.isMac) {
var libc = ctypes.open("libc.dylib")
getpid = libc.declare("getpid", ctypes.default_abi, ctypes.uint32_t)
} else if (LauncherUtil.isWindows) {
var libc = ctypes.open("Kernel32.dll")
getpid = libc.declare("GetCurrentProcessId", ctypes.default_abi, ctypes.uint32_t)
} else {// Linux and others.
var libc;
try {
libc = ctypes.open("libc.so.6")
} catch(e) {
libc = ctypes.open("libc.so")
}
getpid = libc.declare("getpid", ctypes.default_abi, ctypes.int)
}
pid = getpid()
} catch(e) {
this._logger.log(4, "unable to get process ID: ", e)
}
return pid;
},
// Returns undefined if file contents could not be read.
_getFileAsString: function(aFile)
{
let str = ""
let inStream;
try
{
let fis = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(Ci.nsIFileInputStream);
const kOpenFlagsReadOnly = 0x01;
fis.init(aFile, kOpenFlagsReadOnly, 0, 0);
inStream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
inStream.init(fis, "UTF-8", 0, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
const kReadSize = 0xffffffff; // PR_UINT32_MAX
while (true)
{
let outStr = {};
let count = inStream.readString(kReadSize, outStr);
if (count == 0)
break;
str += outStr.value;
}
}
catch (e)
{
this._logger.log(5, "_getFileAsString " + aFile.path + " error: " + e);
str = undefined;
}
if (inStream)
inStream.close();
return str;
},
// After making a backup, replace the contents of aFile with aStr.
// Returns true if successful.
_overwriteFile: function(aFile, aStr)
{
let backupFile;
try
{
// Convert the data to UTF-8.
let conv = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
conv.charset = "UTF-8";
let data = conv.ConvertFromUnicode(aStr) + conv.Finish();
// Rename the file to .bak (we avoid .orig because tor uses it). This
// backup will be left on disk so the user can recover the original
// file contents.
backupFile = aFile.clone();
backupFile.leafName += ".bak";
backupFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, aFile.permissions);
aFile.renameTo(null, backupFile.leafName);
this._logger.log(3, "created backup of " + aFile.leafName + " in " + backupFile.leafName);
// Write the new data to the file.
let stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
stream.init(aFile, 0x02 | 0x08 | 0x20, /* WRONLY CREATE TRUNCATE */
0o600, 0);
stream.write(data, data.length);
stream.QueryInterface(Ci.nsISafeOutputStream).finish();
}
catch (e)
{
// Report an error and try to recover by renaming the backup to the
// original name.
this._logger.log(5, "failed to overwrite file " + aFile.path + ": " + e);
if (backupFile)
backupFile.renameTo(null, aFile.leafName);
return false;
}
return true;
},
endOfObject: true
}
let gI2PProcessService = new I2PProcessService
// TODO: Mark wants to research use of XPCOMUtils.generateNSGetFactory
// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function NSGetFactory(aClassID)
{
if (!aClassID.equals(gI2PProcessService.kClassID))
throw Cr.NS_ERROR_FACTORY_NOT_REGISTERED
return gI2PProcessService
}
// This is the new stuff, stay away from generateNSGetModule which is the old stuff..
//var NSGetFactory = XPCOMUtils.generateNSGetFactory([I2PProcessService])

View File

@ -1,47 +1,40 @@
// Bug 1506 P1: This is just a handy logger. If you have a better one, toss
// this in the trash.
/*************************************************************************
* TBLogger (JavaScript XPCOM component)
*
* Allows loglevel-based logging to different logging mechanisms.
*
*************************************************************************/
// TODO: Slowly migrate to firefox's Log module "resource://gre/modules/Log.jsm"
// Module specific constants
const kMODULE_NAME = "I2pbutton Logger";
const kMODULE_CONTRACTID = "@geti2p.net/i2pbutton-logger;1";
const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7");
const kMODULE_NAME = "I2pbutton Logger"
const kMODULE_CONTRACTID = "@geti2p.net/i2pbutton-logger;1"
const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7")
const Cr = Components.results;
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results
const Cc = Components.classes
const Ci = Components.interfaces
const Cu = Components.utils
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs()
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/Log.jsm")
Cu.import("resource://gre/modules/Services.jsm");
let console = (Cu.import("resource://gre/modules/Console.jsm", {})).console
function I2pbuttonLogger() {
// Register observer
Services.prefs.addObserver("extensions.i2pbutton", this, false);
// Register observer
Services.prefs.addObserver("extensions.i2pbutton", this, false);
this.loglevel = Services.prefs.getIntPref("extensions.i2pbutton.loglevel");
this.logmethod = Services.prefs.getIntPref("extensions.i2pbutton.logmethod");
this.loglevel = Services.prefs.getIntPref("extensions.i2pbutton.loglevel");
this.logmethod = Services.prefs.getIntPref("extensions.i2pbutton.logmethod");
try {
var logMngr = Components.classes["@mozmonkey.com/debuglogger/manager;1"]
.getService(Components.interfaces.nsIDebugLoggerManager);
this._debuglog = logMngr.registerLogger("i2pbutton");
} catch (exErr) {
this._debuglog = false;
}
this._console = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
try {
var logMngr = Components.classes["@mozmonkey.com/debuglogger/manager;1"]
.getService(Components.interfaces.nsIDebugLoggerManager);
this._debuglog = logMngr.registerLogger("i2pbutton");
} catch (exErr) {
this._debuglog = false;
}
this._console = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
// This JSObject is exported directly to chrome
this.wrappedJSObject = this;
this.log(3, "I2pbutton debug output ready");
// This JSObject is exported directly to chrome
this.wrappedJSObject = this;
this.log(3, "I2pbutton debug output ready");
}
/**
@ -55,11 +48,11 @@ const nsIClassInfo = Components.interfaces.nsIClassInfo;
const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
const nsIObserverService = Components.interfaces.nsIObserverService;
const logString = { 1:"VERB", 2:"DBUG", 3: "INFO", 4:"NOTE", 5:"WARN" };
const logString = { 1:"VERB", 2:"DBUG", 3: "INFO", 4:"NOTE", 5:"WARN", 6:"ERRO" };
function padInt(i)
{
return (i < 10) ? '0' + i : i;
return (i < 10) ? '0' + i : i;
}
I2pbuttonLogger.prototype =
@ -95,54 +88,61 @@ I2pbuttonLogger.prototype =
getHelperForLanguage: function(count) { return null; },
formatLog: function(str, level) {
var d = new Date();
var now = padInt(d.getUTCMonth()+1)+"-"+padInt(d.getUTCDate())+" "+padInt(d.getUTCHours())+":"+padInt(d.getUTCMinutes())+":"+padInt(d.getUTCSeconds());
return "["+now+"] I2pbutton "+logString[level]+": "+str;
var d = new Date()
var now = padInt(d.getUTCMonth()+1)+"-"+padInt(d.getUTCDate())+" "+padInt(d.getUTCHours())+":"+padInt(d.getUTCMinutes())+":"+padInt(d.getUTCSeconds())
return "["+now+"] I2pbutton "+logString[level]+": "+str
},
// error console log
eclog: function(level, str) {
switch(this.logmethod) {
case 0: // stderr
if(this.loglevel <= level)
dump(this.formatLog(str, level)+"\n");
break;
default: // errorconsole
if(this.loglevel <= level)
this._console.logStringMessage(this.formatLog(str,level));
break;
}
switch(this.logmethod) {
case 0: // stderr
if(this.loglevel <= level)
dump(this.formatLog(str, level)+"\n");
break;
default: // errorconsole
if(this.loglevel <= level)
this._console.logStringMessage(this.formatLog(str,level));
break;
}
},
safe_log: function(level, str, scrub) {
if (this.loglevel < 4) {
this.eclog(level, str+scrub);
} else {
this.eclog(level, str+" [scrubbed]");
}
if (this.loglevel < 4) {
this.eclog(level, str+scrub);
} else {
this.eclog(level, str+" [scrubbed]");
}
},
log: function(level, str) {
switch(this.logmethod) {
case 2: // debuglogger
if(this._debuglog) {
this._debuglog.log((6-level), this.formatLog(str,level));
break;
}
// fallthrough
case 0: // stderr
if(this.loglevel <= level)
dump(this.formatLog(str,level)+"\n");
break;
default:
dump("Bad log method: "+this.logmethod);
case 1: // errorconsole
if(this.loglevel <= level)
this._console.logStringMessage(this.formatLog(str,level));
break;
}
switch(this.logmethod) {
case 2: // debuglogger
if(this._debuglog) {
this._debuglog.log((6-level), this.formatLog(str,level));
break;
}
// fallthrough
case 0: // stderr
if(this.loglevel <= level)
dump(this.formatLog(str,level)+"\n");
break;
default:
dump("Bad log method: "+this.logmethod);
case 1: // errorconsole
if(this.loglevel <= level)
this._console.logStringMessage(this.formatLog(str,level));
break;
}
},
error: function(str) { this.log(6, str) },
warn: function(str) { this.log(5, str) },
note: function(str) { this.log(4, str) },
info: function(str) { this.log(3, str) },
debug: function(str) { this.log(2, str) },
verbose: function(str) { this.log(1, str) },
// Pref observer interface implementation
// topic: what event occurred
@ -150,35 +150,27 @@ I2pbuttonLogger.prototype =
// data: which pref has been changed (relative to subject)
observe: function(subject, topic, data)
{
if (topic != "nsPref:changed") return;
switch (data) {
case "extensions.i2pbutton.logmethod":
this.logmethod = Services.prefs.getIntPref("extensions.i2pbutton.logmethod");
if (this.logmethod === 0) {
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
true);
} else if (Services.prefs.
getIntPref("extensions.i2plauncher.logmethod", 3) !== 0) {
// If Tor Launcher is not available or its log method is not 0
// then let's reset the dump pref.
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
false);
}
break;
case "extensions.i2pbutton.loglevel":
this.loglevel = Services.prefs.getIntPref("extensions.i2pbutton.loglevel");
break;
}
if (topic != "nsPref:changed") return;
switch (data) {
case "extensions.i2pbutton.logmethod":
this.logmethod = Services.prefs.getIntPref("extensions.i2pbutton.logmethod");
if (this.logmethod === 0) {
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
true);
} else if (Services.prefs.
getIntPref("extensions.i2plauncher.logmethod", 3) !== 0) {
// If I2P Launcher is not available or its log method is not 0
// then let's reset the dump pref.
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
false);
}
break;
case "extensions.i2pbutton.loglevel":
this.loglevel = Services.prefs.getIntPref("extensions.i2pbutton.loglevel");
break;
}
}
}
/**
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
if (XPCOMUtils.generateNSGetFactory)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([I2pbuttonLogger]);
else
var NSGetModule = XPCOMUtils.generateNSGetModule([I2pbuttonLogger]);
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm")
var NSGetFactory = XPCOMUtils.generateNSGetFactory([I2pbuttonLogger])

View File

@ -0,0 +1,359 @@
// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
const Cc = Components.classes
const Ci = Components.interfaces
const Cr = Components.results
const Cu = Components.utils
/*const ZipReader = Components.Constructor(
"@mozilla.org/libjar/zip-reader;1",
"nsIZipReader",
"open"
)*/
const nsFile = Components.Constructor(
"@mozilla.org/file/local;1",
"nsIFile",
"initWithPath"
)
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
Cu.import("resource://gre/modules/Services.jsm")
Cu.import('resource://gre/modules/osfile.jsm')
Cu.import('resource://gre/modules/FileUtils.jsm')
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
let httpProxyPort = Services.prefs.getIntPref("network.proxy.http_port", 7644)
const defaultWebappsConfig = `# Autogenerated by I2P Browser
webapps.jsonrpc.startOnLoad=true
webapps.routerconsole.startOnLoad=true
webapps.i2ptunnel.startOnLoad=true
`
const defaultProxyTunnels = `# Autogenerated by I2P Browser
tunnel.0.description=HTTP proxy for browsing eepsites and the web
tunnel.0.interface=127.0.0.1
tunnel.0.listenPort=${httpProxyPort}
tunnel.0.name=I2P HTTP Proxy
tunnel.0.option.i2cp.closeIdleTime=1800000
tunnel.0.option.i2cp.closeOnIdle=false
tunnel.0.option.i2cp.delayOpen=false
tunnel.0.option.i2cp.destination.sigType=7
tunnel.0.option.i2cp.newDestOnResume=false
tunnel.0.option.i2cp.reduceIdleTime=900000
tunnel.0.option.i2cp.reduceOnIdle=true
tunnel.0.option.i2cp.reduceQuantity=1
tunnel.0.option.i2p.streaming.connectDelay=0
tunnel.0.option.i2ptunnel.httpclient.SSLOutproxies=false.i2p
tunnel.0.option.i2ptunnel.httpclient.allowInternalSSL=true
tunnel.0.option.i2ptunnel.httpclient.jumpServers=http://stats.i2p/cgi-bin/jump.cgi?a=,http://i2pjump.i2p/jump/
tunnel.0.option.i2ptunnel.httpclient.sendAccept=false
tunnel.0.option.i2ptunnel.httpclient.sendReferer=false
tunnel.0.option.i2ptunnel.httpclient.sendUserAgent=false
tunnel.0.option.i2ptunnel.useLocalOutproxy=false
tunnel.0.option.inbound.backupQuantity=0
tunnel.0.option.inbound.length=3
tunnel.0.option.inbound.lengthVariance=0
tunnel.0.option.inbound.nickname=shared clients
tunnel.0.option.inbound.quantity=6
tunnel.0.option.outbound.backupQuantity=0
tunnel.0.option.outbound.length=3
tunnel.0.option.outbound.lengthVariance=0
tunnel.0.option.outbound.nickname=shared clients
tunnel.0.option.outbound.priority=10
tunnel.0.option.outbound.quantity=6
tunnel.0.option.outproxyAuth=false
tunnel.0.option.persistentClientKey=false
tunnel.0.option.sslManuallySet=true
tunnel.0.option.useSSL=false
tunnel.0.proxyList=false.i2p
tunnel.0.sharedClient=true
tunnel.0.startOnLoad=true
tunnel.0.type=httpclient
`
const defaultClientsConfig = `# Autogenerated by I2P Browser
clientApp.0.args=${consolePort} ::1,127.0.0.1 ./webapps/
clientApp.0.main=net.i2p.router.web.RouterConsoleRunner
clientApp.0.name=I2P Router Console
clientApp.0.onBoot=true
clientApp.0.startOnLoad=true
clientApp.1.main=net.i2p.i2ptunnel.TunnelControllerGroup
clientApp.1.name=Application tunnels
clientApp.1.args=i2ptunnel.config
clientApp.1.delay=-1
clientApp.1.startOnLoad=true
`
const defaultSocksProxyTunnels = `# Autogenerated by I2P Browser
tunnel.1.interface=127.0.0.1
tunnel.1.listenPort=4455
tunnel.1.name=SOCKS
tunnel.1.option.i2cp.closeIdleTime=1800000
tunnel.1.option.i2cp.closeOnIdle=false
tunnel.1.option.i2cp.delayOpen=false
tunnel.1.option.i2cp.destination.sigType=7
tunnel.1.option.i2cp.newDestOnResume=false
tunnel.1.option.i2cp.reduceIdleTime=1200000
tunnel.1.option.i2cp.reduceOnIdle=false
tunnel.1.option.i2cp.reduceQuantity=1
tunnel.1.option.i2p.streaming.connectDelay=0
tunnel.1.option.i2ptunnel.httpclient.allowInternalSSL=false
tunnel.1.option.i2ptunnel.httpclient.sendAccept=false
tunnel.1.option.i2ptunnel.httpclient.sendReferer=false
tunnel.1.option.i2ptunnel.httpclient.sendUserAgent=false
tunnel.1.option.i2ptunnel.useLocalOutproxy=true
tunnel.1.option.inbound.backupQuantity=0
tunnel.1.option.inbound.length=3
tunnel.1.option.inbound.lengthVariance=0
tunnel.1.option.inbound.nickname=SOCKS
tunnel.1.option.inbound.quantity=3
tunnel.1.option.outbound.backupQuantity=0
tunnel.1.option.outbound.length=3
tunnel.1.option.outbound.lengthVariance=0
tunnel.1.option.outbound.nickname=SOCKS
tunnel.1.option.outbound.quantity=3
tunnel.1.option.outproxyAuth=false
tunnel.1.option.persistentClientKey=false
tunnel.1.option.useSSL=false
tunnel.1.proxyList=exitpoint.i2p
tunnel.1.sharedClient=false
tunnel.1.startOnLoad=false
tunnel.1.type=sockstunnel
`
const defaultRouterConfig = `# Autogenerated by I2P Browser
i2np.laptopMode=true
i2np.upnp.enable=true
i2np.udp.addressSources=local,upnp,ssu
i2p.reseedURL=https://download.xxlspeed.com/,https://i2p.mooo.com/netDb/,https://i2p.novg.net/,https://i2pseed.creativecowpat.net:8443/,https://itoopie.atomike.ninja/,https://netdb.i2p2.no/,https://reseed.i2p-projekt.de/,https://reseed.i2p.net.in/,https://reseed.memcpy.io/,https://reseed.onion.im/
router.outboundPool.quantity=7
router.inboundPool.quantity=7
router.sharePercentage=50
i2cp.hostname=127.0.0.1
i2cp.port=17654
router.startup.jetty9.migrated=true
routerconsole.welcomeWizardComplete=true
`
let noscript = Cu.import("resource://i2pbutton/modules/noscript-control.js")
noscript.initialize()
function RouterConfigManager() {
this.version = '0.1'
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
this._logger.log(3, "I2pbutton I2P RouterConfigManager Service initialized")
this.wrappedJSObject = this
}
RouterConfigManager.prototype = {
// properties required for XPCOM registration:
classDescription: "A component for handling the embedded router config",
classID: Components.ID("{E2AA62BB-AFD0-4D94-9408-90CE39784086}"),
contractID: "@geti2p.net/i2pbutton-router-config-mgr;1",
serviceName: 'RouterConfigManager',
wrappedJSObject: null,
_logger: null,
state: {},
// State
mDoesRouterConfigExists: false,
mDoesClientsConfigExists: false,
mDoesTunnelConfigExists: false,
mDoesWebappsConfigExists: false,
mHasChecksStarted: false,
mIsChecksDone: false,
// nsISupports implementation.
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]),
canRouterStart: function() {
return (this.mDoesRouterConfigExists && this.mDoesClientsConfigExists && this.mDoesTunnelConfigExists)
},
_write_config: function(configfile, content, onComplete) {
const self = this
LauncherUtil.writeFileWithData(configfile, content, file => { onComplete(file) }, (err) => {
this._logger.log(6,`Can't write config file :( - path was ${configfile.path}, error: ${err}`)
})
},
copy_recursive: async function(sourceDir, destDir) {
let items = sourceDir.directoryEntries
while (items.hasMoreElements()) {
let item = items.getNext().QueryInterface(Components.interfaces.nsIFile)
if (item.isFile()) {
item.copyTo(destDir, "")
this._logger.log(3, `Copied ${item.path}`)
} else if (item.isDirectory()) {
let newDir = destDir.clone()
newDir.append(item.leafName)
newDir.create(newDir.DIRECTORY_TYPE, 0o700)
this._logger.log(3, `Recursively copying ${item.path}`)
this.copy_recursive(item, newDir)
}
}
},
ensure_docs: async function() {
let configDirectory = LauncherUtil.getI2PConfigPath(true)
let destDocsDir = configDirectory.clone()
let distDocsDir = LauncherUtil.getI2PBinary()
distDocsDir = distDocsDir.parent.parent
distDocsDir.append('docs')
destDocsDir.append('docs')
if (!destDocsDir.exists()) {
this.copy_recursive(distDocsDir, destDocsDir)
}
},
ensure_webapps: async function() {
let configDirectory = LauncherUtil.getI2PConfigPath(true)
let destWebappDir = configDirectory.clone()
let distWebppDir = LauncherUtil.getI2PBinary()
distWebppDir = distWebppDir.parent.parent
distWebppDir.append('webapps')
destWebappDir.append('webapps')
if (!destWebappDir.exists()) {
destWebappDir.create(destWebappDir.DIRECTORY_TYPE, 0o700)
let items = distWebppDir.directoryEntries
while (items.hasMoreElements()) {
let item = items.getNext().QueryInterface(Components.interfaces.nsIFile)
if (item.isFile()) {
item.copyTo(destWebappDir, "")
this._logger.log(3, `Copied ${item.path}`)
}
}
}
},
ensure_config: async function(onCompleteCallback) {
this.mHasChecksStarted = true
let configDirectory = LauncherUtil.getI2PConfigPath(true)
let routerConfigFile = configDirectory.clone()
routerConfigFile.append('router.config')
let tunnelConfigFile = configDirectory.clone()
tunnelConfigFile.append('i2ptunnel.config')
let clientsConfigFile = configDirectory.clone()
clientsConfigFile.append('clients.config')
let webappsConfigFile = configDirectory.clone()
webappsConfigFile.append('webapps.config')
let hoststxtFile = configDirectory.clone()
hoststxtFile.append('hosts.txt')
if (!hoststxtFile.exists()) {
let distFile = LauncherUtil.getI2PBinary().parent.parent
distFile.append('hosts.txt')
distFile.copyTo(hoststxtFile.parent, "")
this._logger.log(3, `Copied hosts.txt file`)
}
// Temporary jetty fix
let orgDir = configDirectory.clone()
orgDir.append('org')
if (!orgDir.exists()) {
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
orgDir.append('eclipse')
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
orgDir.append('jetty')
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
orgDir.append('webapp')
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
let distJettyFile = LauncherUtil.getI2PBinary().parent.parent
distJettyFile.append('org')
distJettyFile.append('eclipse')
distJettyFile.append('jetty')
distJettyFile.append('webapp')
distJettyFile.append('webdefault.xml')
distJettyFile.copyTo(orgDir, '')
}
// Ensure they exists
const self = this
this.ensureRouterConfigPromise = () => {
return new Promise(resolve => {
if (!routerConfigFile.exists()) {
self._write_config(routerConfigFile, defaultRouterConfig, file => {
self.mDoesRouterConfigExists = true
self._logger.log(3, 'Wrote router.config')
if (typeof onCompleteCallback === 'function') onCompleteCallback(file)
resolve(routerConfigFile)
})
} else {
self._logger.log(3, 'Found router.config from earlier')
self.mDoesRouterConfigExists = true
resolve(null)
}
})
}
this.ensureTunnelConfigPromise = () => {
return new Promise(resolve => {
if (!tunnelConfigFile.exists()) {
self._write_config(tunnelConfigFile, defaultProxyTunnels, tfile => {
self._logger.log(3, 'Wrote i2ptunnel.config')
self.mDoesTunnelConfigExists = true
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
resolve(tunnelConfigFile)
})
} else {
self._logger.log(3, 'Found i2ptunnel.config from earlier')
self.mDoesTunnelConfigExists = true
resolve(null)
}
})
}
this.ensureClientsConfigPromise = () => {
return new Promise(resolve => {
if (!clientsConfigFile.exists()) {
self._write_config(clientsConfigFile, defaultClientsConfig, tfile => {
self._logger.log(3, 'Wrote clients.config')
self.mDoesClientsConfigExists = true
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
resolve(clientsConfigFile)
})
} else {
self._logger.log(3, 'Found clients.config from earlier')
self.mDoesClientsConfigExists = true
resolve(null)
}
})
}
this.ensureWebappsConfigPromise = () => {
return new Promise(resolve => {
if (!webappsConfigFile.exists()) {
self._write_config(webappsConfigFile, defaultWebappsConfig, tfile => {
self._logger.log(3, 'Wrote webapps.config')
self.mDoesWebappsConfigExists = true
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
resolve(webappsConfigFile)
})
} else {
self._logger.log(3, 'Found webapps.config from earlier')
self.mDoesWebappsConfigExists = true
resolve(null)
}
})
}
// Promises are not done but at least done here.
this.mIsChecksDone = true
return Promise.all([
this.ensureRouterConfigPromise(),
this.ensureTunnelConfigPromise(),
this.ensureClientsConfigPromise(),
this.ensureWebappsConfigPromise(),
])
},
}
var NSGetFactory = XPCOMUtils.generateNSGetFactory([RouterConfigManager])

View File

@ -8,37 +8,34 @@
*
*************************************************************************/
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
const Cc = Components.classes
const Ci = Components.interfaces
const Cr = Components.results
const Cu = Components.utils
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm")
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
//let NoScriptControl = Cu.import("resource://torbutton/modules/noscript-control.js", {});
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs()
let NoScriptControl = Cu.import("resource://i2pbutton/modules/noscript-control.js", {})
// Module specific constants
const kMODULE_NAME = "Startup";
const kMODULE_CONTRACTID = "@geti2p.net/startup-observer;1";
const kMODULE_CID = Components.ID("06322def-6fde-4c06-aef6-47ae8e799629");
const kMODULE_NAME = "Startup"
const kMODULE_CONTRACTID = "@geti2p.net/startup-observer;1"
const kMODULE_CID = Components.ID("06322def-6fde-4c06-aef6-47ae8e799629")
function StartupObserver() {
this.logger = Cc["@geti2p.net/i2pbutton-logger;1"]
.getService(Ci.nsISupports).wrappedJSObject;
this._prefs = Services.prefs;
this.logger.log(3, "Startup Observer created");
this.logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
this._prefs = Services.prefs
this.logger.log(3, "Startup Observer created")
var env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
var prefName = "browser.startup.homepage";
var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment)
var prefName = "browser.startup.homepage"
if (env.exists("I2P_DEFAULT_HOMEPAGE")) {
// if the user has set this value in a previous installation, don't override it
if (!this._prefs.prefHasUserValue(prefName)) {
this._prefs.setCharPref(prefName, env.get("I2P_DEFAULT_HOMEPAGE"));
this._prefs.setCharPref(prefName, env.get("I2P_DEFAULT_HOMEPAGE"))
}
}
@ -51,20 +48,16 @@ function StartupObserver() {
}
try {
// XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
// before the initial SSL-Observatory test... If we lose the race, Firefox
// caches the old proxy settings for check.tp.o somehwere, and it never loads :(
this.setProxySettings();
} catch(e) {
this.logger.log(4, "Early proxy change failed. Will try again at profile load. Error: "+e);
}
// Arrange for our about:tor handler to be loaded in the default (chrome)
// Arrange for our about:i2p handler to be loaded in the default (chrome)
// process as well as in each content process.
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIProcessScriptLoader);
ppmm.loadProcessScript("resource://i2pbutton/components/aboutI2p.js",
true);
ppmm.loadProcessScript("resource://i2pbutton/components/aboutI2p.js", true)
}
StartupObserver.prototype = {
@ -80,12 +73,13 @@ StartupObserver.prototype = {
this._prefs.setIntPref("network.proxy.type", 1);
this._prefs.setIntPref("network.proxy.socks_port", 0);
this._prefs.setCharPref("network.proxy.socks", "");
this._prefs.setIntPref("extensions.i2pbutton.console_port_i2pj", 7647);
this._prefs.setCharPref("network.proxy.http", "127.0.0.1");
this._prefs.setIntPref("network.proxy.http_port", 4444);
this._prefs.setIntPref("network.proxy.http_port", 7644);
this._prefs.setCharPref("network.proxy.ssl", "127.0.0.1");
this._prefs.setIntPref("network.proxy.ssl_port", 4445);
this._prefs.setIntPref("network.proxy.ssl_port", 7644);
this._prefs.setCharPref("network.proxy.ftp", "127.0.0.1");
this._prefs.setIntPref("network.proxy.ftp_port", 4444);
this._prefs.setIntPref("network.proxy.ftp_port", 7644);
this._prefs.setCharPref("network.proxy.no_proxies_on", "localhost, 127.0.0.1");
// Force prefs to be synced to disk
@ -100,8 +94,8 @@ StartupObserver.prototype = {
// but only for hackish reasons.
this._prefs.setBoolPref("extensions.i2pbutton.startup", true);
// We need to listen for NoScript before it starts.
//NoScriptControl.initialize();
// We need to listen for NoScript before it starts.
NoScriptControl.initialize();
this.setProxySettings();
}

View File

@ -1,78 +0,0 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Subprocess.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let EXPORTED_SYMBOLS = [ 'IILauncherSubProcess' ]
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil",
"resource://i2pbutton/modules/launcher-util.jsm")
function _SubProcess(opts)
{
this.kCurrentSubProcessOpts = Object.assign({} ,opts, {
//command: '/bin/ls',
//arguments: ['/'],
workdir: '/',
environment: [],
stderr: "pipe"
})
}
let IILauncherSubProcess = {
createSubProcess: function(opts) {
return new _SubProcess(opts)
}
}
Object.freeze(IILauncherSubProcess)
_SubProcess.prototype = {
kLibVersion: '0.0.1',
kCurrentSubProcess: null,
kCurrentSubProcessStdOutBuffer: null,
init: function() {
//
},
close: function() {
if (this.kCurrentSubProcess !== null)
{
this.kCurrentSubProcess.kill()
this.kCurrentSubProcess = null
}
},
exec: function() {
Subprocess.call(this.kCurrentSubProcessOpts).then(aProc => {
this.kCurrentSubProcess = aProc
new Promise((aResolve, aReject) =>
{
this._readStdOut(aResolve, aReject)
})
})
},
_readStdOut: function (aProc, errReject) {
this.kCurrentSubProcess.stdout.readString().then(out => {
/*if (!out || (out.length == 0))
{
throw new Error('Error: stdout is empty')
}*/
if (this.kCurrentSubProcessStdOutBuffer === null) {
this.kCurrentSubProcessStdOutBuffer = out
} else {
this.kCurrentSubProcessStdOutBuffer += out
}
this._readStdOut(aProc, errReject)
}).catch(err => {
errReject(err)
})
},
await: function() {
let {exitCode} = await this.kCurrentSubProcess.wait()
this.kCurrentSubProcessExitCode = exitCode
return exitCode
}
}

View File

@ -16,7 +16,32 @@ pref("extensions.i2pbutton.local_i2p_check",true);
// https://developer.mozilla.org/en/Addons/Working_with_AMO
pref("extensions.i2pbutton@geti2p.net.getAddons.cache.enabled", false);
pref("extensions.i2pbutton.clear_http_auth", true);
// I2P router control prefs:
pref("extensions.i2pbutton.start_i2p", true);
pref("extensions.i2pbutton.kill_router_on_exit", true);
// State prefs:
pref("extensions.i2pbutton.startup",false);
pref("extensions.i2pbutton.inserted_button",false);
pref("extensions.i2pbutton.inserted_security_level",false);
// Security prefs:
pref("extensions.i2pbutton.cookie_protections",true);
pref("extensions.i2pbutton.cookie_auto_protect",false);
pref("extensions.i2pbutton.clear_http_auth",true);
pref("extensions.i2pbutton.close_newnym",true);
pref("extensions.i2pbutton.resize_new_windows",true);
pref("extensions.i2pbutton.startup_state", 2); // 0=non-i2p, 1=i2p, 2=last
pref("extensions.i2pbutton.i2p_memory_jar",false);
pref("extensions.i2pbutton.noni2p_memory_jar",false);
pref("extensions.i2pbutton.launch_warning",true);
// Security Slider
pref("extensions.i2pbutton.security_slider", 4);
pref("extensions.i2pbutton.security_custom", false);
pref("extensions.i2pbutton.noscript_inited", false);
pref("extensions.i2pbutton.noscript_persist", false);
pref("extensions.i2pbutton.prompt_i2pbrowser", true);
pref("extensions.i2pbutton.confirm_plugins", true);
@ -25,3 +50,15 @@ pref("extensions.i2pbutton.confirm_newnym", true);
pref("extensions.i2pbutton.close_newnym", true);
// Browser home page:
pref("browser.startup.homepage", "chrome://i2pbutton/content/locale/non-localized.properties");
// I2P Startup etc
pref("extensions.i2pbutton.start_i2p", true);
pref("extensions.i2pbutton.kill_router_on_exit", true);
pref("extensions.i2pbutton.console_host", "127.0.0.1");
pref("extensions.i2pbutton.console_port_i2pj", 7647);
pref("extensions.i2pbutton.console_port_i2pd", 17070);
// I2P Implementation
pref("extensions.i2pbutton.i2pimpl_driver", "i2pj");

View File

@ -6,7 +6,7 @@
<em:name>I2pbutton</em:name>
<em:creator>Meeh, Mikal Villa</em:creator>
<em:id>i2pbutton@geti2p.net</em:id>
<em:version>0.2</em:version>
<em:version>0.3.8</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://geti2p.net/en/download/lab</em:homepageURL>
<em:iconURL>chrome://i2pbutton/skin/i2p.png</em:iconURL>

View File

@ -11,6 +11,7 @@ i2pbutton.jar:
skin/ (chrome/skin/*)
% overlay chrome://browser/content/browser.xul chrome://i2pbutton/content/i2pbutton.xul
% overlay chrome://browser/content/preferences/connection.xul chrome://i2pbutton/content/pref-connection.xul
% overlay chrome://messenger/content/messenger.xul chrome://i2pbutton/content/i2pbutton_tb.xul
% overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://i2pbutton/content/i2pbutton_tb.xul
% overlay about:addons chrome://i2pbutton/content/i2pbutton-extensions.xul
@ -26,7 +27,7 @@ i2pbutton.jar:
# UI customization
% overlay chrome://browser/content/browser.xul chrome://i2pbutton/content/menu-items-overlay.xul
% overlay chrome://browser/content/browser.xul chrome://i2pbutton/content/menu-overlay.xul
# Strings for the about:ibupdate page
% override chrome://browser/locale/aboutIBUpdate.dtd chrome://i2pbutton/locale/aboutIBUpdate.dtd
@ -54,6 +55,17 @@ i2pbutton.jar:
% component {f36d72c9-9718-4134-b550-e109638331d7} %components/i2pbutton-logger.js
% contract @geti2p.net/i2pbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d7}
% component {E2AA62BB-AFD0-4D94-9408-90CE39784086} %components/router-config-manager.js
% contract @geti2p.net/i2pbutton-router-config-mgr;1 {E2AA62BB-AFD0-4D94-9408-90CE39784086}
% component {f77babef-dead-b00b-beff-babe6c9afda7} %components/i2p-router-process.js
% contract @geti2p.net/i2pbutton-process-service;1 {f77babef-dead-b00b-beff-babe6c9afda7}
% component {aa132730-beef-dead-babe-0800200c9a66} %components/about-outproxies.js
% contract @geti2p.net/i2pbutton-about-outproxies;1 {aa132730-beef-dead-babe-0800200c9a66}
% category profile-after-change I2PProcessService @geti2p.net/i2pbutton-process-service;1
% category profile-after-change CookieJarSelector @geti2p.net/cookie-jar-selector;1
% category profile-after-change StartupObserver @geti2p.net/startup-observer;1

View File

@ -0,0 +1,93 @@
const EXPORTED_SYMBOLS = ['JsonPrcClient']
// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
const Cc = Components.classes
const Ci = Components.interfaces
const Cr = Components.results
const Cu = Components.utils
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
Cu.import("resource://gre/modules/Log.jsm")
Cu.import("resource://i2pbutton/modules/http.jsm")
Cu.importGlobalProperties(["XMLHttpRequest"])
var log = Log.repository.getLogger("i2pbutton.jsonrpc-client")
log.level = Log.Level.Debug
// A console appender logs to the browser console.
log.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()))
class JsonRpcClient {
constructor(url) {
this.serverUrl = url
this.mReqIdSequence = 0
this.responses = new Array()
this.token = ''
}
_createTemplateData(method, params, id) {
this.mReqIdSequence++
return JSON.stringify({
'id': id || this.mReqIdSequence,
'method': method,
'params': params || {},
'jsonrpc': '2.0'
})
}
_onload(method, callback) {
const self = this
return () => {
console.log('done', method)
switch (method) {
case 'Authenticate':
let jData = JSON.parse(self.xhr.response)
let token = jData.result.Token
self.token = token
break
case 'RouterManager':
break
default:
console.log('Unknown method')
}
if('function' === typeof callback) {
callback(self.xhr)
}
self.responses.push(self.xhr.response)
console.log(self.xhr.responseText)
}
}
makeRequest(method, params, callback) {
this.xhr = new XMLHttpRequest()
this.xhr.open('POST', this.serverUrl)
let data = this._createTemplateData(method, params)
this.xhr.onload = this._onload(method, callback)
this.xhr.setRequestHeader('Content-Length', `${data.length}`)
this.xhr.setRequestHeader('Content-Type', 'application/json')
this.xhr.send(data)
}
}
class I2PControlClient extends JsonRpcClient {
constructor() {
super('http://127.0.0.1:7647/jsonrpc/')
}
authenticate(password, callback) {
this.makeRequest('Authenticate', {'API':1, 'Password':password}, callback)
}
shutdownRouter(callback) {
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Shutdown': true}, callback)
}
reseedRouter(callback) {
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Reseed': true}, callback)
}
restartRouter(callback) {
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Restart': true}, callback)
}
}

View File

@ -1,21 +1,68 @@
let EXPORTED_SYMBOLS = [ 'LauncherUtil' ]
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
const Cc = Components.classes
const Ci = Components.interfaces
const Cu = Components.utils
const Cr = Components.results
Cu.importGlobalProperties(["XMLHttpRequest"])
const kPropBundleURI = "chrome://i2pbutton/locale/i2pbutton.properties"
const kPropNamePrefix = "i2pbutton."
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
Cu.import("resource://gre/modules/Services.jsm")
//const logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
let console = (Cu.import("resource://gre/modules/Console.jsm", {})).console
let LauncherUtil = {
let logger = {
log:function(level, message) {
console.log(message)
}
}
const Timer = Components.Constructor("@mozilla.org/timer;1", "nsITimer", "initWithCallback");
function delay(timeout, func) {
let timer = new Timer(function () {
// Remove the reference so that it can be reaped.
delete delay.timers[idx];
func();
}, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
// Store a reference to the timer so that it's not reaped before it fires.
let idx = delay.timers.push(timer) - 1;
return idx
}
delay.timers = []
function repeat(timeout, func) {
let timer = new Timer(function () {
func();
}, timeout, Ci.nsITimer.TYPE_REPEATING_SLACK);
// Store a reference to the timer so that it's not reaped before it fires.
let idx = delay.timers.push(timer) - 1;
return idx
}
repeat.timers = []
// Wrapper since window.setTimeout isn't always available in context/scope.
function setTimeout(func, interval) {
delay(interval, func)
}
const LauncherUtil = {
get isMac()
{
return LauncherUtilInternal._isMac;
return ("Darwin" == LauncherUtilInternal._OS)
},
get isWindows()
{
return ("WINNT" == LauncherUtilInternal._OS);
return ("WINNT" == LauncherUtilInternal._OS)
},
isAppVersionAtLeast: function(aVersion)
@ -26,46 +73,506 @@ let LauncherUtil = {
.getService(Ci.nsIVersionComparator);
return (vc.compare(appInfo.version, aVersion) >= 0);
},
// Error Reporting / Prompting
showAlert: function(aParentWindow, aMsg)
{
// TODO: alert() does not always resize correctly to fit the message.
try
{
if (!aParentWindow)
{
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator)
let browserWindow = wm.getMostRecentWindow("navigator:browser")
if (LauncherUtilInternal._isWindowVisible(browserWindow))
aParentWindow = browserWindow;
}
var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService);
var title = this.getLocalizedString("error_title");
ps.alert(aParentWindow, title, aMsg);
}
catch (e)
{
alert(aMsg);
}
},
_createOpenWindowArgsArray: function(aArg1, aArg2)
{
var argsArray = Cc["@mozilla.org/array;1"]
.createInstance(Ci.nsIMutableArray);
var variant = Cc["@mozilla.org/variant;1"]
.createInstance(Ci.nsIWritableVariant);
variant.setFromVariant(aArg1);
argsArray.appendElement(variant, false);
if (aArg2)
{
variant = Cc["@mozilla.org/variant;1"]
.createInstance(Ci.nsIWritableVariant);
variant.setFromVariant(aArg2);
argsArray.appendElement(variant, false);
}
return argsArray;
},
setTimeout: (func, interval) => {
delay(interval, func)
},
setInterval: (func, interval) => {
repeat(interval, func)
},
get _networkSettingsWindow()
{
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator)
return wm.getMostRecentWindow("I2PLauncher:NetworkSettings")
},
_openNetworkSettings: function(aIsInitialBootstrap, aStartAtWizardPanel)
{
var win = this._networkSettingsWindow
if (win)
{
// Return to "Starting i2p" panel if being asked to open & dlog already exists.
//win.showStartingI2PPanel()
win.focus()
return;
}
const kSettingsURL = "chrome://i2pbutton/chrome/content/i2pstartup-confdlg.xul"
const kWizardURL = "chrome://i2pbutton/chrome/content/i2pstartup-confdlg-wizard.xul"
var wwSvc = Cc["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Ci.nsIWindowWatcher)
var winFeatures = "chrome,dialog=no,modal,all"
var argsArray = this._createOpenWindowArgsArray(aIsInitialBootstrap,aStartAtWizardPanel)
let isProgress = (this.kWizardProgressPageID == aStartAtWizardPanel)
//let url = (aIsInitialBootstrap || isProgress) ? kWizardURL : kSettingsURL
wwSvc.openWindow(null, kWizardURL, "_blank", winFeatures, argsArray)
},
// Returns true if user confirms; false if not.
// Note that no prompt is shown (and false is returned) if the Network Settings
// window is open.
showConfirm: function(aParentWindow, aMsg, aDefaultButtonLabel, aCancelButtonLabel)
{
try {
if (!aParentWindow) {
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
aParentWindow = wm.getMostRecentWindow("navigator:browser");
}
var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
var title = this.getLocalizedString("error_title");
var btnFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING)
+ ps.BUTTON_POS_0_DEFAULT
+ (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING);
var notUsed = { value: false };
var btnIndex = ps.confirmEx(aParentWindow, title, aMsg, btnFlags,
aDefaultButtonLabel, aCancelButtonLabel,
null, null, notUsed);
return (0 == btnIndex);
} catch (e) {
return confirm(aMsg);
}
return false
},
cleanupTempDirectories: function()
{
try
{
let dirPath = this.getCharPref(LauncherUtilInternal.kIPCDirPrefName);
this.clearUserPref(LauncherUtilInternal.kIPCDirPrefName);
if (dirPath)
{
let f = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
f.initWithPath(dirPath);
if (f.exists())
f.remove(false) // Remove directory if it is empty
}
} catch(e) {}
},
restartBrowser: function() {
let asSvc = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup)
asSvc.quit(0x12) // eAttemptQuit (0x02) + eRestart (0x10)
},
waitForPortToOpen: function(portNum, doneCallback, interval) {
interval = interval || 3000
let portOpen = false
let testPort = () => {
var xhr = new XMLHttpRequest()
xhr.open('GET', `http://127.0.0.1:${portNum}`)
xhr.onerror = () => {
console.log(`Still waiting for ${portNum} to open`)
if (!portOpen) {
setTimeout(testPort, interval)
}
}
xhr.onload = () => {
console.log(`Port ${portNum} seem open now finally`)
portOpen = true
if ('function' === typeof doneCallback) {
doneCallback(portNum)
}
}
xhr.send()
}
testPort()
},
//waitForPortToOpen(7647, () => { console.log('ALL DONE') })
getRouterDefaultArgs: function() {
let dataDir = this.getI2PConfigPath(true)
let exeFile = this.getI2PBinary()
let libDir = dataDir.clone()
let i2pDir = exeFile.parent.parent.clone()
libDir.append('lib')
let args = []
let logFile = dataDir.clone()
logFile.append('wrapper.log')
let nativeLib = libDir.clone()
nativeLib.append('jbigi.jar')
let clientConfigFile = dataDir.clone()
clientConfigFile.append('clients.config')
let routerCofigFile = dataDir.clone()
routerCofigFile.append('router.config')
logger.log(2, `Path for base is => ${i2pDir.path}`)
// NOTE: Don't mind spaces as nsIProcess escapes them.
args.push(`-Di2p.dir.base=${i2pDir.path}`)
args.push(`-Duser.dir=${dataDir.path}`) // make PWD equal dataDir
args.push(`-Dwrapper.logfile=${logFile.path}`)
args.push(`-Djetty.home=${i2pDir.path}`)
args.push(`-Djava.library.path=${libDir.path}`)
args.push(`-Di2p.dir.config=${dataDir.path}`)
args.push(`-Di2p.dir.router=${dataDir.path}`)
args.push(`-Di2p.dir.app=${dataDir.path}`)
args.push(`-Drouter.clientConfigFile=${clientConfigFile.path}`)
args.push(`-Drouter.configLocation=${routerCofigFile.path}`)
args.push('-Di2p.dir.portableMode=false')
args.push('-Dwrapper.name=i2pbrowser')
args.push('-Dwrapper.displayname=I2PBrowser')
args.push('-cp')
args.push(`${i2pDir.path}:${nativeLib.path}:${libDir.path}:${dataDir.path}`)
args.push("-Djava.awt.headless=true")
args.push("-Dwrapper.console.loglevel=DEBUG")
// Main class to execute
args.push("net.i2p.router.Router")
return args
},
writeFileWithData: (file,data,onComplete,onErrorFunc) => {
let converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream)
try {
// file is nsIFile, data is a string
let foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream)
// use 0x02 | 0x10 to open file for appending.
foStream.init(file, 0x02 | 0x08 | 0x20, 0o666, 0)
// write, create, truncate
// In a c file operation, we have no need to set file mode with or operation,
// directly using "r" or "w" usually.
converter.init(foStream, 'UTF-8', 0, 0)
converter.writeString(data)
} catch (err) {
if (typeof onErrorFunc === 'function') {
onErrorFunc(err)
}
} finally {
converter.close() // this closes foStream
if (typeof onComplete === 'function') {
onComplete(file)
}
}
},
/*
spawnRouterWorker: function(handleMessageFunc) {
if (this._currentWorker === undefined) {
let workerFactory = Components.classes['@mozilla.org/threads/workerfactory;1'].createInstance(Components.interfaces.nsIWorkerFactory)
let worker = workerFactory.newChromeWorker('resource://i2pbutton/modules/router-worker.js')
worker.addEventListener('message', handleMessageFunc)
this._currentWorker = worker
}
return this._currentWorker
},
*/
getI2PBinary: function() {
return this.getI2PFile('i2p').clone()
},
getI2PPath: (aI2PFileType, aCreate) => {
return this.getI2PFile(aI2PFileType, aCreate).clone()
},
getI2PConfigPath: (create) => {
// Going backwards from profile works on all OS.
let profDir = Services.dirsvc.get("ProfD", Ci.nsIFile)
let dataDir = profDir.parent.parent.clone()
dataDir.append('I2P')
if (!dataDir.exists() && create) {
dataDir.create(dataDir.DIRECTORY_TYPE, 0o700)
}
return dataDir
},
getI2PFile: function(aI2PFileType, aCreate) {
if (!aI2PFileType) {
aI2PFileType = 'i2p'
}
let i2pFile
let path = ''
let useAppDir = false
let isRelativePath = true
let isUserData = false
let appBaseDir = this.appDirectoryObject.clone()
logger.log(2, `appBaseDir => ${appBaseDir.path}`)
if (this.isWindows) {
//
if ("i2p" == aI2PFileType) {
appBaseDir.append('I2P')
appBaseDir.append('bin')
appBaseDir.append('java.exe')
return appBaseDir
}
} else if (this.isMac) {
if ("i2p" == aI2PFileType) {
path = "Contents/Resources/I2PBrowser/I2P/bin/java"
}
} else {
if ("i2p" == aI2PFileType) {
appBaseDir.append('I2P')
appBaseDir.append('bin')
appBaseDir.append('java')
return appBaseDir
}
}
try {
// Turn 'path' into an absolute path.
i2pFile = LauncherUtilInternal._appDir.clone()
if (!this.isMac) {
let lnxpath = i2pFile.clone()
lnxpath.append(path)
return lnxpath
}
//i2pFile.appendRelativePath(path)
logger.log(2, `getI2PFile - Path before append: ${i2pFile.path}`)
i2pFile.appendRelativePath(path)
logger.log(2, `getI2PFile - Gonna try path ${i2pFile.path}`)
if (i2pFile.exists()) {
try { i2pFile.normalize() } catch(e) {}
logger.log(3, `Decided to use file ${i2pFile.path}`)
return i2pFile
} else {
logger.log(4, aI2PFileType + " file not found: "+ i2pFile.path)
return null
}
} catch(e) {
logger.log(4, `getI2PFile ${aI2PFileType} failed for ${path}: ${e}`)
return null
}
},
get internal() {
return LauncherUtilInternal
},
get dataDirectoryObject() {
let dataDir = LauncherUtilInternal._dataDir
try { dataDir.normalize() } catch(e) {}
logger.log(3, `Decided to use file ${dataDir.path}`)
return dataDir.clone()
},
get appDirectoryObject() {
return LauncherUtilInternal._appDir.clone()
},
flushLocalizedStringCache: function()
{
LauncherUtilInternal.mStringBundle = undefined
},
// "i2pbutton." is prepended to aStringName.
getLocalizedString: function(aStringName)
{
if (!aStringName)
return aStringName;
try
{
var key = kPropNamePrefix + aStringName;
return LauncherUtilInternal._stringBundle.GetStringFromName(key);
} catch(e) {}
return aStringName;
},
// "i2pbutton." is prepended to aStringName.
getFormattedLocalizedString: function(aStringName, aArray, aLen)
{
if (!aStringName || !aArray)
return aStringName;
try
{
var key = kPropNamePrefix + aStringName;
return LauncherUtilInternal._stringBundle.formatStringFromName(key, aArray, aLen)
} catch(e) {}
return aStringName;
},
getLocalizedStringForError: function(aNSResult)
{
for (let prop in Cr)
{
if (Cr[prop] == aNSResult)
{
let key = "nsresult." + prop;
let rv = this.getLocalizedString(key);
if (rv !== key)
return rv;
return prop; // As a fallback, return the NS_ERROR... name.
}
}
return undefined;
},
}
Object.freeze(LauncherUtil)
let LauncherUtilInternal = {
kThunderbirdID: "{3550f703-e582-4d05-9a08-453d09bdfdc6}",
kInstantbirdID: "{33cb9019-c295-46dd-be21-8c4936574bee}",
mOS: '',
mStringBundle : null,
mPrefsSvc : null,
mAppDir: null, // nsIFile (cached; access via this._appDir)
mDataDir: null, // nsIFile (cached; access via this._dataDir)
mIsUserDataOutsideOfAppDir: undefined,
_init: function() {
// Init
this.mPrefsSvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
this._appDir
this._dataDir
},
get _OS()
{
if (!this.mOS) try
{
var xr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
this.mOS = xr.OS;
const xr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
this.mOS = xr.OS
} catch (e) {}
return this.mOS;
return this.mOS
},
get _isMac()
{
return ("Darwin" == this._OS);
},
get _stringBundle()
{
if (!this.mStringBundle)
{
this.mStringBundle = Cc["@mozilla.org/intl/stringbundle;1"]
.getService(Ci.nsIStringBundleService)
.createBundle(kPropBundleURI);
this.mStringBundle = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService).createBundle(kPropBundleURI)
}
return this.mStringBundle;
},
get _dataDir()
{
if (!this.mDataDir)
{
let ds = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties);
let profDir = ds.get("ProfD", Ci.nsIFile);
this.mDataDir = profDir.parent.parent;
get _isUserDataOutsideOfAppDir() {
if (this.mIsUserDataOutsideOfAppDir == undefined) {
// Determine if we are using a "side-by-side" data model by checking
// whether the user profile is outside of the app directory.
try {
let ds = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties)
let profDir = ds.get("ProfD", Ci.nsIFile)
this.mIsUserDataOutsideOfAppDir = !this._appDir.contains(profDir);
} catch (e) {
this.mIsUserDataOutsideOfAppDir = false;
}
}
return this.mDataDir;
return this.mIsUserDataOutsideOfAppDir;
}, // get _isUserDataOutsideOfAppDir
// Returns an nsIFile that points to the application directory.
// May throw.
get _appDir() {
if (!this.mAppDir) {
let topDir = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile)
let appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo)
// On Linux and Windows, we want to return the Browser/ directory.
// Because topDir ("CurProcD") points to Browser/browser on those
// platforms, we need to go up one level.
// On Mac OS, we want to return the I2PBrowser.app/ directory.
// Because topDir points to Contents/Resources/browser on Mac OS,
// we need to go up 3 levels.
let i2bbBrowserDepth = (this._OS == "Darwin") ? 3 : 1;
if ((appInfo.ID == this.kThunderbirdID) ||
(appInfo.ID == this.kInstantbirdID)) {
// On Thunderbird/Instantbird, the topDir is the root dir and not
// browser/, so we need to iterate one level less than Firefox.
--i2bbBrowserDepth;
}
while (i2bbBrowserDepth > 0) {
let didRemove = (topDir.leafName != ".")
topDir = topDir.parent
if (didRemove)
i2bbBrowserDepth--
}
this.mAppDir = topDir
}
return this.mAppDir
}, // get _appDir
// Returns an nsIFile that points to the I2PBrowser-Data/ directory.
// This function is only used when this._isUserDataOutsideOfAppDir == true.
// May throw.
get _dataDir() {
if (!this.mDataDir) {
let ds = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties)
let profDir = ds.get("ProfD", Ci.nsIFile)
this.mDataDir = profDir.parent.parent.clone()
}
return this.mDataDir.clone()
}, // get _dataDir
_isWindowVisible: function(aWindow) {
if (!aWindow)
return false
try {
let winUtils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
return winUtils.isParentWindowMainWidgetVisible
} catch(e) {}
return false
},
}
LauncherUtilInternal._init()

View File

@ -0,0 +1,202 @@
// # NoScript settings control (for binding to Security Slider)
/* jshint esversion:6 */
// ## Utilities
const { utils: Cu } = Components;
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const { LegacyExtensionContext } =
Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
let logger = Components.classes["@geti2p.net/i2pbutton-logger;1"]
.getService(Components.interfaces.nsISupports).wrappedJSObject;
let log = (level, msg) => logger.log(level, msg);
// __prefs__. A shortcut to Mozilla Services.prefs.
let prefs = Services.prefs;
// __getPrefValue(prefName)__
// Returns the current value of a preference, regardless of its type.
var getPrefValue = function (prefName) {
switch(prefs.getPrefType(prefName)) {
case prefs.PREF_BOOL: return prefs.getBoolPref(prefName);
case prefs.PREF_INT: return prefs.getIntPref(prefName);
case prefs.PREF_STRING: return prefs.getCharPref(prefName);
default: return null;
}
};
// __bindPref(prefName, prefHandler, init)__
// Applies prefHandler whenever the value of the pref changes.
// If init is true, applies prefHandler to the current value.
// Returns a zero-arg function that unbinds the pref.
var bindPref = function (prefName, prefHandler, init = false) {
let update = () => { prefHandler(getPrefValue(prefName)); },
observer = { observe : function (subject, topic, data) {
if (data === prefName) {
update();
}
} };
prefs.addObserver(prefName, observer, false);
if (init) {
update();
}
return () => { prefs.removeObserver(prefName, observer); };
};
// __bindPrefAndInit(prefName, prefHandler)__
// Applies prefHandler to the current value of pref specified by prefName.
// Re-applies prefHandler whenever the value of the pref changes.
// Returns a zero-arg function that unbinds the pref.
var bindPrefAndInit = (prefName, prefHandler) =>
bindPref(prefName, prefHandler, true);
// ## NoScript settings
// Minimum and maximum capability states as controlled by NoScript.
const max_caps = ["fetch", "font", "frame", "media", "object", "other", "script", "webgl"];
const min_caps = ["frame", "other"];
// Untrusted capabilities for [Standard, Safer, Safest] safety levels.
const untrusted_caps = [
max_caps, // standard safety: neither http nor https
["frame", "font", "object", "other"], // safer: http
min_caps, // safest: neither http nor https
];
// Default capabilities for [Standard, Safer, Safest] safety levels.
const default_caps = [
max_caps, // standard: both http and https
["fetch", "font", "frame", "object", "other", "script"], // safer: https only
min_caps, // safest: both http and https
];
// __noscriptSettings(safetyLevel)__.
// Produces NoScript settings with policy according to
// the safetyLevel which can be:
// 0 = Standard, 1 = Safer, 2 = Safest
//
// At the "Standard" safety level, we leave all sites at
// default with maximal capabilities. Essentially no content
// is blocked.
//
// At "Safer", we set all http sites to untrusted,
// and all https sites to default. Scripts are only permitted
// on https sites. Neither type of site is supposed to allow
// media, but both allow fonts (as we used in legacy NoScript).
//
// At "Safest", all sites are at default with minimal
// capabilities. Most things are blocked.
let noscriptSettings = safetyLevel => (
{
"__meta": {
"name": "updateSettings",
"recipientInfo": null
},
"policy": {
"DEFAULT": {
"capabilities": default_caps[safetyLevel],
"temp": false
},
"TRUSTED": {
"capabilities": max_caps,
"temp": false
},
"UNTRUSTED": {
"capabilities": untrusted_caps[safetyLevel],
"temp": false
},
"sites": {
"trusted": [],
"untrusted": [[], ["http:"], []][safetyLevel],
"custom": {},
"temp": []
},
"enforced": true,
"autoAllowTop": false
},
"isI2PBrowser": true,
"tabId": -1
});
// ## Communications
// The extension ID for NoScript (WebExtension)
const noscriptID = "{73a6fe31-595d-460b-a920-fcc0f8843232}";
// Ensure binding only occurs once.
let initialized = false;
// __initialize()__.
// The main function that binds the NoScript settings to the security
// slider pref state.
var initialize = () => {
if (initialized) {
return;
}
initialized = true;
try {
// A mock extension object that can communicate with another extension
// via the WebExtensions sendMessage/onMessage mechanism.
let extensionContext = new LegacyExtensionContext({ id : noscriptID });
// The component that handles WebExtensions' sendMessage.
let messageManager = extensionContext.messenger.messageManagers[0];
// __setNoScriptSettings(settings)__.
// NoScript listens for internal settings with onMessage. We can send
// a new settings JSON object according to NoScript's
// protocol and these are accepted! See the use of
// `browser.runtime.onMessage.addListener(...)` in NoScript's bg/main.js.
let sendNoScriptSettings = settings =>
extensionContext.messenger.sendMessage(messageManager, settings, noscriptID);
// __setNoScriptSafetyLevel(safetyLevel)__.
// Set NoScript settings according to a particular safety level
// (security slider level): 0 = Standard, 1 = Safer, 2 = Safest
let setNoScriptSafetyLevel = safetyLevel =>
sendNoScriptSettings(noscriptSettings(safetyLevel));
// __securitySliderToSafetyLevel(sliderState)__.
// Converts the "extensions.i2pbutton.security_slider" pref value
// to a "safety level" value: 0 = Standard, 1 = Safer, 2 = Safest
let securitySliderToSafetyLevel = sliderState =>
[undefined, 2, 1, 1, 0][sliderState];
// Wait for the first message from NoScript to arrive, and then
// bind the security_slider pref to the NoScript settings.
let messageListener = (a,b,c) => {
try {
log(3, `Message received from NoScript: ${JSON.stringify([a,b,c])}`);
if (!["started", "pageshow"].includes(a.__meta.name)) {
return;
}
extensionContext.api.browser.runtime.onMessage.removeListener(messageListener);
let noscriptPersist = Services.prefs.getBoolPref("extensions.i2pbutton.noscript_persist", false);
let noscriptInited = Services.prefs.getBoolPref("extensions.i2pbutton.noscript_inited", false);
// Set the noscript safety level once if we have never run noscript
// before, or if we are not allowing noscript per-site settings to be
// persisted between browser sessions. Otherwise make sure that the
// security slider position, if changed, will rewrite the noscript
// settings.
bindPref("extensions.i2pbutton.security_slider",
sliderState => setNoScriptSafetyLevel(securitySliderToSafetyLevel(sliderState)),
!noscriptPersist || !noscriptInited);
if (!noscriptInited) {
Services.prefs.setBoolPref("extensions.i2pbutton.noscript_inited", true);
}
} catch (e) {
log(5, e.message);
}
};
extensionContext.api.browser.runtime.onMessage.addListener(messageListener);
log(3, "Listening for message from NoScript.");
} catch (e) {
log(5, e.message);
}
};
// Export initialize() function for external use.
let EXPORTED_SYMBOLS = ["initialize"];

View File

@ -0,0 +1,135 @@
// # Security Settings prefs (as controlled by the Security Slider)
// ### Utilities
let {classes: Cc, utils: Cu } = Components;
let { getBoolPref, setBoolPref, getIntPref, setIntPref } =
Cu.import("resource://gre/modules/Services.jsm", {}).Services.prefs;
let { bindPref, bindPrefAndInit } =
Cu.import("resource://i2pbutton/modules/utils.js", {});
let logger = Components.classes["@geti2p.net/i2pbutton-logger;1"]
.getService(Components.interfaces.nsISupports).wrappedJSObject;
let log = (level, msg) => logger.log(level, msg);
// ### Constants
// __kSecuritySettings__.
// A table of all prefs bound to the security slider, and the value
// for each security setting. Note that 2-m and 3-m are identical,
// corresponding to the old 2-medium-high setting. We also separately
// bind NoScript settings to the extensions.i2pbutton.security_slider
// (see noscript-control.js).
const kSecuritySettings = {
// Preference name : [0, 1-high 2-m 3-m 4-low]
"javascript.options.ion" : [, false, false, false, true ],
"javascript.options.baselinejit" : [, false, false, false, true ],
"javascript.options.native_regexp" : [, false, false, false, true ],
"media.webaudio.enabled" : [, false, false, false, true ],
"mathml.disabled" : [, true, true, true, false],
"gfx.font_rendering.opentype_svg.enabled" : [, false, false, false, true ],
"svg.disabled" : [, true, false, false, false],
};
// The Security Settings prefs in question.
const kSliderPref = "extensions.i2pbutton.security_slider";
const kCustomPref = "extensions.i2pbutton.security_custom";
// ### Prefs
// __write_setting_to_prefs(settingIndex)__.
// Take a given setting index and write the appropriate pref values
// to the pref database.
var write_setting_to_prefs = function (settingIndex) {
Object.keys(kSecuritySettings).forEach(
prefName => setBoolPref(
prefName, kSecuritySettings[prefName][settingIndex]));
};
// __read_setting_from_prefs()__.
// Read the current pref values, and decide if any of our
// security settings matches. Otherwise return null.
var read_setting_from_prefs = function () {
let prefNames = Object.keys(kSecuritySettings);
for (let settingIndex of [1, 2, 3, 4]) {
let possibleSetting = true;
// For the given settingIndex, check if all current pref values
// match the setting.
for (let prefName of prefNames) {
if (kSecuritySettings[prefName][settingIndex] !==
getBoolPref(prefName)) {
possibleSetting = false;
}
}
if (possibleSetting) {
// We have a match!
return settingIndex;
}
}
// No matching setting; return null.
return null;
};
// __watch_security_prefs(onSettingChanged)__.
// Whenever a pref bound to the security slider changes, onSettingChanged
// is called with the new security setting value (1,2,3,4 or null).
// Returns a zero-arg function that ends this binding.
var watch_security_prefs = function (onSettingChanged) {
let prefNames = Object.keys(kSecuritySettings);
let unbindFuncs = [];
for (let prefName of prefNames) {
unbindFuncs.push(bindPrefAndInit(
prefName, () => onSettingChanged(read_setting_from_prefs())));
}
// Call all the unbind functions.
return () => unbindFuncs.forEach(unbind => unbind());
};
// __initialized__.
// Have we called initialize() yet?
var initialized = false;
// __initialize()__.
// Defines the behavior of "extensions.i2pbutton.security_custom",
// "extensions.i2pbutton.security_slider", and the security-sensitive
// prefs declared in kSecuritySettings.
var initialize = function () {
// Only run once.
if (initialized) {
return;
}
log(4, "Initializing security-prefs.js");
initialized = true;
// When security_custom is set to false, apply security_slider setting
// to the security-sensitive prefs.
bindPrefAndInit(kCustomPref, function (custom) {
if (custom === false) {
write_setting_to_prefs(getIntPref(kSliderPref));
}
});
// If security_slider is given a new value, then security_custom should
// be set to false.
bindPref(kSliderPref, function (prefIndex) {
setBoolPref(kCustomPref, false);
write_setting_to_prefs(prefIndex);
});
// If a security-sensitive pref changes, then decide if the set of pref values
// constitutes a security_slider setting or a custom value.
watch_security_prefs(settingIndex => {
if (settingIndex === null) {
setBoolPref(kCustomPref, true);
} else {
setIntPref(kSliderPref, settingIndex);
setBoolPref(kCustomPref, false);
}
});
// Migrate from old medium-low (3) to new medium (2).
if (getBoolPref("extensions.i2pbutton.security_custom") === false &&
getIntPref("extensions.i2pbutton.security_slider") === 3) {
setIntPref("extensions.i2pbutton.security_slider", 2);
write_setting_to_prefs(2);
}
log(4, "security-prefs.js initialization complete");
};
// Export initialize() function for external use.
let EXPORTED_SYMBOLS = ["initialize"];

View File

@ -3,12 +3,52 @@ const { Cu: utils, Cr: results } = Components
// ### Import Mozilla Services
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/FileUtils.jsm")
//Cu.import("resource://gre/modules/FileUtils.jsm")
// ### Import global URL
Cu.importGlobalProperties(["URL"])
const ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService)
//const ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService)
String.prototype.trim = function () {
return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
/*
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
*/
function loadScript(name, context) {
// Create the Sandbox
let sandbox = Components.utils.Sandbox(context, {
sandboxPrototype: context,
wantXrays: false
});
// Get the caller's filename
let file = Components.caller.stack.filename;
// Strip off any prefixes added by the sub-script loader
// and the trailing filename
let directory = file.replace(/.* -> |[^\/]+$/g, "");
Services.scriptloader.loadSubScript(directory + name, sandbox, "UTF-8");
}
// The following function will import an arbitrary module into a singleton object,
// which it returns. If the argument is not an absolute path, the module is
// imported relative to the caller's filename.
function module(uri) {
if (!/^[a-z-]+:/.exec(uri))
uri = /([^ ]+\/)[^\/]+$/.exec(Components.stack.caller.filename)[1] + uri + ".jsm";
let obj = {};
Components.utils.import(uri, obj);
return obj;
}
/**
*
@ -37,7 +77,55 @@ const getProfileDir = function() {
getService(Ci.nsIProperties)
// this is a reference to the profile dir (ProfD) now.
let localDir = directoryService.get("ProfD", Ci.nsIFile)
return localDir.path
return localDir
}
function openFile(path, mode) {
let file = Cc["@mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
file.initWithPath(path);
let stream = Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream);
stream.init(file, mode, -1, 0);
return stream
}
function readfile(path) {
var file = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsIFile);
file.initWithPath(path);
var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
.createInstance(Components.interfaces.nsIFileInputStream);
fileStream.init(file, 1, 0, false);
var binaryStream = Components.classes['@mozilla.org/binaryinputstream;1']
.createInstance(Components.interfaces.nsIBinaryInputStream);
binaryStream.setInputStream(fileStream);
var array = binaryStream.readByteArray(fileStream.available());
binaryStream.close();
fileStream.close();
return array_to_hexdigits(array);
}
// Bug 1506 P4: Control port interaction. Needed for New Identity.
function array_to_hexdigits(array) {
return array.map(function(c) {
return String("0" + c.toString(16)).slice(-2)
}).join('');
}
function listExtensions(callbackFn) {
AddonManager.getAddonsByTypes(["extension"], function(addons) {
var addonData = [];
for (let i in addons) {
let cur = addons[i];
addonData.push({
id: cur.id.toString(),
name: cur.name,
});
};
console.log(JSON.stringify(addonData, null, ' '));
callbackFn(addonData)
});
}
//window.open("chrome://browser/content/browser.xul", "bmarks", "chrome,width=600,height=300")
@ -63,10 +151,10 @@ var getPrefValue = function (prefName) {
var bindPref = function (prefName, prefHandler, init = false) {
let update = () => { prefHandler(getPrefValue(prefName)); },
observer = { observe : function (subject, topic, data) {
if (data === prefName) {
update();
}
} };
if (data === prefName) {
update();
}
} };
prefs.addObserver(prefName, observer, false);
if (init) {
update();
@ -128,18 +216,23 @@ let dialogsByName = {};
// Like window.openDialog, but if the window is already
// open, just focuses it instead of opening a new one.
var showDialog = function (parent, url, name, features) {
let existingDialog = dialogsByName[name];
let existingDialog = dialogsByName[name]
if (existingDialog && !existingDialog.closed) {
existingDialog.focus();
return existingDialog;
existingDialog.focus()
return existingDialog
} else {
let newDialog = parent.openDialog.apply(parent,
Array.slice(arguments, 1));
dialogsByName[name] = newDialog;
return newDialog;
let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1))
dialogsByName[name] = newDialog
return newDialog
}
}
var openTabWithFocus = function (url) {
gBrowser.selectedTab = gBrowser.addTab(url)
}
// Export utility functions for external use.
let EXPORTED_SYMBOLS = ['bindPref', 'bindPrefAndInit', 'getEnv', 'getLocale',
'loadScript', 'module', 'readfile', 'getProfileDir',
'getPrefValue', 'observe', 'showDialog'];

View File

@ -0,0 +1,10 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Legwork</ShortName>
<Description>Legwork YaCy Search Engine</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">
<!-- Insert data:image/x-icon;base64,blablabla here -->
</Image>
<Url type="text/html" method="GET" template="http://legwork.i2p/yacysearch.html?query={searchTerms}"/>
<SearchForm>http://legwork.i2p/</SearchForm>
</SearchPlugin>

View File

@ -0,0 +1,10 @@
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>Seeker</ShortName>
<Description>Seeker Search Engine</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">
<!-- Insert data:image/x-icon;base64,blablabla here -->
</Image>
<Url type="text/html" method="GET" template="http://seeker.i2p/index.php?query={searchTerms}"/>
<SearchForm>http://seeker.i2p/</SearchForm>
</SearchPlugin>