From: Egor Date: Thu, 22 Jan 2026 13:22:47 +0000 (+0200) Subject: job: templateize job_password_check X-Git-Url: https://git.patchysicp.xyz/?a=commitdiff_plain;h=dcc5f6430f5abb558b8b0ce62a013d7583ed3b5e;p=patchyircd.git job: templateize job_password_check --- diff --git a/src/irc.cpp b/src/irc.cpp index c51dff1..97dd0a0 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -386,7 +386,7 @@ int irc_process_line(Client *client, char *source, std::string_view command, int char *password = strchr(p, '\0')+1; if (password > client->saslbuf + client->saslbufLen) goto saslerr; - job_password_check(client, username, password, "users", [client](int res) { + job_password_check<"users">(client, username, password, [client](int res) { if (client->saslusername) { if (res == 0) { rpl_saslsuccess(), sendbuf(client); @@ -485,7 +485,7 @@ saslcleanup: memcpy(client->webirchostname, args[2], len); memcpy(client->webirchostname+len, ".xmpp", sizeof(".xmpp")); } - job_password_check(client, args[1], args[0], "webirc", [client](int res) { + job_password_check<"webirc">(client, args[1], args[0], [client](int res) { if (!(client->umode & UMODE_SECURE) || res != 0) { delete[] client->webircpeername; client->webircpeername = 0; @@ -515,7 +515,7 @@ saslcleanup: if (argc < 2) return err_needmoreparams(client, command), sendbuf(client), 0; stringlower(args[0]); - job_password_check(client, args[0], args[1], "ops", [client](int res) { + job_password_check<"ops">(client, args[0], args[1], [client](int res) { if (!(client->umode & UMODE_SECURE) || res != 0) { err_passwdmismatch(client), sendbuf(client); } else { @@ -1226,7 +1226,7 @@ void newUser(Client *client) { } } if (client->username[0] == '~' && client->pass_reg) { - job_password_check(client, client->username+1, client->pass_reg, "users", [client](int res) { + job_password_check<"users">(client, client->username+1, client->pass_reg, [client](int res) { if (client->passwait) { client->passwait = 0; if (!(client->umode & UMODE_SECURE) || res != 0) { diff --git a/src/job.cpp b/src/job.cpp index 37a45c4..f8730b6 100644 --- a/src/job.cpp +++ b/src/job.cpp @@ -118,27 +118,11 @@ struct SecureStringWrapper { } } }; -void job_password_check(Client *client, const char *key, const char *pw, const char *fn, contproc_t&& then) +static void job_password_check_internal(Client *client, const char *salt, const char *pw, contproc_t&& then) { - db::Statement stmt; - std::string_view salt; - if (fn == "ops"sv) - stmt = db::disk("SELECT hash FROM ops WHERE account = ?;"); - else if (fn == "users"sv) - stmt = db::disk("SELECT hash FROM users WHERE account = ?;"); - else if (fn == "webirc"sv) - stmt = db::disk("SELECT hash FROM webirc WHERE account = ?;"); - else - goto no_table; - - stmt.bind(1, key); - if (stmt.step()) - salt = stmt.text(0); - -no_table: // FIXME: make_shared only really needed here cuz std::function wants a copyable object // C++23 adds a std::move_only_function - job_add(client, [pw=std::make_shared(pw), salt=std::make_shared(salt.data())]() -> int { + job_add(client, [pw=std::make_shared(pw), salt=std::make_shared(salt)]() -> int { if (!*salt) return 1; char *hash = password_crypt(*pw, *salt); @@ -148,3 +132,25 @@ no_table: return rv; }, std::move(then)); } +template +consteval static std::array concat(const char (&a)[A], const char (&b)[B], const char (&c)[C]) { + std::array arr; + std::copy_n(a, A-1, &arr[0]); + std::copy_n(b, B-1, &arr[A-1]); + std::copy_n(c, C, &arr[A+B-2]); + return arr; +} +template +void job_password_check(Client *client, const char *key, const char *pw, contproc_t&& then) +{ + constexpr auto query = concat("SELECT hash FROM ", table.value, " WHERE account = ?;"); + auto stmt = db::disk(std::string_view(query.data(), query.size())); + stmt.bind(1, key); + std::string_view salt; + if (stmt.step()) + salt = stmt.text(0); + job_password_check_internal(client, salt.data(), pw, std::move(then)); +} +template void job_password_check<"ops">(Client *client, const char *key, const char *pw, contproc_t&& then); +template void job_password_check<"users">(Client *client, const char *key, const char *pw, contproc_t&& then); +template void job_password_check<"webirc">(Client *client, const char *key, const char *pw, contproc_t&& then); diff --git a/src/job.hpp b/src/job.hpp index 490e018..1d27887 100644 --- a/src/job.hpp +++ b/src/job.hpp @@ -10,5 +10,14 @@ void job_fini(void); void job_process(void); void job_add(Client *client, jobproc_t&& job, contproc_t&& then); void job_kill(Client *client); -void job_password_check(Client *client, const char *key, const char *pw, const char *fn, contproc_t&& then); +template +struct Literal { + char value[N]; + consteval Literal(const char (&s)[N]) { std::copy_n(s, N, value); } +}; +template +void job_password_check(Client *client, const char *key, const char *pw, contproc_t&& then); +extern template void job_password_check<"ops">(Client *client, const char *key, const char *pw, contproc_t&& then); +extern template void job_password_check<"users">(Client *client, const char *key, const char *pw, contproc_t&& then); +extern template void job_password_check<"webirc">(Client *client, const char *key, const char *pw, contproc_t&& then); #endif