commit: e016382605f6cdc93afc3bd63d8df6a53225b80c
parent 43250cd651ad96a1b50d06de1dccda647af69509
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 28 Sep 2025 13:51:15 +0200
argv0, no-strlen hash_match
Diffstat:
5 files changed, 32 insertions(+), 46 deletions(-)
diff --git a/common.c b/common.c
@@ -13,25 +13,20 @@
#include <termios.h> // tcgetattr, tcsetattr
#include <unistd.h> // crypt
-#ifndef MIN
+#undef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-// Needs to be constant-time so the hash can't be guessed via using a rainbow-table
+// Needs to be constant-time
bool
-hash_match(const char *a, const char *b)
+hash_match(const char *a, size_t alen, const char *b, size_t blen)
{
- /* flawfinder: ignore CWE-126 */
- size_t len_a = strlen(a);
- /* flawfinder: ignore CWE-126 */
- size_t len_b = strlen(b);
- size_t n = MIN(len_a, len_b);
- bool ret = true;
+ size_t n = MIN(alen, blen);
+ bool ret = true;
for(size_t i = 0; i < n; i++)
if(a[i] != b[i]) ret = false;
- if(len_a != len_b)
+ if(alen != blen)
return false;
else
return ret;
@@ -40,18 +35,18 @@ hash_match(const char *a, const char *b)
bool
skeud_crypt_check(const char *hash, const char *password)
{
- if(!hash) return false;
- if(strcmp(hash, "") == 0) return false;
+ size_t hashlen = strlen0(hash);
+ if(hashlen == 0) return false;
/* flawfinder: ignore CWE-327, crypt is the only relevant function */
char *chk_hash = crypt(password, hash);
if(chk_hash == NULL)
{
- perror("skeud_crypt_check: error: crypt");
+ fprintf(stderr, "%s: error: Failed hashing password: %s\n", argv0, strerror(errno));
return false;
}
- bool match = hash_match(hash, chk_hash);
+ bool match = hash_match(hash, hashlen, chk_hash, strlen(chk_hash));
// cleanup
chk_hash = crypt("", hash);
diff --git a/common.h b/common.h
@@ -4,7 +4,10 @@
#include <stdbool.h> // bool
#include <sys/types.h> // ssize_t
-size_t smin(size_t a, size_t b);
-bool hash_match(const char *a, const char *b);
+extern const char *argv0;
+
+#define strlen0(str) str ? strlen(str) : 0
+
+bool hash_match(const char *a, size_t alen, const char *b, size_t blen);
bool skeud_crypt_check(const char *hash, const char *password);
ssize_t skeud_getpass(char **password);
diff --git a/common_test.c b/common_test.c
@@ -4,43 +4,26 @@
#include "common.h"
#include <stdio.h>
+#include <string.h> // strlen
+
+const char *argv0 = "common_test";
int counter = 0;
int err = 0;
static void
-test_hash_match(int ret, const char *s1, const char *s2)
-{
- int id = ++counter;
- int got = hash_match(s1, s2);
-
- if(got == ret)
- {
- printf("ok %d - hash_match(\"%s\", \"%s\") == %d\n", id, s1, s2, ret);
- return;
- }
-
- err = 1;
-
- printf("not ok %d - hash_match(\"%s\", \"%s\") == %d\n", id, s1, s2, ret);
- printf("# Got: %d\n", got);
-}
-
-static void
-test_crypt_check(int ret, const char *s1, const char *s2)
+check_int(const char *name, int got, int exp)
{
- int id = ++counter;
- int got = skeud_crypt_check(s1, s2);
-
- if(got == ret)
+ int id = ++counter;
+ if(got == exp)
{
- printf("ok %d - skeud_crypt_check(\"%s\", \"%s\") == %d\n", id, s1, s2, ret);
+ printf("ok %d - %s ==> %d\n", id, name, exp);
return;
}
err = 1;
- printf("not ok %d - skeud_crypt_check(\"%s\", \"%s\") == %d\n", id, s1, s2, ret);
+ printf("not ok %d - %s ==> %d\n", id, name, exp);
printf("# Got: %d\n", got);
}
@@ -50,11 +33,14 @@ main(void)
int plan = 12;
printf("1..%d\n", plan);
+#define CHECK_INT(func, exp) check_int(#func, func, exp)
+#define test_hash_match(exp, s1, s2) CHECK_INT(hash_match(s1, strlen0(s1), s2, strlen0(s2)), exp)
test_hash_match(1, "foo", "foo");
test_hash_match(0, "foo", "bar");
test_hash_match(0, "foo", "fooo");
test_hash_match(0, "fooo", "foo");
+#define test_crypt_check(exp, s1, s2) CHECK_INT(skeud_crypt_check(s1, s2), exp)
test_crypt_check(0, NULL, "foobar");
test_crypt_check(0, "", "foobar");
test_crypt_check(0, "x", "foobar");
@@ -70,10 +56,10 @@ main(void)
test_crypt_check(1, "$5$8VryLuwDTzZ8MSZX$2UIaWB5LcMlhXv7UQIBcFeq8/Dr6PswXZP/SJ09L01B", "foobar");
// SHA512: openssl passwd -6 -noverify
- const char *hash =
+ const char *sha256_hash =
"$6$QUEEGuX9dkGlNkTP$IJwcvb6tpm63hoOfm9QJjEgjte/OpcQS3S43zDN95G3diJ5Xc/OlhhbCkUyV/"
"A0ARhgQj2D/4m/DWhwvvs3A91";
- test_crypt_check(1, hash, "foobar");
+ test_crypt_check(1, sha256_hash, "foobar");
if(counter != plan)
{
diff --git a/login.c b/login.c
@@ -27,7 +27,8 @@
#define TTY_PERMS 0600
extern char **environ;
-char *envclear[] = {NULL};
+char *envclear[] = {NULL};
+const char *argv0 = "login";
static int
process_pwent(struct passwd *pwent)
diff --git a/su.c b/su.c
@@ -23,7 +23,8 @@
#include <unistd.h> // getuid, getopt, opt*, chdir, setuid, setgid
extern char **environ;
-char *envclear[] = {NULL};
+char *envclear[] = {NULL};
+const char *argv0 = "su";
int
main(int argc, char *argv[])