summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSimponic <loganhunt@simponic.xyz>2022-12-27 23:50:22 -0700
committerSimponic <loganhunt@simponic.xyz>2022-12-27 23:50:22 -0700
commit10bc34245e8e1e3ba63fb0720d3bcfb1119db921 (patch)
tree0158f37dcda36f36327e45c4ce7543e77c26c8a0 /lib
parentf7c2ccbe26dc808e4a7eae9a378e6c382220961a (diff)
downloadchessh-10bc34245e8e1e3ba63fb0720d3bcfb1119db921.tar.gz
chessh-10bc34245e8e1e3ba63fb0720d3bcfb1119db921.zip
Initial erlang stuff
Diffstat (limited to 'lib')
-rw-r--r--lib/chessh/application.ex2
-rw-r--r--lib/chessh/auth/password.ex3
-rw-r--r--lib/chessh/schema/key.ex3
-rw-r--r--lib/chessh/ssh/daemon.ex60
-rw-r--r--lib/chessh/ssh/server.ex0
-rw-r--r--lib/chessh/ssh/server_key.ex11
6 files changed, 74 insertions, 5 deletions
diff --git a/lib/chessh/application.ex b/lib/chessh/application.ex
index c760532..847dd98 100644
--- a/lib/chessh/application.ex
+++ b/lib/chessh/application.ex
@@ -2,7 +2,7 @@ defmodule Chessh.Application do
use Application
def start(_, _) do
- children = [Chessh.Repo]
+ children = [Chessh.Repo, Chessh.SSH.Daemon]
opts = [strategy: :one_for_one, name: Chessh.Supervisor]
Supervisor.start_link(children, opts)
end
diff --git a/lib/chessh/auth/password.ex b/lib/chessh/auth/password.ex
index 8a6c683..c3b03f5 100644
--- a/lib/chessh/auth/password.ex
+++ b/lib/chessh/auth/password.ex
@@ -1,6 +1,5 @@
defmodule Chessh.Auth.PasswordAuthenticator do
- alias Chessh.Player
- alias Chessh.Repo
+ alias Chessh.{Player, Repo}
def authenticate(username, password) do
case Repo.get_by(Player, username: String.Chars.to_string(username)) do
diff --git a/lib/chessh/schema/key.ex b/lib/chessh/schema/key.ex
index 765c83b..adf018d 100644
--- a/lib/chessh/schema/key.ex
+++ b/lib/chessh/schema/key.ex
@@ -16,7 +16,7 @@ defmodule Chessh.Key do
|> cast(update_encode_key(attrs, :key), [:key])
|> cast(attrs, [:name])
|> validate_required([:key, :name])
- |> validate_format(:key, ~r/[\-\w\d]+ [^ ]+$/, message: "invalid ssh key")
+ |> validate_format(:key, ~r/[\-\w\d]+ [^ ]+$/, message: "invalid public ssh key")
|> validate_format(:key, ~r/^(?!ssh-dss).+/, message: "DSA keys are not supported")
end
@@ -41,7 +41,6 @@ defmodule Chessh.Key do
end
# Remove comment at end of key
|> String.replace(~r/ [^ ]+\@[^ ]+$/, "")
- # Remove potential spaces / newline
|> String.trim()
end
end
diff --git a/lib/chessh/ssh/daemon.ex b/lib/chessh/ssh/daemon.ex
new file mode 100644
index 0000000..acb6bea
--- /dev/null
+++ b/lib/chessh/ssh/daemon.ex
@@ -0,0 +1,60 @@
+defmodule Chessh.SSH.Daemon do
+ use GenServer
+
+ def start_link(_) do
+ GenServer.start_link(__MODULE__, %{
+ pid: nil
+ })
+ end
+
+ def init(state) do
+ GenServer.cast(self(), :start)
+ {: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
+ :disconnect
+ else
+ {false, newAttempts + 1}
+ end
+ end
+ end
+
+ def handle_cast(:start, state) do
+ port = Application.fetch_env!(:chessh, :port)
+ key_dir = String.to_charlist(Application.fetch_env!(:chessh, :key_dir))
+ max_sessions = Application.fetch_env!(:chessh, :max_sessions)
+
+ case :ssh.daemon(
+ port,
+ system_dir: key_dir,
+ pwdfun: &pwd_authenticate/4,
+ key_cb: Chessh.SSH.ServerKey,
+ id_string: :random,
+ subsystems: [],
+ parallel_login: true,
+ max_sessions: max_sessions
+ ) do
+ {:ok, pid} ->
+ Process.link(pid)
+ {:noreply, %{state | pid: pid}, :hibernate}
+
+ {:error, err} ->
+ raise inspect(err)
+ end
+
+ {:noreply, state}
+ end
+
+ def handle_info(_, state), do: {:noreply, state}
+end
diff --git a/lib/chessh/ssh/server.ex b/lib/chessh/ssh/server.ex
deleted file mode 100644
index e69de29..0000000
--- a/lib/chessh/ssh/server.ex
+++ /dev/null
diff --git a/lib/chessh/ssh/server_key.ex b/lib/chessh/ssh/server_key.ex
new file mode 100644
index 0000000..1096e09
--- /dev/null
+++ b/lib/chessh/ssh/server_key.ex
@@ -0,0 +1,11 @@
+defmodule Chessh.SSH.ServerKey do
+ @behaviour :ssh_server_key_api
+
+ def is_auth_key(key, username, _daemon_options) do
+ Chessh.Auth.KeyAuthenticator.authenticate(username, key)
+ end
+
+ def host_key(algorithm, daemon_options) do
+ :ssh_file.host_key(algorithm, daemon_options)
+ end
+end