╭ changed ─────────────────╮ │src/serve_ssh_protocol.zig│ ╰──────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │123 keypair: Ed25519.KeyPair, │ │124 │ │125 pub fn loadOrGenerate(io: std.Io, allocator: std.mem.Allocator, data_dir_path: []const u8) !HostKey {│ │126 - const path = try std.fs.path.join(allocator, &.{ data_dir_path, host_key_file_name }); │ │126 + const path = try std.Io.Dir.path.join(allocator, &.{ data_dir_path, host_key_file_name }); │ │127 defer allocator.free(path); │ │128 │ │129 const cwd = std.Io.Dir.cwd(); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │141 defer allocator.free(text); │ │142 defer std.crypto.secureZero(u8, text); │ │143 // owner-only from the start — never a window where the key is readable │ │144 - const permissions: std.Io.File.Permissions = if (builtin.os.tag == .windows) .default_file else @enumFromInt(0o600); │ │144 + const permissions: std.Io.File.Permissions = if (builtin.target.os.tag == .windows) .default_file else @fromBackingInt(@intCast(0o600));│ │145 // linked into place only once complete, and never over an existing key │ │146 var atomic_file = try cwd.createFileAtomic(io, path, .{ .permissions = permissions }); │ │147 defer atomic_file.deinit(io); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │776 defer std.crypto.secureZero(u8, std.mem.asBytes(&conn.cs_cipher)); │ │777 defer std.crypto.secureZero(u8, std.mem.asBytes(&conn.sc_cipher)); │ │778 │ │779 - errdefer |err| disconnectOnError(&conn, err); │ │779 + authAndRunChannels(&conn, handler) catch |err| { │ │780 + disconnectOnError(&conn, err); │ │781 + return err; │ │782 + }; │ │783 +} │ │784 │ │781 - const fingerprint = try runAuth(&conn); │ │782 - try runChannelLayer(&conn, &fingerprint, handler); │ │785 +fn authAndRunChannels(conn: *Conn, handler: anytype) !void { │ │786 + const fingerprint = try runAuth(conn); │ │787 + try runChannelLayer(conn, &fingerprint, handler); │ │788 } │ │789 │ │790 /// tell the peer why we're hanging up (RFC 4253 §11.1), best effort. protocol│ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1877 const pk = rsa.PublicKey.fromBytes(e, n) catch return false; │ │1878 switch (n.len) { │ │1879 inline 256, 384, 512 => |len| { │ │1875 - rsa.PKCS1v1_5Signature.verify(len, sig[0..len].*, signed, pk, Hash) catch return false;│ │1880 + rsa.PKCS1v1_5Signature.verify(len, sig[0..len], signed, pk, Hash) catch return false; │ │1881 return true; │ │1882 }, │ │1883 else => return false, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────╮ │2244 test "channel close before shell or exec is acknowledged" {│ │2245 const io = std.testing.io; │ │2246 const allocator = std.testing.allocator; │ │2242 - const key = [_]u8{0x5a} ** 64; │ │2247 + const key: [64]u8 = @splat(0x5a); │ │2248 var encoded: [256]u8 = undefined; │ │2249 var encoded_writer = std.Io.Writer.fixed(&encoded); │ │2250 var sender = Cipher.init(&key, 0); │ ╰─────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │2277 } │ │2278 }; │ │2279 var handler = Handler{}; │ │2275 - try runChannelLayer(&conn, &([_]u8{0} ** fingerprint_len), &handler); │ │2280 + try runChannelLayer(&conn, &@as([fingerprint_len]u8, @splat(0)), &handler);│ │2281 var output_reader = std.Io.Reader.fixed(writer.buffered()); │ │2282 var receiver = Cipher.init(&key, 0); │ │2283 const confirmation = try receiver.readPacket(allocator, &output_reader); │ ╰─────────────────────────────────────────────────────────────────────────────────────╯