From 8f3a3d44db5d297336dc1138193514c6d79d080e Mon Sep 17 00:00:00 2001 From: Harishankar Date: Fri, 8 May 2020 11:48:37 +0530 Subject: [PATCH] Separate solution password implemented Implemented a solution password apart from the master password and now the player asks and checks for the solution password to reveal the solution rather than check the master password. --- constantstrings.h | 17 +++++---- wordblox.c | 48 ++++++++++++++++------- wordblox.h | 89 ++++++++++++++++++++++++++++++------------- wordblox_player.c | 12 ++++-- wordblox_player.glade | 37 ++++++++++++++---- 5 files changed, 146 insertions(+), 57 deletions(-) diff --git a/constantstrings.h b/constantstrings.h index d5f4734..d80bc1a 100644 --- a/constantstrings.h +++ b/constantstrings.h @@ -25,8 +25,10 @@ #define INVALID_WORD "Word contains illegal characters. Only alphabets allowed!" #define FILE_SAVED "File saved successfully" #define PASSWORD_SET "Password set successfully" -#define PASSWORD_RESET "Password reset successfully. Puzzle is no longer \ -password protected!" +#define MASTER_PASSWORD_RESET "Master password reset successfully. Puzzle no \ +longer password protected!" +#define SOLUTION_PASSWORD_RESET "Solution password reset successfully. Solution\ + can be viewed in the player without a password!" #define WRONG_PASSWORD "Wrong password!" #define NO_WORD_INDEX "No such word with specified index" #define INPUT_CONFIRM_EXIT "Are you sure you wish to exit? \ @@ -69,10 +71,11 @@ char *PUZZLE_EDIT_MENU[] = "7. Set Clue - Across Word", "8. Set Clue - Down Word", "9. Save puzzle", - "10.Set puzzle password", - "11.Reset entire grid", - "12.Export puzzle as PNG image", - "13.Export clues to text file", - "14.Return to main menu" }; + "10.Set master (editing) password", + "11.Set solution password", + "12.Reset entire grid", + "13.Export puzzle as PNG image", + "14.Export clues to text file", + "15.Return to main menu" }; #endif diff --git a/wordblox.c b/wordblox.c index 0cbb804..f30c039 100644 --- a/wordblox.c +++ b/wordblox.c @@ -70,22 +70,42 @@ void do_reset_puzzle (Puzzle *p) char ch = getchar (); } -/* set the password for the puzzle */ -void do_set_password (Puzzle *p) +/* set the solution password for the puzzle */ +void do_set_solution_password (Puzzle *p) { char* password; password = getpass (INPUT_PASSWORD); /* if empty reset the password to nothing */ if (strlen(password) == 0) { - set_puzzle_password (p, "\0"); - printf (PASSWORD_RESET); + set_solution_password (p, "\0"); + printf (SOLUTION_PASSWORD_RESET); char ch = getchar (); } /* set the password */ else { - set_puzzle_password (p, (const char* )password); + set_solution_password (p, (const char* )password); + printf (PASSWORD_SET); + char ch = getchar (); + } +} +/* set the master (editing) password for the puzzle */ +void do_set_master_password (Puzzle *p) +{ + char* password; + password = getpass (INPUT_PASSWORD); + /* if empty reset the password to nothing */ + if (strlen(password) == 0) + { + set_master_password (p, "\0"); + printf (MASTER_PASSWORD_RESET); + char ch = getchar (); + } + /* set the password */ + else + { + set_master_password (p, (const char* )password); printf (PASSWORD_SET); char ch = getchar (); } @@ -258,7 +278,7 @@ void puzzle_editor_loop (Puzzle *p, const char *filename) { char puzzle_title[60]; sprintf (puzzle_title, "%s - %s", PUZZLE_MENU_TITLE, filename); - print_menu (WHITE, BLUE, puzzle_title, PUZZLE_EDIT_MENU, 14, 50); + print_menu (WHITE, BLUE, puzzle_title, PUZZLE_EDIT_MENU, 15, 50); printf (INPUT_CHOICE); int ch = get_num (); switch (ch) @@ -288,15 +308,17 @@ void puzzle_editor_loop (Puzzle *p, const char *filename) printf ("%s\n",FILE_SAVED); ch = getchar (); break; - case 10: do_set_password (p); + case 10: do_set_master_password (p); + break; + case 11: do_set_solution_password (p); break; - case 11: do_reset_puzzle (p); + case 12: do_reset_puzzle (p); break; - case 12: do_export_puzzle (p); + case 13: do_export_puzzle (p); break; - case 13: do_export_clues (p); + case 14: do_export_clues (p); break; - case 14: loop = ! do_confirm_exit (); + case 15: loop = ! do_confirm_exit (); break; } } @@ -319,14 +341,14 @@ void do_open_puzzle (const char *filename) p = load_puzzle (filename); - if (strcmp (p.hashed_password, "\0") != 0) + if (strcmp (p.hashed_master_password, "\0") != 0) { char *passwd; passwd = getpass (INPUT_PASSWORD); if (strlen (passwd) == 0) return; - if (verify_password (&p, (const char*) passwd)) + if (verify_master_password (&p, (const char*) passwd)) puzzle_editor_loop (&p, filename); else { diff --git a/wordblox.h b/wordblox.h index 1925573..a355a09 100644 --- a/wordblox.h +++ b/wordblox.h @@ -57,8 +57,8 @@ typedef struct { String clue_down[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE]; int grid_size; bool grid_frozen; - char hashed_password[256]; - char salt[256]; + char hashed_master_password[256]; + char hashed_solution_password[256]; } Puzzle; /* The player data struct type - for the player app */ @@ -129,36 +129,75 @@ int get_num () return n; } -/* verify password */ -bool verify_password (Puzzle *p, const char* password) +/* verify solution password */ +bool verify_solution_password (Puzzle *p, const char* password) { /* no password set */ - if (strcmp (p->hashed_password, "\0") == 0) + if (strcmp (p->hashed_solution_password, "\0") == 0) return true; /* hash the user input password and compare it with the stored password */ - unsigned char* hashed_password; + unsigned char* hashed_sol_password; unsigned int len; digest_message ((const unsigned char *)password, strlen(password), - &hashed_password, &len); + &hashed_sol_password, &len); char hashed_hex_pwd[256] = { (char) NULL }; - to_hexadecimal (hashed_hex_pwd, hashed_password, len); + to_hexadecimal (hashed_hex_pwd, hashed_sol_password, len); - if (strcmp (p->hashed_password, hashed_hex_pwd) == 0) + if (strcmp (p->hashed_solution_password, hashed_hex_pwd) == 0) return true; return false; } -/* Set or reset password for puzzle */ -void set_puzzle_password (Puzzle *p, const char *password) + +/* verify master password */ +bool verify_master_password (Puzzle *p, const char* password) +{ + /* no password set */ + if (strcmp (p->hashed_master_password, "\0") == 0) + return true; + + /* hash the user input password and compare it with the stored password */ + unsigned char* hashed_mas_password; + unsigned int len; + digest_message ((const unsigned char *)password, strlen(password), + &hashed_mas_password, &len); + char hashed_hex_pwd[256] = { (char) NULL }; + to_hexadecimal (hashed_hex_pwd, hashed_mas_password, len); + + if (strcmp (p->hashed_master_password, hashed_hex_pwd) == 0) + return true; + + return false; +} + +/* Set or reset solution password for puzzle */ +void set_solution_password (Puzzle *p, const char *password) { /* if it is a null string, reset the password */ if (strcmp (password, "\0") == 0) + strcpy (p->hashed_solution_password, "\0"); + else { - strcpy (p->hashed_password, "\0"); - strcpy (p->salt, "\0"); + + unsigned char* hashedpwd; + unsigned int len; + digest_message ((const unsigned char *)password, strlen(password), + &hashedpwd, &len); + /* the hashedpwd contains binary data - we will convert it to + hexadecimal data and store in file */ + + to_hexadecimal (p->hashed_solution_password, hashedpwd, len); } +} + +/* Set or reset master password for puzzle */ +void set_master_password (Puzzle *p, const char *password) +{ + /* if it is a null string, reset the password */ + if (strcmp (password, "\0") == 0) + strcpy (p->hashed_master_password, "\0"); else { @@ -169,11 +208,7 @@ void set_puzzle_password (Puzzle *p, const char *password) /* the hashedpwd contains binary data - we will convert it to hexadecimal data and store in file */ - to_hexadecimal (p->hashed_password, hashedpwd, len); - printf ("%s\n", p->hashed_password); - - strcpy (p->salt, "\0"); - + to_hexadecimal (p->hashed_master_password, hashedpwd, len); } } @@ -465,8 +500,8 @@ void init_puzzle (Puzzle *p, int grid_size) strcpy (p->clue_down[i][j], ""); } } - strcpy (p->hashed_password, "\0"); - strcpy (p->salt, "\0"); + strcpy (p->hashed_master_password, "\0"); + strcpy (p->hashed_solution_password, "\0"); } @@ -485,9 +520,9 @@ void save_puzzle (Puzzle *puzzle, const char* file) { /* whether grid is frozen or not */ fprintf (outfile, "%d\n", puzzle->grid_frozen); /* the hashed password */ - fprintf (outfile, "%s\n", puzzle->hashed_password); - /* the salt */ - fprintf (outfile, "%s\n", puzzle->salt); + fprintf (outfile, "%s\n", puzzle->hashed_master_password); + /* the hashed_solution_password */ + fprintf (outfile, "%s\n", puzzle->hashed_solution_password); /* First output the grid characters columns/rows */ for (int i = 0; i < puzzle->grid_size; i ++) @@ -616,14 +651,14 @@ Puzzle load_puzzle (const char* file) { p.grid_frozen = atoi (line) == 0 ? false : true ; fgets (line, MAX_CLUE_LENGTH + 10, infile); if (strlen (line) != 1) - strcpy (p.hashed_password, strtok (line, "\n")); + strcpy (p.hashed_master_password, strtok (line, "\n")); else - strcpy (p.hashed_password, "\0"); + strcpy (p.hashed_master_password, "\0"); fgets (line, MAX_CLUE_LENGTH + 10, infile); if (strlen (line) != 1) - strcpy (p.salt, strtok (line, "\n")); + strcpy (p.hashed_solution_password, strtok (line, "\n")); else - strcpy (p.salt, "\0"); + strcpy (p.hashed_solution_password, "\0"); /* read each character of the grid */ for (int i = 0; i < p.grid_size; i ++ ) diff --git a/wordblox_player.c b/wordblox_player.c index 605d9f5..d1f0929 100644 --- a/wordblox_player.c +++ b/wordblox_player.c @@ -466,8 +466,8 @@ gboolean on_puzzle_area_draw (GtkWidget *widget, cairo_t *cr, gpointer data) /* slot for reveal solution menu */ void on_menu_reveal_solution_activate (GtkMenuItem *item, GtkDrawingArea *area) { - /* if puzzle is password protected ask for the password */ - if (strlen (app_data.puzzle.hashed_password) > 0) + /* if puzzle solution is password protected ask for the password */ + if (strlen (app_data.puzzle.hashed_solution_password) > 0) { GtkBuilder *builder; builder = gtk_builder_new (); @@ -504,7 +504,7 @@ void on_menu_reveal_solution_activate (GtkMenuItem *item, GtkDrawingArea *area) const gchar *user_pwd = gtk_entry_get_text (GTK_ENTRY(password_text)); /* if password is correct */ - if (verify_password (&app_data.puzzle, user_pwd) == true) + if (verify_solution_password (&app_data.puzzle, user_pwd) == true) app_data.solution_revealed = true; /* password is incorrect */ else @@ -534,6 +534,12 @@ void on_menu_reveal_solution_activate (GtkMenuItem *item, GtkDrawingArea *area) } +/* slot for load grid state menu */ +void on_menu_load_grid_state_activate (GtkMenuItem *item, gpointer *data) +{ + /* TODO */ +} + /* slot for save grid state menu */ void on_menu_save_grid_state_activate (GtkMenuItem *item, gpointer *data) { diff --git a/wordblox_player.glade b/wordblox_player.glade index 7142360..19d8fdd 100644 --- a/wordblox_player.glade +++ b/wordblox_player.glade @@ -56,27 +56,50 @@ - + True False - _Save Grid State... + + + + + True + False + E_xit True - + + + + + + + + True + False + _Grid + True + + + True + False - + True False + _Save Grid State... + True + - + True False - E_xit + _Load Grid State... True - + -- 2.20.1