-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add TLS support to fetch based networking. #1361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| import { LOG_FETCH } from "../const.js"; | ||
| import { h } from "../lib.js"; | ||
| import { dbg_log } from "../log.js"; | ||
|
|
||
| import { | ||
|
|
@@ -36,6 +35,14 @@ export function FetchNetworkAdapter(bus, config) | |
| this.eth_encoder_buf = create_eth_encoder_buf(); | ||
| this.fetch = (...args) => fetch(...args); | ||
|
|
||
| eval(`import("../../build/mitm.mjs")`).then(factory => factory.default()).then(obj => { | ||
| this.tls = new obj["MITM"](); | ||
| this.tls["generateECCPrivateKey"](); | ||
| }).catch(e => { | ||
| console.log(e); | ||
| dbg_log("No TLS library detected."); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing |
||
| }); | ||
|
|
||
| // Ex: 'https://corsproxy.io/?' | ||
| this.cors_proxy = config.cors_proxy; | ||
|
|
||
|
|
@@ -46,27 +53,22 @@ export function FetchNetworkAdapter(bus, config) | |
| { | ||
| this.send(data); | ||
| }, this); | ||
| this.bus.register("tcp-connection", (conn) => { | ||
| if(conn.sport === 80) { | ||
| conn.on("data", on_data_http); | ||
| conn.accept(); | ||
| } | ||
| if(conn.sport === 443 && this.tls) { | ||
| conn.on("data", on_data_tls.bind(conn, {net: this})); | ||
| conn.accept(); | ||
| } | ||
| }, this); | ||
| } | ||
|
|
||
| FetchNetworkAdapter.prototype.destroy = function() | ||
| { | ||
| }; | ||
|
|
||
| FetchNetworkAdapter.prototype.on_tcp_connection = function(packet, tuple) | ||
| { | ||
| if(packet.tcp.dport === 80) { | ||
| let conn = new TCPConnection(); | ||
| conn.state = TCP_STATE_SYN_RECEIVED; | ||
| conn.net = this; | ||
| conn.on("data", on_data_http); | ||
| conn.tuple = tuple; | ||
| conn.accept(packet); | ||
| this.tcp_conn[tuple] = conn; | ||
| return true; | ||
| } | ||
| return false; | ||
| }; | ||
|
|
||
| FetchNetworkAdapter.prototype.connect = function(port) | ||
| { | ||
| return fake_tcp_connect(port, this); | ||
|
|
@@ -104,6 +106,9 @@ async function on_data_http(data) | |
| // fix "Mixed Content" errors | ||
| target.protocol = "https:"; | ||
| } | ||
| else if(this.tls) { | ||
| target.protocol = "https:"; | ||
| } | ||
|
|
||
| let req_headers = new Headers(); | ||
| for(let i = 1; i < headers.length; ++i) { | ||
|
|
@@ -144,7 +149,7 @@ async function on_data_http(data) | |
| const fetch_url = this.net.cors_proxy ? this.net.cors_proxy + encodeURIComponent(target.href) : target.href; | ||
| const encoder = new TextEncoder(); | ||
| let response_started = false; | ||
| this.net.fetch(fetch_url, opts).then((resp) => { | ||
| let handler = (resp) => { | ||
| let resp_headers = new Headers(resp.headers); | ||
| resp_headers.delete("content-encoding"); | ||
| resp_headers.delete("keep-alive"); | ||
|
|
@@ -177,7 +182,13 @@ async function on_data_http(data) | |
| this.close(); | ||
| }); | ||
| } | ||
| }) | ||
| }; | ||
|
|
||
| if(this.net.tls && /^https?:[/][/]mitm[.]it[/](ca|cert)[/.]pem/.test(target.href)) { | ||
| return handler(new Response(this.net.tls["getCACertificate"]())); | ||
| } | ||
|
|
||
| this.net.fetch(fetch_url, opts).then(handler) | ||
| .catch((e) => { | ||
| console.warn("Fetch Failed: " + fetch_url + "\n" + e); | ||
| if(!response_started) { | ||
|
|
@@ -188,6 +199,36 @@ async function on_data_http(data) | |
| } | ||
| } | ||
|
|
||
|
|
||
| async function on_data_tls(ctx, data) | ||
| { | ||
| let packet = this; | ||
| if(!ctx.tls) { | ||
| ctx.tls = packet.net.tls["ssl"](); | ||
| ctx.write = d => { | ||
| let r = ctx.tls["dataIn"](d); | ||
| }; | ||
| ctx.writev = v => { | ||
| for(const data of v) { | ||
| let r = ctx.tls["dataIn"](data); | ||
| } | ||
| }; | ||
| ctx.close = () => { | ||
| ctx.tls["close"](); | ||
| setTimeout(()=> packet.close(), 100); | ||
| }; | ||
|
|
||
| ctx.tls["setPacketOutCallback"](d => { | ||
| let r = packet.write(d); | ||
| }); | ||
|
|
||
| ctx.tls["setDataOutCallback"](d => { | ||
| on_data_http.call(ctx, d); | ||
| }); | ||
| } | ||
| ctx.tls["packetIn"](data); | ||
| } | ||
|
|
||
| FetchNetworkAdapter.prototype.fetch = async function(url, options) | ||
| { | ||
| if(this.cors_proxy) url = this.cors_proxy + encodeURIComponent(url); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -242,9 +242,11 @@ V86.prototype.continue_init = async function(emulator, options) | |
| if(relay_url) | ||
| { | ||
| // TODO: remove bus, use direct calls instead | ||
| if(relay_url === "fetch") | ||
| if(relay_url.startsWith("fetch")) | ||
| { | ||
| this.network_adapter = new FetchNetworkAdapter(this.bus, options.net_device); | ||
| let parts = relay_url.split(";"); | ||
| if(parts[1]) this.network_adapter.cors_proxy = parts[1]; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #1189 (comment) |
||
| } | ||
| else if(relay_url === "inbrowser") | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,11 +107,9 @@ export function VirtioConsole(cpu, bus) | |
| { | ||
| dbg_assert(false, "VirtioConsole Notified for wrong queue: " + queue_id + | ||
| " (expected queue_id of 2)"); | ||
| return; | ||
|
|
||
| } | ||
| const queue = this.virtio.queues[queue_id]; | ||
| // Full buffer looks like an empty buffer so prevent it from filling | ||
| while(queue.count_requests() > queue.size - 2) queue.pop_request(); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you move this into its own commit and write a commit message that explains what gets fixed/changed here? |
||
|
|
||
| }, | ||
| (queue_id) => | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this for preloading?