╭ changed ───────╮ │src/test/ssh.zig│ ╰────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 85 packet.items[8] = 2; │ │ 86 try std.testing.expectError(error.UnsupportedExtendedData, proto.parseChannelData(packet.items, true, 0));│ │ 87 } │ │ 88 + │ │ 89 +test "initial strict kex rejects ignored packets" { │ │ 90 + const io = std.testing.io; │ │ 91 + const allocator = std.testing.allocator; │ │ 92 + │ │ 93 + var encoded_buf: [128]u8 = undefined; │ │ 94 + var writer = std.Io.Writer.fixed(&encoded_buf); │ │ 95 + try proto.writePlainPacket(io, &writer, &.{proto.SSH_MSG_IGNORE}); │ │ 96 │ │ 97 + var reader = std.Io.Reader.fixed(writer.buffered()); │ │ 98 + var client_seq: u64 = 0; │ │ 99 + const transport = proto.KexTransport{ .plain = &client_seq }; │ │100 + try std.testing.expectError(error.StrictKexViolation, transport.readPacket(allocator, &reader, true)); │ │101 + try std.testing.expectEqual(@as(u64, 1), client_seq); │ │102 +} │ │103 + │ │104 +test "ignored packets do not count as connection activity" { │ │105 + const io = std.testing.io; │ │106 + const allocator = std.testing.allocator; │ │107 + const key_material = [_]u8{0x5A} ** 64; │ │108 + │ │109 + var sender = proto.Cipher.init(&key_material, 0); │ │110 + var encoded_buf: [128]u8 = undefined; │ │111 + var encoded_writer = std.Io.Writer.fixed(&encoded_buf); │ │112 + try sender.writePacket(io, &encoded_writer, &.{proto.SSH_MSG_IGNORE}); │ │113 + │ │114 + var idle = proto.IdleState{}; │ │115 + var receiver = proto.Cipher.init(&key_material, 0); │ │116 + receiver.idle = &idle; │ │117 + var reader = std.Io.Reader.fixed(encoded_writer.buffered()); │ │118 + var output_buf: [1]u8 = undefined; │ │119 + var output_writer = std.Io.Writer.fixed(&output_buf); │ │120 + var conn = proto.Conn{ │ │121 + .io = io, │ │122 + .allocator = allocator, │ │123 + .reader = &reader, │ │124 + .writer = &output_writer, │ │125 + .cs_cipher = receiver, │ │126 + .sc_cipher = sender, │ │127 + .rekey = undefined, │ │128 + }; │ │129 + │ │130 + try std.testing.expectError(error.EndOfStream, proto.readSessionPacket(&conn)); │ │131 + try std.testing.expectEqual(@as(u64, 0), idle.activity.load(.monotonic)); │ │132 +} │ │133 + │ │134 test "SSH-2 negotiation: walk through every step (banner -> KEX -> auth -> channel -> exec)" { │ │135 const io = std.testing.io; │ │136 const allocator = std.testing.allocator; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯