EXPERIMENTAL Password Hashing

This commit is contained in:
Andrew Pamment 2016-08-04 21:41:37 +10:00
parent 3954817248
commit 73aa146b84
8 changed files with 290 additions and 87 deletions

View File

@ -9,10 +9,10 @@ OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o
%.o: %.c $(DEPS) %.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS) $(CC) -c -o $@ $< $(CFLAGS)
magicka: $(OBJ) magicka: $(OBJ)
$(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 $(JAMLIB) $(ZMODEM) $(LUA) -lutil -lm $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 $(JAMLIB) $(ZMODEM) $(LUA) -lutil -lm -lssl -lcrypto
.PHONY: clean .PHONY: clean
clean: clean:
rm -f $(OBJ) magicka rm -f $(OBJ) magicka

View File

@ -9,10 +9,10 @@ OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o
%.o: %.c $(DEPS) %.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS) $(CC) -c -o $@ $< $(CFLAGS)
magicka: $(OBJ) magicka: $(OBJ)
$(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 $(JAMLIB) $(ZMODEM) $(LUA) -lutil -lm -ldl $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 $(JAMLIB) $(ZMODEM) $(LUA) -lutil -lm -ldl -lssl -lcrypto
.PHONY: clean .PHONY: clean
clean: clean:
rm -f $(OBJ) magicka rm -f $(OBJ) magicka

View File

@ -9,10 +9,10 @@ OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o
%.o: %.c $(DEPS) %.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS) $(CC) -c -o $@ $< $(CFLAGS)
magicka: $(OBJ) magicka: $(OBJ)
$(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/pkg/lib -lsqlite3 $(JAMLIB) $(ZMODEM) $(LUA) -lutil -lm $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/pkg/lib -lsqlite3 $(JAMLIB) $(ZMODEM) $(LUA) -lutil -lm -lssl -lcrypto
.PHONY: clean .PHONY: clean
clean: clean:
rm -f $(OBJ) magicka rm -f $(OBJ) magicka

1
bbs.h
View File

@ -120,6 +120,7 @@ struct user_record {
int id; int id;
char *loginname; char *loginname;
char *password; char *password;
char *salt;
char *firstname; char *firstname;
char *lastname; char *lastname;
char *email; char *email;

165
users.c
View File

@ -3,11 +3,64 @@
#include <stdlib.h> #include <stdlib.h>
#include <sqlite3.h> #include <sqlite3.h>
#include <ctype.h> #include <ctype.h>
#include <openssl/sha.h>
#include "bbs.h" #include "bbs.h"
#include "inih/ini.h" #include "inih/ini.h"
extern struct bbs_config conf; extern struct bbs_config conf;
char *hash_sha256(char *pass, char *salt) {
char *buffer = (char *)malloc(strlen(pass) + strlen(salt) + 1);
char *shash = (char *)malloc(66);
unsigned char hash[SHA256_DIGEST_LENGTH];
if (!buffer) {
dolog("Out of memory!");
exit(-1);
}
sprintf(buffer, "%s%s", pass, salt);
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, buffer, strlen(buffer));
SHA256_Final(hash, &sha256);
int i = 0;
for(i = 0; i < SHA256_DIGEST_LENGTH; i++) {
sprintf(shash + (i * 2), "%02x", hash[i]);
}
shash[64] = 0;
free(buffer);
return shash;
}
void gen_salt(char **s) {
FILE *fptr;
int i;
char c;
*s = (char *)malloc(11);
char *salt = *s;
if (!salt) {
dolog("Out of memory..");
exit(-1);
}
fptr = fopen("/dev/urandom", "rb");
if (!fptr) {
dolog("Unable to open /dev/urandom!");
exit(-1);
}
for (i=0;i<10;i++) {
fread(&c, 1, 1, fptr);
salt[i] = (char)((abs(c) % 93) + 33);
}
fclose(fptr);
salt[10] = '\0';
}
static int secLevel(void* user, const char* section, const char* name, static int secLevel(void* user, const char* section, const char* name,
const char* value) const char* value)
{ {
@ -27,7 +80,7 @@ int save_user(struct user_record *user) {
sqlite3_stmt *res; sqlite3_stmt *res;
int rc; int rc;
char *update_sql = "UPDATE users SET password=?, firstname=?," char *update_sql = "UPDATE users SET password=?, salt=?, firstname=?,"
"lastname=?, email=?, location=?, sec_level=?, last_on=?, time_left=?, cur_mail_conf=?, cur_mail_area=?, cur_file_dir=?, cur_file_sub=?, times_on=? where loginname LIKE ?"; "lastname=?, email=?, location=?, sec_level=?, last_on=?, time_left=?, cur_mail_conf=?, cur_mail_area=?, cur_file_dir=?, cur_file_sub=?, times_on=? where loginname LIKE ?";
char *err_msg = 0; char *err_msg = 0;
@ -46,19 +99,20 @@ int save_user(struct user_record *user) {
if (rc == SQLITE_OK) { if (rc == SQLITE_OK) {
sqlite3_bind_text(res, 1, user->password, -1, 0); sqlite3_bind_text(res, 1, user->password, -1, 0);
sqlite3_bind_text(res, 2, user->firstname, -1, 0); sqlite3_bind_text(res, 2, user->salt, -1, 0);
sqlite3_bind_text(res, 3, user->lastname, -1, 0); sqlite3_bind_text(res, 3, user->firstname, -1, 0);
sqlite3_bind_text(res, 4, user->email, -1, 0); sqlite3_bind_text(res, 4, user->lastname, -1, 0);
sqlite3_bind_text(res, 5, user->location, -1, 0); sqlite3_bind_text(res, 5, user->email, -1, 0);
sqlite3_bind_int(res, 6, user->sec_level); sqlite3_bind_text(res, 6, user->location, -1, 0);
sqlite3_bind_int(res, 7, user->laston); sqlite3_bind_int(res, 7, user->sec_level);
sqlite3_bind_int(res, 8, user->timeleft); sqlite3_bind_int(res, 8, user->laston);
sqlite3_bind_int(res, 9, user->cur_mail_conf); sqlite3_bind_int(res, 9, user->timeleft);
sqlite3_bind_int(res, 10, user->cur_mail_area); sqlite3_bind_int(res, 10, user->cur_mail_conf);
sqlite3_bind_int(res, 11, user->cur_file_dir); sqlite3_bind_int(res, 11, user->cur_mail_area);
sqlite3_bind_int(res, 12, user->cur_file_sub); sqlite3_bind_int(res, 12, user->cur_file_dir);
sqlite3_bind_int(res, 13, user->timeson); sqlite3_bind_int(res, 13, user->cur_file_sub);
sqlite3_bind_text(res, 14, user->loginname, -1, 0); sqlite3_bind_int(res, 14, user->timeson);
sqlite3_bind_text(res, 15, user->loginname, -1, 0);
} else { } else {
dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
} }
@ -86,6 +140,7 @@ int inst_user(struct user_record *user) {
"Id INTEGER PRIMARY KEY," "Id INTEGER PRIMARY KEY,"
"loginname TEXT COLLATE NOCASE," "loginname TEXT COLLATE NOCASE,"
"password TEXT," "password TEXT,"
"salt TEXT,"
"firstname TEXT," "firstname TEXT,"
"lastname TEXT," "lastname TEXT,"
"email TEXT," "email TEXT,"
@ -99,8 +154,8 @@ int inst_user(struct user_record *user) {
"cur_file_dir INTEGER," "cur_file_dir INTEGER,"
"times_on INTEGER);"; "times_on INTEGER);";
char *insert_sql = "INSERT INTO users (loginname, password, firstname," char *insert_sql = "INSERT INTO users (loginname, password, salt, firstname,"
"lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on) VALUES(?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; "lastname, email, location, sec_level, last_on, time_left, cur_mail_conf, cur_mail_area, cur_file_dir, cur_file_sub, times_on) VALUES(?,?, ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
char *err_msg = 0; char *err_msg = 0;
sprintf(buffer, "%s/users.sq3", conf.bbs_path); sprintf(buffer, "%s/users.sq3", conf.bbs_path);
@ -130,18 +185,19 @@ int inst_user(struct user_record *user) {
if (rc == SQLITE_OK) { if (rc == SQLITE_OK) {
sqlite3_bind_text(res, 1, user->loginname, -1, 0); sqlite3_bind_text(res, 1, user->loginname, -1, 0);
sqlite3_bind_text(res, 2, user->password, -1, 0); sqlite3_bind_text(res, 2, user->password, -1, 0);
sqlite3_bind_text(res, 3, user->firstname, -1, 0); sqlite3_bind_text(res, 3, user->salt, -1, 0);
sqlite3_bind_text(res, 4, user->lastname, -1, 0); sqlite3_bind_text(res, 4, user->firstname, -1, 0);
sqlite3_bind_text(res, 5, user->email, -1, 0); sqlite3_bind_text(res, 5, user->lastname, -1, 0);
sqlite3_bind_text(res, 6, user->location, -1, 0); sqlite3_bind_text(res, 6, user->email, -1, 0);
sqlite3_bind_int(res, 7, user->sec_level); sqlite3_bind_text(res, 7, user->location, -1, 0);
sqlite3_bind_int(res, 8, user->laston); sqlite3_bind_int(res, 8, user->sec_level);
sqlite3_bind_int(res, 9, user->timeleft); sqlite3_bind_int(res, 9, user->laston);
sqlite3_bind_int(res, 10, user->cur_mail_conf); sqlite3_bind_int(res, 10, user->timeleft);
sqlite3_bind_int(res, 11, user->cur_mail_area); sqlite3_bind_int(res, 11, user->cur_mail_conf);
sqlite3_bind_int(res, 12, user->cur_file_dir); sqlite3_bind_int(res, 12, user->cur_mail_area);
sqlite3_bind_int(res, 13, user->cur_file_sub); sqlite3_bind_int(res, 13, user->cur_file_dir);
sqlite3_bind_int(res, 14, user->timeson); sqlite3_bind_int(res, 14, user->cur_file_sub);
sqlite3_bind_int(res, 15, user->timeson);
} else { } else {
dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
@ -151,10 +207,9 @@ int inst_user(struct user_record *user) {
rc = sqlite3_step(res); rc = sqlite3_step(res);
if (rc != SQLITE_DONE) { if (rc != SQLITE_DONE) {
dolog("execution failed: %s", sqlite3_errmsg(db)); dolog("execution failed: %s", sqlite3_errmsg(db));
sqlite3_close(db); sqlite3_close(db);
exit(1); exit(1);
} }
user->id = sqlite3_last_insert_rowid(db); user->id = sqlite3_last_insert_rowid(db);
@ -168,9 +223,10 @@ struct user_record *check_user_pass(int socket, char *loginname, char *password)
struct user_record *user; struct user_record *user;
char buffer[256]; char buffer[256];
sqlite3 *db; sqlite3 *db;
sqlite3_stmt *res; sqlite3_stmt *res;
int rc; int rc;
char *sql = "SELECT * FROM users WHERE loginname LIKE ?"; char *sql = "SELECT * FROM users WHERE loginname LIKE ?";
char *pass_hash;
sprintf(buffer, "%s/users.sq3", conf.bbs_path); sprintf(buffer, "%s/users.sq3", conf.bbs_path);
@ -199,31 +255,37 @@ struct user_record *check_user_pass(int socket, char *loginname, char *password)
user->id = sqlite3_column_int(res, 0); user->id = sqlite3_column_int(res, 0);
user->loginname = strdup((char *)sqlite3_column_text(res, 1)); user->loginname = strdup((char *)sqlite3_column_text(res, 1));
user->password = strdup((char *)sqlite3_column_text(res, 2)); user->password = strdup((char *)sqlite3_column_text(res, 2));
user->firstname = strdup((char *)sqlite3_column_text(res, 3)); user->salt = strdup((char *)sqlite3_column_text(res, 3));
user->lastname = strdup((char *)sqlite3_column_text(res, 4)); user->firstname = strdup((char *)sqlite3_column_text(res, 4));
user->email = strdup((char *)sqlite3_column_text(res, 5)); user->lastname = strdup((char *)sqlite3_column_text(res, 5));
user->location = strdup((char *)sqlite3_column_text(res, 6)); user->email = strdup((char *)sqlite3_column_text(res, 6));
user->sec_level = sqlite3_column_int(res, 7); user->location = strdup((char *)sqlite3_column_text(res, 7));
user->laston = (time_t)sqlite3_column_int(res, 8); user->sec_level = sqlite3_column_int(res, 8);
user->timeleft = sqlite3_column_int(res, 9); user->laston = (time_t)sqlite3_column_int(res, 9);
user->cur_mail_conf = sqlite3_column_int(res, 10); user->timeleft = sqlite3_column_int(res, 10);
user->cur_mail_area = sqlite3_column_int(res, 11); user->cur_mail_conf = sqlite3_column_int(res, 11);
user->cur_file_dir = sqlite3_column_int(res, 13); user->cur_mail_area = sqlite3_column_int(res, 12);
user->cur_file_sub = sqlite3_column_int(res, 12); user->cur_file_dir = sqlite3_column_int(res, 14);
user->timeson = sqlite3_column_int(res, 14); user->cur_file_sub = sqlite3_column_int(res, 13);
user->timeson = sqlite3_column_int(res, 15);
if (strcmp(password, user->password) != 0) { pass_hash = hash_sha256(password, user->salt);
if (strcmp(pass_hash, user->password) != 0) {
free(user->loginname); free(user->loginname);
free(user->firstname); free(user->firstname);
free(user->lastname); free(user->lastname);
free(user->email); free(user->email);
free(user->location); free(user->location);
free(user->salt);
free(user); free(user);
sqlite3_finalize(res); free(pass_hash);
sqlite3_finalize(res);
sqlite3_close(db); sqlite3_close(db);
return NULL; return NULL;
} }
} else { free(pass_hash);
} else {
sqlite3_finalize(res); sqlite3_finalize(res);
sqlite3_close(db); sqlite3_close(db);
return NULL; return NULL;
@ -437,7 +499,8 @@ struct user_record *new_user(int socket) {
s_putstring(socket, "Password too short!\r\n"); s_putstring(socket, "Password too short!\r\n");
} }
} while (!passok); } while (!passok);
user->password = strdup(buffer); gen_salt(&user->salt);
user->password = hash_sha256(buffer, salt);
s_putstring(socket, "You Entered:\r\n"); s_putstring(socket, "You Entered:\r\n");
s_putstring(socket, "-------------------------------------\r\n"); s_putstring(socket, "-------------------------------------\r\n");
@ -451,8 +514,6 @@ struct user_record *new_user(int socket) {
s_putstring(socket, user->email); s_putstring(socket, user->email);
s_putstring(socket, "\r\nLocation: "); s_putstring(socket, "\r\nLocation: ");
s_putstring(socket, user->location); s_putstring(socket, user->location);
s_putstring(socket, "\r\nPassword: ");
s_putstring(socket, user->password);
s_putstring(socket, "\r\n-------------------------------------\r\n"); s_putstring(socket, "\r\n-------------------------------------\r\n");
s_putstring(socket, "Is this Correct? (Y/N)"); s_putstring(socket, "Is this Correct? (Y/N)");
c = s_getchar(socket); c = s_getchar(socket);

View File

@ -8,9 +8,9 @@
s_JamBase *open_jam_base(char *path) { s_JamBase *open_jam_base(char *path) {
int ret; int ret;
s_JamBase *jb; s_JamBase *jb;
ret = JAM_OpenMB((char *)path, &jb); ret = JAM_OpenMB((char *)path, &jb);
if (ret != 0) { if (ret != 0) {
if (ret == JAM_IO_ERROR) { if (ret == JAM_IO_ERROR) {
free(jb); free(jb);
@ -35,12 +35,12 @@ int main(int argc, char **argv) {
time_t thetime; time_t thetime;
int z; int z;
int i; int i;
s_JamBase *jb; s_JamBase *jb;
s_JamMsgHeader jmh; s_JamMsgHeader jmh;
s_JamSubPacket* jsp; s_JamSubPacket* jsp;
s_JamSubfield jsf; s_JamSubfield jsf;
if (argc < 6) { if (argc < 6) {
printf("Usage:\n"); printf("Usage:\n");
printf("%s [l|e] filename jambase from subject laddress\n", argv[0]); printf("%s [l|e] filename jambase from subject laddress\n", argv[0]);
@ -50,29 +50,29 @@ int main(int argc, char **argv) {
} }
if (tolower(argv[1][0]) != 'l' && tolower(argv[1][0]) != 'e') { if (tolower(argv[1][0]) != 'l' && tolower(argv[1][0]) != 'e') {
printf("Usage:\n"); printf("Usage:\n");
printf("%s [l|e] filename jambase from subject\n", argv[0]); printf("%s [l|e] filename jambase from subject laddress\n", argv[0]);
printf(" l = Local Message, e = Echomail Message\n"); printf(" l = Local Message, e = Echomail Message\n");
printf(" laddress is your network address, and only required on echomail.\n"); printf(" laddress is your network address, and only required on echomail.\n");
exit(1); exit(1);
} }
if (tolower(argv[1][0]) == 'e' && argc < 7) { if (tolower(argv[1][0]) == 'e' && argc < 7) {
printf("Usage:\n"); printf("Usage:\n");
printf("%s [l|e] filename jambase from subject\n", argv[0]); printf("%s [l|e] filename jambase from subject laddress\n", argv[0]);
printf(" l = Local Message, e = Echomail Message\n"); printf(" l = Local Message, e = Echomail Message\n");
printf(" laddress is your network address, and only required on echomail.\n"); printf(" laddress is your network address, and only required on echomail.\n");
exit(1); exit(1);
} }
fptr = fopen(argv[2], "r"); fptr = fopen(argv[2], "r");
if (!fptr) { if (!fptr) {
printf("Unable to open %s\n", argv[2]); printf("Unable to open %s\n", argv[2]);
exit(1); exit(1);
} }
body = NULL; body = NULL;
totlen = 0; totlen = 0;
len = fread(buffer, 1, 256, fptr); len = fread(buffer, 1, 256, fptr);
while (len > 0) { while (len > 0) {
totlen += len; totlen += len;
@ -85,33 +85,33 @@ int main(int argc, char **argv) {
body[totlen] = '\0'; body[totlen] = '\0';
len = fread(buffer, 1, 256, fptr); len = fread(buffer, 1, 256, fptr);
} }
fclose(fptr); fclose(fptr);
for (i=0;i<totlen;i++) { for (i=0;i<totlen;i++) {
if (body[i] == '\n') { if (body[i] == '\n') {
body[i] = '\r'; body[i] = '\r';
} }
} }
jb = open_jam_base(argv[3]); jb = open_jam_base(argv[3]);
if (!jb) { if (!jb) {
printf("Unable to open JAM base %s\n", argv[2]); printf("Unable to open JAM base %s\n", argv[2]);
exit(1); exit(1);
} }
thetime = time(NULL); thetime = time(NULL);
JAM_ClearMsgHeader( &jmh ); JAM_ClearMsgHeader( &jmh );
jmh.DateWritten = thetime; jmh.DateWritten = thetime;
jmh.Attribute |= MSG_LOCAL; jmh.Attribute |= MSG_LOCAL;
if (tolower(argv[1][0]) == 'l') { if (tolower(argv[1][0]) == 'l') {
jmh.Attribute |= MSG_TYPELOCAL; jmh.Attribute |= MSG_TYPELOCAL;
} else if (tolower(argv[1][0]) == 'e') { } else if (tolower(argv[1][0]) == 'e') {
jmh.Attribute |= MSG_TYPEECHO; jmh.Attribute |= MSG_TYPEECHO;
} }
jsp = JAM_NewSubPacket(); jsp = JAM_NewSubPacket();
jsf.LoID = JAMSFLD_SENDERNAME; jsf.LoID = JAMSFLD_SENDERNAME;
jsf.HiID = 0; jsf.HiID = 0;
@ -124,13 +124,13 @@ int main(int argc, char **argv) {
jsf.DatLen = 3; jsf.DatLen = 3;
jsf.Buffer = "ALL"; jsf.Buffer = "ALL";
JAM_PutSubfield(jsp, &jsf); JAM_PutSubfield(jsp, &jsf);
jsf.LoID = JAMSFLD_SUBJECT; jsf.LoID = JAMSFLD_SUBJECT;
jsf.HiID = 0; jsf.HiID = 0;
jsf.DatLen = strlen(argv[5]); jsf.DatLen = strlen(argv[5]);
jsf.Buffer = (char *)argv[5]; jsf.Buffer = (char *)argv[5];
JAM_PutSubfield(jsp, &jsf); JAM_PutSubfield(jsp, &jsf);
if (tolower(argv[1][0]) == 'e') { if (tolower(argv[1][0]) == 'e') {
jsf.LoID = JAMSFLD_OADDRESS; jsf.LoID = JAMSFLD_OADDRESS;
jsf.HiID = 0; jsf.HiID = 0;
@ -138,7 +138,7 @@ int main(int argc, char **argv) {
jsf.Buffer = (char *)argv[6]; jsf.Buffer = (char *)argv[6];
JAM_PutSubfield(jsp, &jsf); JAM_PutSubfield(jsp, &jsf);
} }
while (1) { while (1) {
z = JAM_LockMB(jb, 100); z = JAM_LockMB(jb, 100);
if (z == 0) { if (z == 0) {
@ -146,7 +146,7 @@ int main(int argc, char **argv) {
} else if (z == JAM_LOCK_FAILED) { } else if (z == JAM_LOCK_FAILED) {
sleep(1); sleep(1);
} else { } else {
printf("Failed to lock msg base!\n"); printf("Failed to lock msg base!\n");
break; break;
} }
} }
@ -154,11 +154,11 @@ int main(int argc, char **argv) {
if (JAM_AddMessage(jb, &jmh, jsp, (char *)body, strlen(body))) { if (JAM_AddMessage(jb, &jmh, jsp, (char *)body, strlen(body))) {
printf("Failed to add message\n"); printf("Failed to add message\n");
} }
JAM_UnlockMB(jb); JAM_UnlockMB(jb);
JAM_DelSubPacket(jsp); JAM_DelSubPacket(jsp);
} }
JAM_CloseMB(jb); JAM_CloseMB(jb);
return 0; return 0;
} }

View File

@ -0,0 +1,15 @@
CC=cc
CFLAGS=-I/usr/local/include
DEPS = update_pass.c
OBJ = update_pass.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
update_pass: $(OBJ)
$(CC) -o update_pass -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lssl -lcrypto
.PHONY: clean
clean:
rm -f $(OBJ) update_pass

View File

@ -0,0 +1,126 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <ctype.h>
#include <openssl/sha.h>
char *hash_sha256(char *pass, char *salt) {
char *buffer = (char *)malloc(strlen(pass) + strlen(salt) + 1);
char *shash = (char *)malloc(66);
unsigned char hash[SHA256_DIGEST_LENGTH];
if (!buffer) {
printf("Out of memory!");
exit(-1);
}
sprintf(buffer, "%s%s", pass, salt);
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, buffer, strlen(buffer));
SHA256_Final(hash, &sha256);
int i = 0;
for(i = 0; i < SHA256_DIGEST_LENGTH; i++) {
sprintf(shash + (i * 2), "%02x", hash[i]);
}
shash[64] = 0;
free(buffer);
return shash;
}
void gen_salt(char **s) {
FILE *fptr;
int i;
char c;
*s = (char *)malloc(11);
char *salt = *s;
if (!salt) {
printf("Out of memory..");
exit(-1);
}
fptr = fopen("/dev/urandom", "rb");
if (!fptr) {
printf("Unable to open /dev/urandom!");
exit(-1);
}
for (i=0;i<10;i++) {
fread(&c, 1, 1, fptr);
salt[i] = (char)((abs(c) % 93) + 33);
}
fclose(fptr);
salt[10] = '\0';
}
int main(int argc, char **argv) {
sqlite3 *db;
sqlite3_stmt *res;
sqlite3_stmt *res2;
char *alter_table_sql = "ALTER TABLE users ADD COLUMN salt TEXT";
char *select_sql = "SELECT Id,password FROM users";
char *update_sql = "UPDATE users SET password=?, salt=? WHERE Id=?";
char *err_msg = 0;
int id;
int rc;
char *password;
char *hash;
char *salt;
rc = sqlite3_open(argv[1], &db);
if (rc != SQLITE_OK) {
printf("Error opening database\n");
return -1;
}
rc = sqlite3_exec(db, alter_table_sql, 0, 0, &err_msg);
if (rc != SQLITE_OK ) {
printf("SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
rc = sqlite3_prepare_v2(db, select_sql, -1, &res, 0);
if (rc != SQLITE_OK) {
printf("Cannot prepare statement: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
while (sqlite3_step(res) == SQLITE_ROW) {
id = sqlite3_column_int(res, 0);
password = strdup(sqlite3_column_text(res, 1));
gen_salt(&salt);
hash = hash_sha256(password, salt);
rc = sqlite3_prepare_v2(db, update_sql, -1, &res2, 0);
if (rc != SQLITE_OK) {
printf("Cannot prepare statement: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
sqlite3_bind_text(res2, 1, hash, -1, 0);
sqlite3_bind_text(res2, 2, salt, -1, 0);
sqlite3_bind_int(res2, 3, id);
rc = sqlite3_step(res2);
if (rc != SQLITE_DONE) {
printf("Error: %s\n", sqlite3_errmsg(db));
exit(1);
}
sqlite3_finalize(res2);
}
printf("Converted!\n");
sqlite3_finalize(res);
sqlite3_close(db);
}