diff options
author | 2023-10-30 16:56:31 -0300 | |
---|---|---|
committer | 2023-10-30 12:56:31 -0700 | |
commit | 4d780837ac241ed595287a19f2d5b403680eab0b (patch) | |
tree | 78f728fa6b6f51a55561961e237be51628c8b21f /src/http/websocket_http_client.zig | |
parent | cbc5ca770bd427ffff29c748f9da60b83b621a00 (diff) | |
download | bun-4d780837ac241ed595287a19f2d5b403680eab0b.tar.gz bun-4d780837ac241ed595287a19f2d5b403680eab0b.tar.zst bun-4d780837ac241ed595287a19f2d5b403680eab0b.zip |
fix(fetch) (#6672)
* fix fetch
* oops
* revert
* fix checkServerIdentity
* check dns len
* use same checks on wsclient and fetch, fix tests
* more tests and more fixes
* fix node-http flask test
* orelse
* fix requestCert
* more fixes, but no data receiving
* fix pause on connect behavior on TLS
* WS Client + rejectUnauthorized progress
* move test to the right place
* more test
* oops
* oops 2
* fmt
* cleanup
* WIP: handle handshake properly on uWS
* handle rejectUnauthorized in uWS
* fmt
* duplicated test
* fix leak
* add rejectUnauthorized option in WS types
* fix merge
* fix merge2
Diffstat (limited to 'src/http/websocket_http_client.zig')
-rw-r--r-- | src/http/websocket_http_client.zig | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/src/http/websocket_http_client.zig b/src/http/websocket_http_client.zig index 1f821812e..c3b98f5a8 100644 --- a/src/http/websocket_http_client.zig +++ b/src/http/websocket_http_client.zig @@ -13,7 +13,7 @@ const MutableString = bun.MutableString; const stringZ = bun.stringZ; const default_allocator = bun.default_allocator; const C = bun.C; - +const BoringSSL = bun.BoringSSL; const uws = @import("root").bun.uws; const JSC = @import("root").bun.JSC; const PicoHTTP = @import("root").bun.picohttp; @@ -143,6 +143,15 @@ const ErrorCode = enum(i32) { invalid_utf8, }; +pub export fn Bun__defaultRejectUnauthorized(global: *JSC.JSGlobalObject) callconv(.C) bool { + var vm = global.bunVM(); + return vm.bundler.env.getTLSRejectUnauthorized(); +} + +comptime { + _ = Bun__defaultRejectUnauthorized; +} + const CppWebSocket = opaque { extern fn WebSocket__didConnect( websocket_context: *CppWebSocket, @@ -154,7 +163,7 @@ const CppWebSocket = opaque { extern fn WebSocket__didClose(websocket_context: *CppWebSocket, code: u16, reason: *const bun.String) void; extern fn WebSocket__didReceiveText(websocket_context: *CppWebSocket, clone: bool, text: *const JSC.ZigString) void; extern fn WebSocket__didReceiveBytes(websocket_context: *CppWebSocket, bytes: [*]const u8, byte_len: usize, opcode: u8) void; - + extern fn WebSocket__rejectUnauthorized(websocket_context: *CppWebSocket) bool; pub const didConnect = WebSocket__didConnect; pub const didAbruptClose = WebSocket__didAbruptClose; pub const didClose = WebSocket__didClose; @@ -167,6 +176,11 @@ const CppWebSocket = opaque { WebSocket__incrementPendingActivity(this); } + pub fn rejectUnauthorized(this: *CppWebSocket) bool { + JSC.markBinding(@src()); + return WebSocket__rejectUnauthorized(this); + } + pub fn unref(this: *CppWebSocket) void { JSC.markBinding(@src()); WebSocket__decrementPendingActivity(this); @@ -192,8 +206,7 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type { body: std.ArrayListUnmanaged(u8) = .{}, websocket_protocol: u64 = 0, hostname: [:0]const u8 = "", - poll_ref: Async.KeepAlive = .{}, - + poll_ref: Async.KeepAlive = Async.KeepAlive.init(), pub const name = if (ssl) "WebSocketHTTPSClient" else "WebSocketHTTPClient"; pub const shim = JSC.Shimmer("Bun", name, @This()); @@ -257,6 +270,8 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type { &client_protocol_hash, NonUTF8Headers.init(header_names, header_values, header_count), ) catch return null; + var vm = global.bunVM(); + var client: HTTPClient = HTTPClient{ .tcp = undefined, .outgoing_websocket = websocket, @@ -265,7 +280,6 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type { }; var host_ = host.toSlice(bun.default_allocator); defer host_.deinit(); - var vm = global.bunVM(); const prev_start_server_on_next_tick = vm.eventLoop().start_server_on_next_tick; vm.eventLoop().start_server_on_next_tick = true; client.poll_ref.ref(vm); @@ -347,11 +361,28 @@ pub fn NewHTTPUpgradeClient(comptime ssl: bool) type { } pub fn handleHandshake(this: *HTTPClient, socket: Socket, success: i32, ssl_error: uws.us_bun_verify_error_t) void { - _ = socket; - _ = ssl_error; log("onHandshake({d})", .{success}); - if (success == 0) { + + const authorized = if (success == 1) true else false; + var reject_unauthorized = false; + if (this.outgoing_websocket) |ws| { + reject_unauthorized = ws.rejectUnauthorized(); + } + if (ssl_error.error_no != 0 and (reject_unauthorized or !authorized)) { this.fail(ErrorCode.failed_to_connect); + return; + } + + if (authorized) { + if (reject_unauthorized) { + const ssl_ptr = @as(*BoringSSL.SSL, @ptrCast(socket.getNativeHandle())); + if (BoringSSL.SSL_get_servername(ssl_ptr, 0)) |servername| { + const hostname = servername[0..bun.len(servername)]; + if (!BoringSSL.checkServerIdentity(ssl_ptr, hostname)) { + this.fail(ErrorCode.failed_to_connect); + } + } + } } } @@ -949,15 +980,29 @@ pub fn NewWebSocketClient(comptime ssl: bool) type { pub fn handleHandshake(this: *WebSocket, socket: Socket, success: i32, ssl_error: uws.us_bun_verify_error_t) void { JSC.markBinding(@src()); - _ = socket; - _ = ssl_error; - JSC.markBinding(@src()); + const authorized = if (success == 1) true else false; + log("onHandshake({d})", .{success}); - JSC.markBinding(@src()); - if (success == 0) { - if (this.outgoing_websocket) |ws| { + + if (this.outgoing_websocket) |ws| { + var reject_unauthorized = ws.rejectUnauthorized(); + if (ssl_error.error_no != 0 and (reject_unauthorized or !authorized)) { this.outgoing_websocket = null; ws.didAbruptClose(ErrorCode.failed_to_connect); + return; + } + + if (authorized) { + if (reject_unauthorized) { + const ssl_ptr = @as(*BoringSSL.SSL, @ptrCast(socket.getNativeHandle())); + if (BoringSSL.SSL_get_servername(ssl_ptr, 0)) |servername| { + const hostname = servername[0..bun.len(servername)]; + if (!BoringSSL.checkServerIdentity(ssl_ptr, hostname)) { + this.outgoing_websocket = null; + ws.didAbruptClose(ErrorCode.failed_to_connect); + } + } + } } } } |