Check credentials and create a session

This commit is contained in:
Josh Holtrop 2026-03-29 21:00:05 -04:00
parent 8a8d793199
commit d61c137c12
3 changed files with 53 additions and 9 deletions

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= hostname %> status</title>
<title><%= hostname %> status - MALP</title>
<style>
body {
background: #0f1117;
@ -115,7 +115,7 @@
<body>
<header>
<h1><span><%= hostname %></span> &middot; status</h1>
<h1><span><%= hostname %></span> status - MALP</h1>
</header>
<div class="card">

View File

@ -5,6 +5,9 @@ require "fileutils"
require "io/console"
require "securerandom"
DATA_DIR = File.join(__dir__, "../data")
USER_FILE = File.join(DATA_DIR, "user.txt")
print "User name: "
username = $stdin.gets.chomp
@ -16,14 +19,11 @@ end
print "Password: "
password = $stdin.noecho(&:gets).chomp
user_path = File.join(File.dirname(__FILE__), "../user.txt")
salt = SecureRandom.random_bytes(8)
salthex = salt.chars.map {|c| sprintf("%02X", c.ord)}.join
salt = SecureRandom.hex(8)
input = salt + password
hash = Digest::SHA256.hexdigest(input)
hashhex = hash.chars.map {|c| sprintf("%02X", c.ord)}.join
user_file_contents = "#{username}:#{salthex}:#{hashhex}\n"
user_file_contents = "#{username}:#{salt}:#{hashhex}\n"
File.binwrite(user_path, user_file_contents)
File.binwrite(USER_FILE, user_file_contents)
puts "User and password set"

View File

@ -2,15 +2,59 @@
require "cgi"
require "erb"
require "digest"
require "securerandom"
ASSETS_DIR = File.join(__dir__, "../assets")
DATA_DIR = File.join(__dir__, "../data")
SESSIONS_FILE = File.join(DATA_DIR, "sessions.txt")
USER_FILE = File.join(DATA_DIR, "user.txt")
cgi = CGI.new
hostname = File.read("/etc/hostname").strip rescue "localhost"
def valid_session?(token)
return false if token.nil? || token.empty?
return false unless File.exist?(SESSIONS_FILE)
File.readlines(SESSIONS_FILE).any? { |line| line.strip == token }
end
def check_credentials(username, password)
return false unless File.exist?(USER_FILE)
stored_user, salt, stored_hash_hex2 = File.read(USER_FILE).strip.split(":", 3)
return false unless username == stored_user
stored_hash = [stored_hash_hex2].pack("H*")
computed_hash = Digest::SHA256.hexdigest(salt + password)
stored_hash == computed_hash
end
def create_session
token = SecureRandom.hex(32)
File.open(SESSIONS_FILE, "a") { |f| f.puts(token) }
token
end
session_token = (cgi.cookies["MALP"] || []).first
authenticated = valid_session?(session_token)
cookie = nil
if cgi.request_method == "POST" && !authenticated
username = cgi.params["username"]&.first.to_s
password = cgi.params["password"]&.first.to_s
if check_credentials(username, password)
token = create_session
cookie = CGI::Cookie.new("name" => "MALP", "value" => token, "path" => "/")
authenticated = true
end
end
template = ERB.new(File.read(File.join(ASSETS_DIR, "page.erb")))
cgi.out("type" => "text/html", "charset" => "UTF-8") do
out_params = { "type" => "text/html", "charset" => "UTF-8" }
out_params["cookie"] = cookie if cookie
cgi.out(out_params) do
template.result(binding)
end