summaryrefslogtreecommitdiff
path: root/lib/chessh/ssh/daemon.ex
diff options
context:
space:
mode:
authorSimponic <loganhunt@simponic.xyz>2022-12-29 17:21:20 -0700
committerSimponic <loganhunt@simponic.xyz>2022-12-29 17:21:20 -0700
commit1a2bdccf124de6207899f59538cc0ed2efc97b5a (patch)
tree5b582023531c8df637881899ab64d5f5eddd7f3f /lib/chessh/ssh/daemon.ex
parent10bc34245e8e1e3ba63fb0720d3bcfb1119db921 (diff)
downloadchessh-1a2bdccf124de6207899f59538cc0ed2efc97b5a.tar.gz
chessh-1a2bdccf124de6207899f59538cc0ed2efc97b5a.zip
Add scalable nodes and user sessions
Diffstat (limited to 'lib/chessh/ssh/daemon.ex')
-rw-r--r--lib/chessh/ssh/daemon.ex45
1 files changed, 31 insertions, 14 deletions
diff --git a/lib/chessh/ssh/daemon.ex b/lib/chessh/ssh/daemon.ex
index acb6bea..cd0d466 100644
--- a/lib/chessh/ssh/daemon.ex
+++ b/lib/chessh/ssh/daemon.ex
@@ -1,4 +1,5 @@
defmodule Chessh.SSH.Daemon do
+ alias Chessh.Auth.PasswordAuthenticator
use GenServer
def start_link(_) do
@@ -12,24 +13,39 @@ defmodule Chessh.SSH.Daemon do
{:ok, state}
end
- def pwd_authenticate(username, password, _address, attempts) do
- if Chessh.Auth.PasswordAuthenticator.authenticate(username, password) do
- true
- else
- newAttempts =
- case attempts do
- :undefined -> 0
- _ -> attempts
- end
-
- if Application.fetch_env!(:chessh, :max_password_attempts) <= newAttempts do
+ def pwd_authenticate(username, password) do
+ # TODO - check concurrent sessions
+ PasswordAuthenticator.authenticate(
+ String.Chars.to_string(username),
+ String.Chars.to_string(password)
+ )
+ end
+
+ def pwd_authenticate(username, password, inet) do
+ [jail_timeout_ms, jail_threshold] =
+ Application.get_env(:chessh, RateLimits)
+ |> Keyword.take([:jail_timeout_ms, :jail_threshold])
+ |> Keyword.values()
+
+ {ip, _port} = inet
+ rateId = "failed_password_attempts:#{Enum.join(Tuple.to_list(ip), ".")}"
+
+ case Hammer.check_rate(rateId, jail_timeout_ms, jail_threshold) do
+ {:allow, _count} ->
+ pwd_authenticate(username, password) ||
+ (fn ->
+ Hammer.check_rate_inc(rateId, jail_timeout_ms, jail_threshold, 1)
+ false
+ end).()
+
+ {:deny, _limit} ->
:disconnect
- else
- {false, newAttempts + 1}
- end
end
end
+ def pwd_authenticate(username, password, inet, _address),
+ do: pwd_authenticate(username, password, inet)
+
def handle_cast(:start, state) do
port = Application.fetch_env!(:chessh, :port)
key_dir = String.to_charlist(Application.fetch_env!(:chessh, :key_dir))
@@ -40,6 +56,7 @@ defmodule Chessh.SSH.Daemon do
system_dir: key_dir,
pwdfun: &pwd_authenticate/4,
key_cb: Chessh.SSH.ServerKey,
+ # disconnectfun:
id_string: :random,
subsystems: [],
parallel_login: true,