"use strict" ;
const override = Cc["@mozilla.org/network/native-dns-override;1" ].getService(
Ci.nsINativeDNSResolverOverride
);
const mockNetwork = Cc[
"@mozilla.org/network/mock-network-controller;1"
].getService(Ci.nsIMockNetworkLayerController);
const certOverrideService = Cc[
"@mozilla.org/security/certoverride;1"
].getService(Ci.nsICertOverrideService);
const { AppConstants } = ChromeUtils.importESModule(
"resource://gre/modules/AppConstants.sys.mjs"
);
const { NodeHTTPServer, NodeHTTPSServer } = ChromeUtils.importESModule(
"resource://testing-common/NodeServer.sys.mjs"
);
const DOMAIN = "example.org" ;
function makeChan(url, expected) {
let chan = NetUtil.newChannel({
uri: url,
loadUsingSystemPrincipal: true ,
contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
}).QueryInterface(Ci.nsIHttpChannel);
if (
expected.PublicToPrivateHttp !== undefined ||
expected.PublicToLocalHttp !== undefined ||
expected.PublicToPublicHttp !== undefined ||
expected.PublicToPrivateHttps !== undefined ||
expected.PublicToLocalHttps !== undefined ||
expected.PublicToPublicHttp !== undefined
) {
chan.loadInfo.parentIpAddressSpace = Ci.nsILoadInfo.Public ;
} else if (
expected.PrivateToLocalHttp !== undefined ||
expected.PrivateToPrivateHttp !== undefined ||
expected.PrivateToLocalHttps !== undefined ||
expected.PrivateToPrivateHttps !== undefined
) {
chan.loadInfo.parentIpAddressSpace = Ci.nsILoadInfo.Private ;
}
return chan;
}
function channelOpenPromise(chan, flags) {
return new Promise(resolve => {
function finish(req, buffer) {
resolve([req, buffer]);
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
false
);
}
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
true
);
chan.asyncOpen(new ChannelListener(finish, null , flags));
});
}
let server;
add_setup(async function setup() {
Services.prefs.setBoolPref("network.socket.attach_mock_network_layer" , true );
Services.fog.initializeFOG();
server = new NodeHTTPServer();
await server.start();
registerCleanupFunction(async () => {
Services.prefs.clearUserPref("network.disable-localhost-when-offline" );
Services.prefs.clearUserPref("network.dns.use_override_as_peer_address" );
Services.prefs.clearUserPref("dom.security.https_only_mode" );
Services.prefs.clearUserPref("dom.security.https_first" );
Services.prefs.clearUserPref("dom.security.https_first_schemeless" );
Services.prefs.clearUserPref("network.socket.attach_mock_network_layer" );
await server.stop();
});
});
function verifyGleanValues(aDescription, aExpected) {
info(aDescription);
let privateToLocalHttp = aExpected.PrivateToLocalHttp || null ;
let publicToPrivateHttp = aExpected.PublicToPrivateHttp || null ;
let publicToLocalHttp = aExpected.PublicToLocalHttp || null ;
let privateToLocalHttps = aExpected.PrivateToLocalHttps || null ;
let publicToPrivateHttps = aExpected.PublicToPrivateHttps || null ;
let publicToLocalHttps = aExpected.PublicToLocalHttps || null ;
let glean = Glean.networking.localNetworkAccess;
Assert .equal(
glean.private_to_local_http.testGetValue(),
privateToLocalHttp,
"verify private_to_local_http"
);
Assert .equal(
glean.public_to_private_http.testGetValue(),
publicToPrivateHttp,
"verify public_to_private_http"
);
Assert .equal(
glean.public_to_local_http.testGetValue(),
publicToLocalHttp,
"verify public_to_local_http"
);
Assert .equal(
glean.private_to_local_https.testGetValue(),
privateToLocalHttps,
"verify private_to_local_http"
);
Assert .equal(
glean.public_to_private_https.testGetValue(),
publicToPrivateHttps,
"verify public_to_private_http"
);
Assert .equal(
glean.public_to_local_https.testGetValue(),
publicToLocalHttps,
"verify public_to_local_http"
);
Assert .equal(
glean.public_to_local_https.testGetValue(),
publicToLocalHttps,
"verify public_to_local_http"
);
if (
privateToLocalHttp ||
publicToPrivateHttp ||
publicToLocalHttp ||
privateToLocalHttps ||
publicToPrivateHttps ||
publicToLocalHttps
) {
Assert .equal(
glean.success.testGetValue(),
1 ,
"verify local_network_access_success"
);
// XXX (sunil) add test for local_network_access_failure cases
}
}
async function do_test(ip, expected, srcPort, dstPort) {
Services.fog.testResetFOG();
override.addIPOverride(DOMAIN, ip);
let fromAddr = mockNetwork.createScriptableNetAddr(ip, srcPort ?? 80 );
let toAddr = mockNetwork.createScriptableNetAddr(
fromAddr.family == Ci.nsINetAddr.FAMILY_INET ? "127.0.0.1" : "::1" ,
dstPort ?? server.port()
);
mockNetwork.addNetAddrOverride(fromAddr, toAddr);
info(`do_test ${ip}, ${fromAddr} -> ${toAddr}`);
let chan = makeChan(`http://${DOMAIN}`, expected);
let [req] = await channelOpenPromise(chan);
info(
"req.remoteAddress=" +
req.QueryInterface(Ci.nsIHttpChannelInternal).remoteAddress
);
if (expected.PublicToPrivateHttp) {
Assert .equal(chan.loadInfo.ipAddressSpace, Ci.nsILoadInfo.Private );
} else if (expected.PrivateToLocalHttp || expected.PrivateToLocalHttp) {
Assert .equal(chan.loadInfo.ipAddressSpace, Ci.nsILoadInfo.Local);
}
verifyGleanValues(`test ip=${ip}`, expected);
Services.dns.clearCache(false );
override.clearOverrides();
mockNetwork.clearNetAddrOverrides();
Services.obs.notifyObservers(null , "net:prune-all-connections" );
}
add_task(async function test_lna_http() {
Services.prefs.setBoolPref("dom.security.https_only_mode" , false );
Services.prefs.setBoolPref("dom.security.https_first" , false );
Services.prefs.setBoolPref("dom.security.https_first_schemeless" , false );
await do_test("10.0.0.1" , { PublicToPrivateHttp: 1 });
// NO LNA access do not increment
await do_test("10.0.0.1" , { PrivateToPrivateHttp: 0 });
await do_test("2.2.2.2" , { PublicToPublicHttp: 0 });
await do_test("100.64.0.1" , { PublicToPrivateHttp: 1 });
await do_test("127.0.0.1" , { PublicToLocalHttp: 1 });
await do_test("127.0.0.1" , { PrivateToLocalHttp: 1 });
if (AppConstants.platform != "android" ) {
await do_test("::1" , { PrivateToLocalHttp: 1 });
}
});
add_task(async function test_lna_https() {
Services.prefs.setBoolPref("dom.security.https_only_mode" , true );
let httpsServer = new NodeHTTPSServer();
await httpsServer.start();
registerCleanupFunction(async () => {
await httpsServer.stop();
});
await do_test(
"10.0.0.1" ,
{ PublicToPrivateHttps: 1 },
443 ,
httpsServer.port()
);
// NO LNA access do not increment
await do_test(
"10.0.0.1" ,
{ PrivateToPrivateHttps: 0 },
443 ,
httpsServer.port()
);
await do_test(
"2.2.2.2" ,
{ PublicToPublicHttps: 0 },
443 ,
httpsServer.port(),
true
);
await do_test(
"100.64.0.1" ,
{ PublicToPrivateHttps: 1 },
443 ,
httpsServer.port()
);
await do_test(
"127.0.0.1" ,
{ PublicToLocalHttps: 1 },
443 ,
httpsServer.port()
);
await do_test(
"127.0.0.1" ,
{ PrivateToLocalHttps: 1 },
443 ,
httpsServer.port()
);
if (AppConstants.platform != "android" ) {
await do_test("::1" , { PrivateToLocalHttps: 1 }, 443 , httpsServer.port());
}
});
Messung V0.5 in Prozent C=98 H=100 G=98
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-10-02)
¤
*© Formatika GbR, Deutschland