From 073bcbd2ddbde3055a406c1e39a9c0365817af5d Mon Sep 17 00:00:00 2001
From: nishi <nishi@f982e544-4a7d-3444-ad1a-fde59a2a69f1>
Date: Sat, 11 May 2024 10:42:36 +0000
Subject: [PATCH] rewrite mkpasswd in c

git-svn-id: file:///raid/svn-main/nishi-mandshurica/trunk@88 f982e544-4a7d-3444-ad1a-fde59a2a69f1
---
 CTool/GNUmakefile       | 30 ++++++++++++++
 CTool/mkpasswd.c        | 87 +++++++++++++++++++++++++++++++++++++++++
 GNUmakefile             | 19 ++++++---
 Mandshurica/GNUmakefile |  2 +-
 Module/cookie.c         | 24 +++++++++++-
 5 files changed, 154 insertions(+), 8 deletions(-)
 create mode 100644 CTool/GNUmakefile
 create mode 100644 CTool/mkpasswd.c

diff --git a/CTool/GNUmakefile b/CTool/GNUmakefile
new file mode 100644
index 0000000..6695f3f
--- /dev/null
+++ b/CTool/GNUmakefile
@@ -0,0 +1,30 @@
+# $Id$
+
+EXTRA_CFLAGS =
+EXTRA_LDFLAGS =
+EXTRA_LIBS = -lcrypto
+
+.PHONY: all clean install
+
+all: ./mkpasswd
+
+./mkpasswd: ./mkpasswd.o ./util.o ./db.o ./crypto.o
+	$(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS)
+
+./mkpasswd.o: ./mkpasswd.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+
+./util.o: ../Mandshurica/util.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+
+./db.o: ../Mandshurica/db.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+
+./crypto.o: ../Mandshurica/crypto.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+	
+install:
+	cp ./mkpasswd $(PREFIX)/bin/
+
+clean:
+	rm -f ./mkpasswd ./*.o
diff --git a/CTool/mkpasswd.c b/CTool/mkpasswd.c
new file mode 100644
index 0000000..542c05a
--- /dev/null
+++ b/CTool/mkpasswd.c
@@ -0,0 +1,87 @@
+/* $Id$ */
+/* --- START LICENSE --- */
+/* --- END LICENSE --- */
+
+#include "../Mandshurica/ms_crypto.h"
+#include "../Mandshurica/ms_db.h"
+#include "../Mandshurica/ms_util.h"
+
+#include <termios.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+const char avail[] = " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+
+int main(int argc, char** argv){
+	if(argc != 3){
+		fprintf(stderr, "Usage: %s database username\n", argv[0]);
+		return 1;
+	}
+	int retcode = 0;
+	struct ms_db* db = mandshurica_db_open(argv[1]);
+	if(db != NULL){
+		struct termios oldattr, newattr;
+		tcgetattr(STDIN_FILENO, &oldattr);
+		newattr = oldattr;
+		newattr.c_lflag &= ~(ECHO | ICANON);
+		tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
+		char cbuf[2];
+		cbuf[1] = 0;
+		printf("New password: ");
+		fflush(stdout);
+		char* passwd = malloc(1);
+		passwd[0] = 0;
+		while(1){
+			cbuf[0] = getchar();
+			if(cbuf[0] == '\n') break;
+			char* tmp = passwd;
+			passwd = mandshurica_strcat(tmp, cbuf);
+			free(tmp);
+		}
+		printf("\n");
+		printf("Verify password: ");
+		fflush(stdout);
+		char* vpasswd = malloc(1);
+		vpasswd[0] = 0;
+		while(1){
+			cbuf[0] = getchar();
+			if(cbuf[0] == '\n') break;
+			char* tmp = vpasswd;
+			vpasswd = mandshurica_strcat(tmp, cbuf);
+			free(tmp);
+		}
+		printf("\n");
+		if(strcmp(passwd, vpasswd) == 0){
+			char* salt = malloc(17);
+			salt[16] = 0;
+			int i;
+			srand(time(NULL));
+			for(i = 0; i < 16; i++){
+				salt[i] = avail[rand() % sizeof(avail)];
+			}
+			char* _pwd = mandshurica_strcat(passwd, salt);
+			char* pwd_sha512 = mandshurica_sha512(_pwd);
+			free(_pwd);
+			char* pwd = mandshurica_strcat3(pwd_sha512, "$", salt);
+			free(pwd_sha512);
+			free(salt);
+			free(vpasswd);
+			free(passwd);
+			mandshurica_db_write(db, argv[2], pwd);
+			free(pwd);
+		}else{
+			fprintf(stderr, "Password mismatch\n");
+			retcode = 1;
+		}
+
+		tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
+		mandshurica_db_close(db);
+	}else{
+		fprintf(stderr, "Failed to open the database\n");
+		retcode = 1;
+	}
+	return retcode;
+}
diff --git a/GNUmakefile b/GNUmakefile
index bc03387..694bf3e 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -8,7 +8,7 @@ DATABASE_PREFIX := $(PREFIX)/lib/mandshurica/db
 
 .PHONY: all clean format replace ./Mandshurica ./Module ./Tool
 
-all: ./config.mk ./Mandshurica ./Module ./Tool
+all: ./config.mk ./Mandshurica ./Module ./Tool ./CTool
 
 ./config.mk:
 	echo "PREFIX := $(PREFIX)" > $@
@@ -18,6 +18,8 @@ all: ./config.mk ./Mandshurica ./Module ./Tool
 	echo "TOOL_PREFIX := $(TOOL_PREFIX)" >> $@
 	echo "DATABASE_PREFIX := $(DATABASE_PREFIX)" >> $@
 
+PREFIXES := PREFIX="$(PREFIX)" MODULE_PREFIX="$(MODULE_PREFIX)" PROJECT_PREFIX="$(PROJECT_PREFIX)" TOOL_PREFIX="$(TOOL_PREFIX)" WEBROOT_PREFIX="$(WEBROOT_PREFIX)"
+
 CC := gcc
 CFLAGS := -g -std=c99 -DPREFIX=\\\"$(PREFIX)\\\" -DWEBROOT_PREFIX=\\\"$(WEBROOT_PREFIX)\\\" -DMODULE_PREFIX=\\\"$(MODULE_PREFIX)\\\" -DPROJECT_PREFIX=\\\"$(PROJECT_PREFIX)\\\" -DTOOL_PREFIX=\\\"$(TOOL_PREFIX)\\\" -DDATABASE_PREFIX=\\\"$(DATABASE_PREFIX)\\\" -D_DEFAULT_SOURCE
 LDFLAGS :=
@@ -32,6 +34,9 @@ LIBS :=
 ./Tool::
 	$(MAKE) -C $@ CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)"
 
+./CTool::
+	$(MAKE) -C $@ CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)"
+
 
 format:
 	clang-format -i $(wildcard Module/*.c Module/*.h Mandshurica/*.c Mandshurica/*.h)
@@ -49,13 +54,14 @@ install: all
 	touch $(PREFIX)/lib/mandshurica/db/auth.db $(PREFIX)/lib/mandshurica/db/login.db $(PREFIX)/lib/mandshurica/db/project.db
 	cp ./mkpasswd.pl $(PREFIX)/bin/
 	./Mandshurica/mandshurica --create $(PREFIX)/etc/mandshurica.conf
-	$(MAKE) -C ./Mandshurica install PREFIX="$(PREFIX)" MODULE_PREFIX="$(MODULE_PREFIX)" PROJECT_PREFIX="$(PROJECT_PREFIX)" TOOL_PREFIX="$(TOOL_PREFIX)" WEBROOT_PREFIX="$(WEBROOT_PREFIX)"
-	$(MAKE) -C ./Module install PREFIX="$(PREFIX)" MODULE_PREFIX="$(MODULE_PREFIX)" PROJECT_PREFIX="$(PROJECT_PREFIX)" TOOL_PREFIX="$(TOOL_PREFIX)" WEBROOT_PREFIX="$(WEBROOT_PREFIX)" DATABASE_PREFIX="$(DATABASE_PREFIX)"
-	$(MAKE) -C ./Tool install PREFIX="$(PREFIX)" MODULE_PREFIX="$(MODULE_PREFIX)" PROJECT_PREFIX="$(PROJECT_PREFIX)" TOOL_PREFIX="$(TOOL_PREFIX)" WEBROOT_PREFIX="$(WEBROOT_PREFIX)" DATABASE_PREFIX="$(DATABASE_PREFIX)"
-	$(MAKE) -C ./Webroot install PREFIX="$(PREFIX)" MODULE_PREFIX="$(MODULE_PREFIX)" PROJECT_PREFIX="$(PROJECT_PREFIX)" TOOL_PREFIX="$(TOOL_PREFIX)" WEBROOT_PREFIX="$(WEBROOT_PREFIX)" DATABASE_PREFIX="$(DATABASE_PREFIX)"
+	$(MAKE) -C ./Mandshurica install $(PREFIXES)
+	$(MAKE) -C ./Module install $(PREFIXES)
+	$(MAKE) -C ./Tool install $(PREFIXES)
+	$(MAKE) -C ./Webroot install $(PREFIXES)
+	$(MAKE) -C ./CTool install $(PREFIXES)
 	@echo "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
 	@echo "Mandshurica executable has been installed to $(PREFIX)/bin"
-	@echo "mkpasswd.pl has been installed to $(PREFIX)/bin"
+	@echo "mkpasswd has been installed to $(PREFIX)/bin"
 	@echo "Authentication database is at $(PREFIX)/lib/mandshurica/db/auth.db"
 	@echo
 	@echo "Thank you for choosing Mandshurica"
@@ -65,4 +71,5 @@ clean:
 	$(MAKE) -C ./Mandshurica clean
 	$(MAKE) -C ./Module clean
 	$(MAKE) -C ./Tool clean
+	$(MAKE) -C ./CTool clean
 	rm -f ./config.mk
diff --git a/Mandshurica/GNUmakefile b/Mandshurica/GNUmakefile
index 5c0a4b2..b517241 100644
--- a/Mandshurica/GNUmakefile
+++ b/Mandshurica/GNUmakefile
@@ -18,7 +18,7 @@ all: ./mandshurica
 ./main.o: ./main.c ./mandshurica.h
 	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
 
-./%.o: ./%.c ./mandshurica%.h
+./%.o: ./%.c ./ms_%.h
 	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
 	
 install:
diff --git a/Module/cookie.c b/Module/cookie.c
index 39a2fbb..850a684 100644
--- a/Module/cookie.c
+++ b/Module/cookie.c
@@ -114,13 +114,35 @@ int mod_auth(const char* username, const char* password, char** ptr) {
 				mandshurica_db_close(db);
 				return MS_AUTH_FAIL;
 			} else {
-				char* sh = config->mandshurica_sha512(password);
+				int i;
+				bool has_salt = false;
+				char* salt = NULL;
+				for(i = 0; pwd[i] != 0; i++) {
+					if(pwd[i] == '$') {
+						pwd[i] = 0;
+						has_salt = true;
+						salt = mandshurica_strdup(pwd + i + 1);
+						break;
+					}
+				}
+				char* sh;
+				if(has_salt) {
+					char* password_wsalt = mandshurica_strcat(password, salt);
+					sh = config->mandshurica_sha512(password_wsalt);
+					free(password_wsalt);
+					free(salt);
+				} else {
+					/* Backward compatible, not recommended */
+					sh = config->mandshurica_sha512(password);
+				}
 				if(strcmp(sh, pwd) == 0) {
 					free(sh);
 					*ptr = generate_token(username);
+					free(pwd);
 					return MS_AUTH_OK;
 				}
 				free(sh);
+				free(pwd);
 				return MS_AUTH_FAIL;
 			}
 			mandshurica_db_close(db);
-- 
2.43.0