mirror of
https://github.com/oven-sh/bun
synced 2026-02-11 19:38:58 +00:00
### What does this PR do? Add MySQL support, Refactor will be in a followup PR ### How did you verify your code works? A lot of tests --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: cirospaciari <6379399+cirospaciari@users.noreply.github.com>
181 lines
5.4 KiB
Zig
181 lines
5.4 KiB
Zig
pub const Authentication = union(enum) {
|
|
Ok: void,
|
|
ClearTextPassword: struct {},
|
|
MD5Password: struct {
|
|
salt: [4]u8,
|
|
},
|
|
KerberosV5: struct {},
|
|
SCMCredential: struct {},
|
|
GSS: struct {},
|
|
GSSContinue: struct {
|
|
data: Data,
|
|
},
|
|
SSPI: struct {},
|
|
SASL: struct {},
|
|
SASLContinue: struct {
|
|
data: Data,
|
|
r: []const u8,
|
|
s: []const u8,
|
|
i: []const u8,
|
|
|
|
pub fn iterationCount(this: *const @This()) !u32 {
|
|
return try std.fmt.parseInt(u32, this.i, 0);
|
|
}
|
|
},
|
|
SASLFinal: struct {
|
|
data: Data,
|
|
},
|
|
Unknown: void,
|
|
|
|
pub fn deinit(this: *@This()) void {
|
|
switch (this.*) {
|
|
.MD5Password => {},
|
|
.SASL => {},
|
|
.SASLContinue => {
|
|
this.SASLContinue.data.zdeinit();
|
|
},
|
|
.SASLFinal => {
|
|
this.SASLFinal.data.zdeinit();
|
|
},
|
|
else => {},
|
|
}
|
|
}
|
|
|
|
pub fn decodeInternal(this: *@This(), comptime Container: type, reader: NewReader(Container)) !void {
|
|
const message_length = try reader.length();
|
|
|
|
switch (try reader.int4()) {
|
|
0 => {
|
|
if (message_length != 8) return error.InvalidMessageLength;
|
|
this.* = .{ .Ok = {} };
|
|
},
|
|
2 => {
|
|
if (message_length != 8) return error.InvalidMessageLength;
|
|
this.* = .{
|
|
.KerberosV5 = .{},
|
|
};
|
|
},
|
|
3 => {
|
|
if (message_length != 8) return error.InvalidMessageLength;
|
|
this.* = .{
|
|
.ClearTextPassword = .{},
|
|
};
|
|
},
|
|
5 => {
|
|
if (message_length != 12) return error.InvalidMessageLength;
|
|
var salt_data = try reader.bytes(4);
|
|
defer salt_data.deinit();
|
|
this.* = .{
|
|
.MD5Password = .{
|
|
.salt = salt_data.slice()[0..4].*,
|
|
},
|
|
};
|
|
},
|
|
7 => {
|
|
if (message_length != 8) return error.InvalidMessageLength;
|
|
this.* = .{
|
|
.GSS = .{},
|
|
};
|
|
},
|
|
|
|
8 => {
|
|
if (message_length < 9) return error.InvalidMessageLength;
|
|
const bytes = try reader.read(message_length - 8);
|
|
this.* = .{
|
|
.GSSContinue = .{
|
|
.data = bytes,
|
|
},
|
|
};
|
|
},
|
|
9 => {
|
|
if (message_length != 8) return error.InvalidMessageLength;
|
|
this.* = .{
|
|
.SSPI = .{},
|
|
};
|
|
},
|
|
|
|
10 => {
|
|
if (message_length < 9) return error.InvalidMessageLength;
|
|
try reader.skip(message_length - 8);
|
|
this.* = .{
|
|
.SASL = .{},
|
|
};
|
|
},
|
|
|
|
11 => {
|
|
if (message_length < 9) return error.InvalidMessageLength;
|
|
var bytes = try reader.bytes(message_length - 8);
|
|
errdefer {
|
|
bytes.deinit();
|
|
}
|
|
|
|
var iter = bun.strings.split(bytes.slice(), ",");
|
|
var r: ?[]const u8 = null;
|
|
var i: ?[]const u8 = null;
|
|
var s: ?[]const u8 = null;
|
|
|
|
while (iter.next()) |item| {
|
|
if (item.len > 2) {
|
|
const key = item[0];
|
|
const after_equals = item[2..];
|
|
if (key == 'r') {
|
|
r = after_equals;
|
|
} else if (key == 's') {
|
|
s = after_equals;
|
|
} else if (key == 'i') {
|
|
i = after_equals;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (r == null) {
|
|
debug("Missing r", .{});
|
|
}
|
|
|
|
if (s == null) {
|
|
debug("Missing s", .{});
|
|
}
|
|
|
|
if (i == null) {
|
|
debug("Missing i", .{});
|
|
}
|
|
|
|
this.* = .{
|
|
.SASLContinue = .{
|
|
.data = bytes,
|
|
.r = r orelse return error.InvalidMessage,
|
|
.s = s orelse return error.InvalidMessage,
|
|
.i = i orelse return error.InvalidMessage,
|
|
},
|
|
};
|
|
},
|
|
|
|
12 => {
|
|
if (message_length < 9) return error.InvalidMessageLength;
|
|
const remaining: usize = message_length - 8;
|
|
|
|
const bytes = try reader.read(remaining);
|
|
this.* = .{
|
|
.SASLFinal = .{
|
|
.data = bytes,
|
|
},
|
|
};
|
|
},
|
|
|
|
else => {
|
|
this.* = .{ .Unknown = {} };
|
|
},
|
|
}
|
|
}
|
|
|
|
pub const decode = DecoderWrap(Authentication, decodeInternal).decode;
|
|
};
|
|
|
|
const debug = bun.Output.scoped(.Postgres, .hidden);
|
|
|
|
const bun = @import("bun");
|
|
const std = @import("std");
|
|
const Data = @import("../../shared/Data.zig").Data;
|
|
const DecoderWrap = @import("./DecoderWrap.zig").DecoderWrap;
|
|
const NewReader = @import("./NewReader.zig").NewReader;
|