mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Add an insecure_disable_tls_host_verification command line option
When set, this disables the host verification of all HTTP requests. Available for both the fetch and serve mode. Also introduced an App.Config, for future command line options which need to be passed more deeply into the code.
This commit is contained in:
17
src/app.zig
17
src/app.zig
@@ -17,11 +17,18 @@ pub const App = struct {
|
|||||||
app_dir_path: ?[]const u8,
|
app_dir_path: ?[]const u8,
|
||||||
|
|
||||||
pub const RunMode = enum {
|
pub const RunMode = enum {
|
||||||
serve,
|
help,
|
||||||
fetch,
|
fetch,
|
||||||
|
serve,
|
||||||
|
version,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, run_mode: RunMode) !*App {
|
pub const Config = struct {
|
||||||
|
tls_verify_host: bool = true,
|
||||||
|
run_mode: RunMode,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(allocator: Allocator, config: Config) !*App {
|
||||||
const app = try allocator.create(App);
|
const app = try allocator.create(App);
|
||||||
errdefer allocator.destroy(app);
|
errdefer allocator.destroy(app);
|
||||||
|
|
||||||
@@ -38,9 +45,11 @@ pub const App = struct {
|
|||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.telemetry = undefined,
|
.telemetry = undefined,
|
||||||
.app_dir_path = app_dir_path,
|
.app_dir_path = app_dir_path,
|
||||||
.http_client = try HttpClient.init(allocator, 5),
|
.http_client = try HttpClient.init(allocator, 5, .{
|
||||||
|
.tls_verify_host = config.tls_verify_host,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
app.telemetry = Telemetry.init(app, run_mode);
|
app.telemetry = Telemetry.init(app, config.run_mode);
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ const TestContext = struct {
|
|||||||
|
|
||||||
pub fn context() TestContext {
|
pub fn context() TestContext {
|
||||||
return .{
|
return .{
|
||||||
.app = App.init(std.testing.allocator, .serve) catch unreachable,
|
.app = App.init(std.testing.allocator, .{ .run_mode = .serve }) catch unreachable,
|
||||||
.arena = std.heap.ArenaAllocator.init(std.testing.allocator),
|
.arena = std.heap.ArenaAllocator.init(std.testing.allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,13 @@ pub const Client = struct {
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
state_pool: StatePool,
|
state_pool: StatePool,
|
||||||
root_ca: tls.config.CertBundle,
|
root_ca: tls.config.CertBundle,
|
||||||
|
tls_verify_host: bool = true,
|
||||||
|
|
||||||
// we only allow passing in a root_ca for testing
|
const Opts = struct {
|
||||||
pub fn init(allocator: Allocator, max_concurrent: usize) !Client {
|
tls_verify_host: bool = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(allocator: Allocator, max_concurrent: usize, opts: Opts) !Client {
|
||||||
var root_ca = try tls.config.CertBundle.fromSystem(allocator);
|
var root_ca = try tls.config.CertBundle.fromSystem(allocator);
|
||||||
errdefer root_ca.deinit(allocator);
|
errdefer root_ca.deinit(allocator);
|
||||||
|
|
||||||
@@ -58,6 +62,7 @@ pub const Client = struct {
|
|||||||
.root_ca = root_ca,
|
.root_ca = root_ca,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.state_pool = state_pool,
|
.state_pool = state_pool,
|
||||||
|
.tls_verify_host = opts.tls_verify_host,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +128,7 @@ pub const Request = struct {
|
|||||||
_has_host_header: bool,
|
_has_host_header: bool,
|
||||||
|
|
||||||
// Whether or not we should verify that the host matches the certificate CN
|
// Whether or not we should verify that the host matches the certificate CN
|
||||||
_tls_verify_host: bool = true,
|
_tls_verify_host: bool,
|
||||||
|
|
||||||
pub const Method = enum {
|
pub const Method = enum {
|
||||||
GET,
|
GET,
|
||||||
@@ -167,6 +172,7 @@ pub const Request = struct {
|
|||||||
._client = client,
|
._client = client,
|
||||||
._redirect_count = 0,
|
._redirect_count = 0,
|
||||||
._has_host_header = false,
|
._has_host_header = false,
|
||||||
|
._tls_verify_host = client.tls_verify_host,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,11 +211,13 @@ pub const Request = struct {
|
|||||||
|
|
||||||
// TODO timeout
|
// TODO timeout
|
||||||
const SendSyncOpts = struct {
|
const SendSyncOpts = struct {
|
||||||
tls_verify_host: bool = true,
|
tls_verify_host: ?bool = null,
|
||||||
};
|
};
|
||||||
// Makes an synchronous request
|
// Makes an synchronous request
|
||||||
pub fn sendSync(self: *Request, opts: SendSyncOpts) anyerror!Response {
|
pub fn sendSync(self: *Request, opts: SendSyncOpts) anyerror!Response {
|
||||||
self._tls_verify_host = opts.tls_verify_host;
|
if (opts.tls_verify_host) |override| {
|
||||||
|
self._tls_verify_host = override;
|
||||||
|
}
|
||||||
try self.prepareInitialSend();
|
try self.prepareInitialSend();
|
||||||
return self.doSendSync();
|
return self.doSendSync();
|
||||||
}
|
}
|
||||||
@@ -230,11 +238,13 @@ pub const Request = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SendAsyncOpts = struct {
|
const SendAsyncOpts = struct {
|
||||||
tls_verify_host: bool = true,
|
tls_verify_host: ?bool = null,
|
||||||
};
|
};
|
||||||
// Makes an asynchronous request
|
// Makes an asynchronous request
|
||||||
pub fn sendAsync(self: *Request, loop: anytype, handler: anytype, opts: SendAsyncOpts) !void {
|
pub fn sendAsync(self: *Request, loop: anytype, handler: anytype, opts: SendAsyncOpts) !void {
|
||||||
self._tls_verify_host = opts.tls_verify_host;
|
if (opts.tls_verify_host) |override| {
|
||||||
|
self._tls_verify_host = override;
|
||||||
|
}
|
||||||
try self.prepareInitialSend();
|
try self.prepareInitialSend();
|
||||||
return self.doSendAsync(loop, handler);
|
return self.doSendAsync(loop, handler);
|
||||||
}
|
}
|
||||||
@@ -2176,5 +2186,5 @@ fn testReader(state: *State, res: *TestResponse, data: []const u8) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn testClient() !Client {
|
fn testClient() !Client {
|
||||||
return try Client.init(testing.allocator, 1);
|
return try Client.init(testing.allocator, 1, .{});
|
||||||
}
|
}
|
||||||
|
|||||||
60
src/main.zig
60
src/main.zig
@@ -22,6 +22,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
|
|
||||||
const jsruntime = @import("jsruntime");
|
const jsruntime = @import("jsruntime");
|
||||||
|
|
||||||
|
const App = @import("app.zig").App;
|
||||||
const Browser = @import("browser/browser.zig").Browser;
|
const Browser = @import("browser/browser.zig").Browser;
|
||||||
const server = @import("server.zig");
|
const server = @import("server.zig");
|
||||||
|
|
||||||
@@ -69,9 +70,12 @@ pub fn main() !void {
|
|||||||
log.err("address (host:port) {any}\n", .{err});
|
log.err("address (host:port) {any}\n", .{err});
|
||||||
return args.printUsageAndExit(false);
|
return args.printUsageAndExit(false);
|
||||||
};
|
};
|
||||||
|
var app = try App.init(alloc, .{
|
||||||
var app = try @import("app.zig").App.init(alloc, .serve);
|
.run_mode = args.mode,
|
||||||
|
.tls_verify_host = opts.tls_verify_host,
|
||||||
|
});
|
||||||
defer app.deinit();
|
defer app.deinit();
|
||||||
|
|
||||||
app.telemetry.record(.{ .run = {} });
|
app.telemetry.record(.{ .run = {} });
|
||||||
|
|
||||||
const timeout = std.time.ns_per_s * @as(u64, opts.timeout);
|
const timeout = std.time.ns_per_s * @as(u64, opts.timeout);
|
||||||
@@ -83,7 +87,10 @@ pub fn main() !void {
|
|||||||
.fetch => |opts| {
|
.fetch => |opts| {
|
||||||
log.debug("Fetch mode: url {s}, dump {any}", .{ opts.url, opts.dump });
|
log.debug("Fetch mode: url {s}, dump {any}", .{ opts.url, opts.dump });
|
||||||
|
|
||||||
var app = try @import("app.zig").App.init(alloc, .fetch);
|
var app = try App.init(alloc, .{
|
||||||
|
.run_mode = args.mode,
|
||||||
|
.tls_verify_host = opts.tls_verify_host,
|
||||||
|
});
|
||||||
defer app.deinit();
|
defer app.deinit();
|
||||||
app.telemetry.record(.{ .run = {} });
|
app.telemetry.record(.{ .run = {} });
|
||||||
|
|
||||||
@@ -125,14 +132,7 @@ const Command = struct {
|
|||||||
mode: Mode,
|
mode: Mode,
|
||||||
exec_name: []const u8,
|
exec_name: []const u8,
|
||||||
|
|
||||||
const ModeType = enum {
|
const Mode = union(App.RunMode) {
|
||||||
help,
|
|
||||||
fetch,
|
|
||||||
serve,
|
|
||||||
version,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Mode = union(ModeType) {
|
|
||||||
help: bool, // false when being printed because of an error
|
help: bool, // false when being printed because of an error
|
||||||
fetch: Fetch,
|
fetch: Fetch,
|
||||||
serve: Serve,
|
serve: Serve,
|
||||||
@@ -143,11 +143,13 @@ const Command = struct {
|
|||||||
host: []const u8,
|
host: []const u8,
|
||||||
port: u16,
|
port: u16,
|
||||||
timeout: u16,
|
timeout: u16,
|
||||||
|
tls_verify_host: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Fetch = struct {
|
const Fetch = struct {
|
||||||
url: []const u8,
|
url: []const u8,
|
||||||
dump: bool = false,
|
dump: bool = false,
|
||||||
|
tls_verify_host: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn printUsageAndExit(self: *const Command, success: bool) void {
|
fn printUsageAndExit(self: *const Command, success: bool) void {
|
||||||
@@ -164,6 +166,12 @@ const Command = struct {
|
|||||||
\\--dump Dumps document to stdout.
|
\\--dump Dumps document to stdout.
|
||||||
\\ Defaults to false.
|
\\ Defaults to false.
|
||||||
\\
|
\\
|
||||||
|
\\--insecure_disable_tls_host_verification
|
||||||
|
\\ Disables host verification on all HTTP requests.
|
||||||
|
\\ This is an advanced option which should only be
|
||||||
|
\\ set if you understand and accept the risk of
|
||||||
|
\\ disabling host verification.
|
||||||
|
\\
|
||||||
\\serve command
|
\\serve command
|
||||||
\\Starts a websocket CDP server
|
\\Starts a websocket CDP server
|
||||||
\\Example: {s} serve --host 127.0.0.1 --port 9222
|
\\Example: {s} serve --host 127.0.0.1 --port 9222
|
||||||
@@ -178,11 +186,18 @@ const Command = struct {
|
|||||||
\\--timeout Inactivity timeout in seconds before disconnecting clients
|
\\--timeout Inactivity timeout in seconds before disconnecting clients
|
||||||
\\ Defaults to 3 (seconds)
|
\\ Defaults to 3 (seconds)
|
||||||
\\
|
\\
|
||||||
|
\\--insecure_disable_tls_host_verification
|
||||||
|
\\ Disables host verification on all HTTP requests.
|
||||||
|
\\ This is an advanced option which should only be
|
||||||
|
\\ set if you understand and accept the risk of
|
||||||
|
\\ disabling host verification.
|
||||||
|
\\
|
||||||
\\version command
|
\\version command
|
||||||
\\Displays the version of {s}
|
\\Displays the version of {s}
|
||||||
\\
|
\\
|
||||||
\\help command
|
\\help command
|
||||||
\\Displays this message
|
\\Displays this message
|
||||||
|
\\
|
||||||
;
|
;
|
||||||
std.debug.print(usage, .{ self.exec_name, self.exec_name, self.exec_name, self.exec_name });
|
std.debug.print(usage, .{ self.exec_name, self.exec_name, self.exec_name, self.exec_name });
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -204,7 +219,7 @@ fn parseArgs(allocator: Allocator) !Command {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mode_string = args.next() orelse "";
|
const mode_string = args.next() orelse "";
|
||||||
const mode = std.meta.stringToEnum(Command.ModeType, mode_string) orelse blk: {
|
const mode = std.meta.stringToEnum(App.RunMode, mode_string) orelse blk: {
|
||||||
const inferred_mode = inferMode(mode_string) orelse return cmd;
|
const inferred_mode = inferMode(mode_string) orelse return cmd;
|
||||||
// "command" wasn't a command but an option. We can't reset args, but
|
// "command" wasn't a command but an option. We can't reset args, but
|
||||||
// we can create a new one. Not great, but this fallback is temporary
|
// we can create a new one. Not great, but this fallback is temporary
|
||||||
@@ -227,7 +242,7 @@ fn parseArgs(allocator: Allocator) !Command {
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inferMode(opt: []const u8) ?Command.ModeType {
|
fn inferMode(opt: []const u8) ?App.RunMode {
|
||||||
if (opt.len == 0) {
|
if (opt.len == 0) {
|
||||||
return .serve;
|
return .serve;
|
||||||
}
|
}
|
||||||
@@ -260,6 +275,7 @@ fn parseServeArgs(
|
|||||||
var host: []const u8 = "127.0.0.1";
|
var host: []const u8 = "127.0.0.1";
|
||||||
var port: u16 = 9222;
|
var port: u16 = 9222;
|
||||||
var timeout: u16 = 3;
|
var timeout: u16 = 3;
|
||||||
|
var tls_verify_host = true;
|
||||||
|
|
||||||
while (args.next()) |opt| {
|
while (args.next()) |opt| {
|
||||||
if (std.mem.eql(u8, "--host", opt)) {
|
if (std.mem.eql(u8, "--host", opt)) {
|
||||||
@@ -297,6 +313,11 @@ fn parseServeArgs(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, "--insecure_tls_verify_host", opt)) {
|
||||||
|
tls_verify_host = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
log.err("Unknown option to serve command: '{s}'", .{opt});
|
log.err("Unknown option to serve command: '{s}'", .{opt});
|
||||||
return error.UnkownOption;
|
return error.UnkownOption;
|
||||||
}
|
}
|
||||||
@@ -305,6 +326,7 @@ fn parseServeArgs(
|
|||||||
.host = host,
|
.host = host,
|
||||||
.port = port,
|
.port = port,
|
||||||
.timeout = timeout,
|
.timeout = timeout,
|
||||||
|
.tls_verify_host = tls_verify_host,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,6 +336,7 @@ fn parseFetchArgs(
|
|||||||
) !Command.Fetch {
|
) !Command.Fetch {
|
||||||
var dump: bool = false;
|
var dump: bool = false;
|
||||||
var url: ?[]const u8 = null;
|
var url: ?[]const u8 = null;
|
||||||
|
var tls_verify_host = true;
|
||||||
|
|
||||||
while (args.next()) |opt| {
|
while (args.next()) |opt| {
|
||||||
if (std.mem.eql(u8, "--dump", opt)) {
|
if (std.mem.eql(u8, "--dump", opt)) {
|
||||||
@@ -321,6 +344,11 @@ fn parseFetchArgs(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, "--insecure_disable_tls_host_verification", opt)) {
|
||||||
|
tls_verify_host = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (std.mem.startsWith(u8, opt, "--")) {
|
if (std.mem.startsWith(u8, opt, "--")) {
|
||||||
log.err("Unknown option to serve command: '{s}'", .{opt});
|
log.err("Unknown option to serve command: '{s}'", .{opt});
|
||||||
return error.UnkownOption;
|
return error.UnkownOption;
|
||||||
@@ -338,7 +366,11 @@ fn parseFetchArgs(
|
|||||||
return error.MissingURL;
|
return error.MissingURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{ .url = url.?, .dump = dump };
|
return .{
|
||||||
|
.url = url.?,
|
||||||
|
.dump = dump,
|
||||||
|
.tls_verify_host = tls_verify_host,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var verbose: bool = builtin.mode == .Debug; // In debug mode, force verbose.
|
var verbose: bool = builtin.mode == .Debug; // In debug mode, force verbose.
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ fn testExecFn(
|
|||||||
std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
|
std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
|
|
||||||
var http_client = try @import("http/client.zig").Client.init(alloc, 5);
|
var http_client = try @import("http/client.zig").Client.init(alloc, 5, .{});
|
||||||
defer http_client.deinit();
|
defer http_client.deinit();
|
||||||
|
|
||||||
try js_env.setUserContext(.{
|
try js_env.setUserContext(.{
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ fn serveHTTPS(address: std.net.Address) !void {
|
|||||||
|
|
||||||
fn serveCDP(address: std.net.Address) !void {
|
fn serveCDP(address: std.net.Address) !void {
|
||||||
const App = @import("app.zig").App;
|
const App = @import("app.zig").App;
|
||||||
var app = try App.init(gpa.allocator(), .serve);
|
var app = try App.init(gpa.allocator(), .{.run_mode = .serve});
|
||||||
defer app.deinit();
|
defer app.deinit();
|
||||||
|
|
||||||
const server = @import("server.zig");
|
const server = @import("server.zig");
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ pub fn print(comptime fmt: []const u8, args: anytype) void {
|
|||||||
|
|
||||||
// dummy opts incase we want to add something, and not have to break all the callers
|
// dummy opts incase we want to add something, and not have to break all the callers
|
||||||
pub fn app(_: anytype) *App {
|
pub fn app(_: anytype) *App {
|
||||||
return App.init(allocator, .serve) catch unreachable;
|
return App.init(allocator, .{.run_mode = .serve}) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const Random = struct {
|
pub const Random = struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user