Separate solution password implemented
authorHarishankar <v.harishankar@gmail.com>
Fri, 8 May 2020 06:18:37 +0000 (11:48 +0530)
committerHarishankar <v.harishankar@gmail.com>
Fri, 8 May 2020 06:18:37 +0000 (11:48 +0530)
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
wordblox.c
wordblox.h
wordblox_player.c
wordblox_player.glade

index d5f4734..d80bc1a 100644 (file)
 #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
index 0cbb804..f30c039 100644 (file)
@@ -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
                {
index 1925573..a355a09 100644 (file)
@@ -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 ++ )
index 605d9f5..d1f0929 100644 (file)
@@ -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)
 {
index 7142360..19d8fdd 100644 (file)
                       </object>
                     </child>
                     <child>
-                      <object class="GtkMenuItem" id="menu_save_grid_state">
+                      <object class="GtkSeparatorMenuItem">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">_Save Grid State...</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkMenuItem" id="menu_exit">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">E_xit</property>
                         <property name="use_underline">True</property>
-                        <signal name="activate" handler="on_menu_save_grid_state_activate" swapped="no"/>
+                        <signal name="activate" handler="on_menu_exit_activate" swapped="no"/>
                       </object>
                     </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkMenuItem" id="menu_grid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">_Grid</property>
+                <property name="use_underline">True</property>
+                <child type="submenu">
+                  <object class="GtkMenu">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <child>
-                      <object class="GtkSeparatorMenuItem">
+                      <object class="GtkMenuItem" id="menu_save_grid_state">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Save Grid State...</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_menu_save_grid_state_activate" swapped="no"/>
                       </object>
                     </child>
                     <child>
-                      <object class="GtkMenuItem" id="menu_exit">
+                      <object class="GtkMenuItem" id="menu_load_grid_state">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">E_xit</property>
+                        <property name="label" translatable="yes">_Load Grid State...</property>
                         <property name="use_underline">True</property>
-                        <signal name="activate" handler="on_menu_exit_activate" swapped="no"/>
+                        <signal name="activate" handler="on_menu_load_grid_state_activate" swapped="no"/>
                       </object>
                     </child>
                   </object>