Skip to content

Commit

Permalink
listener: send TOO_MANY_CONNECTIONS if max_connections_per_ip is exce…
Browse files Browse the repository at this point in the history
…eded
  • Loading branch information
MaxKellermann committed Jul 23, 2024
1 parent 1323f26 commit 7fbcdfb
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 2 deletions.
3 changes: 2 additions & 1 deletion debian/changelog
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
cm4all-lukko (0.26) unstable; urgency=low

*
* listener: send TOO_MANY_CONNECTIONS if max_connections_per_ip is
exceeded

--

Expand Down
7 changes: 6 additions & 1 deletion src/Listener.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "Config.hxx"
#include "DelayedConnection.hxx"
#include "Connection.hxx"
#include "ssh/EarlyDisconnect.hxx"
#include "ssh/Protocol.hxx"
#include "lib/fmt/SocketAddressFormatter.hxx"
#include "net/ClientAccounting.hxx"
#include "net/SocketAddress.hxx"
Expand All @@ -21,6 +23,8 @@

#include <sys/socket.h>

using std::string_view_literals::operator""sv;

Listener::Listener(Instance &_instance, const ListenerConfig &config)
:ServerSocket(_instance.GetEventLoop(), config.Create(SOCK_STREAM)),
instance(_instance),
Expand Down Expand Up @@ -61,9 +65,10 @@ Listener::OnAccept(UniqueSocketDescriptor connection_fd,
if (!per_client->Check()) {
/* too many connections from this IP address -
reject the new connection */
// TODO send SSH::DisconnectReasonCode::TOO_MANY_CONNECTIONS
++instance.counters.n_rejected_connections;
logger.Fmt(1, "Too many connections from {}", peer_address);
SendEarlyDisconnect(connection_fd, SSH::DisconnectReasonCode::TOO_MANY_CONNECTIONS,
"Too many connections"sv);
return;
}

Expand Down
27 changes: 27 additions & 0 deletions src/ssh/EarlyDisconnect.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <[email protected]>

#include "EarlyDisconnect.hxx"
#include "IdentificationString.hxx"
#include "MakePacket.hxx"
#include "net/SocketDescriptor.hxx"
#include "io/Iovec.hxx"
#include "util/SpanCast.hxx"

namespace SSH {

void
SendEarlyDisconnect(SocketDescriptor socket,
DisconnectReasonCode reason_code, std::string_view msg) noexcept
{
auto disconnect_packet = MakeDisconnect(reason_code, msg);
const struct iovec v[] = {
MakeIovec(AsBytes(IDENTIFICATION_STRING)),
MakeIovec(disconnect_packet.Finish(8, false)),
};

(void)socket.Send(v);
}

} // namespace SSH
24 changes: 24 additions & 0 deletions src/ssh/EarlyDisconnect.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <[email protected]>

#pragma once

#include <cstdint>
#include <string_view>

class SocketDescriptor;

namespace SSH {

enum class DisconnectReasonCode : uint32_t;

/**
* Send the SSH protocol version exchange followed by a DISCONNECT
* packet. Use this to reject a new connection.
*/
void
SendEarlyDisconnect(SocketDescriptor socket,
DisconnectReasonCode reason_code, std::string_view msg) noexcept;

} // namespace SSH
1 change: 1 addition & 0 deletions src/ssh/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ libssh = static_library(
'KexState.cxx',
'Serializer.cxx',
'TerminalMode.cxx',
'EarlyDisconnect.cxx',
include_directories: inc,
dependencies: [
cipher_dep,
Expand Down

0 comments on commit 7fbcdfb

Please sign in to comment.