Modifications to PasswordVault.cpp
Produced: 5/14/2009 10:33:36 PM
   
Mode:  All, Ignoring Unimportant  
Left file: C:\project_repository\password_vault_cpp_source\password_vault_cpp_unobfuscated\PasswordVault.cpp  
Right file: C:\project_repository\password_vault_cpp_source\password_vault_cpp_obfuscated\PasswordVault.cpp  
1 1 /*****************************************************************
2 2 * Copyright (c):   2009, All Rights Reserved.
3 3 * Project:         Software Reverse Engineering (SRE) Education
4 4 *                  Password Vault Native C/C++ Application
5 5 * Programmer:      Teodoro Cipresso, San Jose State University
6 6 *                  teodoro@reversingproject.info
7 7 ******************************************************************
8 8  
9 9 This file is part of Password Vault.
10 10  
11 11 Password Vault is free software: you can redistribute it and/or modify
12 12 it under the terms of the GNU General Public License as published by
13 13 the Free Software Foundation, either version 3 of the License, or
14 14 (at your option) any later version.
15 15  
16 16 Password Vault is distributed in the hope that it will be useful,
17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 19 GNU General Public License for more details.
20 20  
21 21 You should have received a copy of the GNU General Public License
22 22 along with Password Vault.  If not, see <http://www.gnu.org/licenses/>.
23 23  
24 24 */
25    
26 25 #include "passwordvault.h"
27 26  
28 27 using namespace std;
29 28  
30 29 /**
31 30 * Main entry point entry point for the Password Vault program.
32 31 * The program expects no command line arguments.  The program
33 32 * begins by prompting for the username and password.  The
34 33 * username + ".dat" is used to locate the password vault file
35 34 * for the user in the local directory.  If no file with that
36 35 * name is found, the program assumes a new vault is being
37 36 * created.
38 37 */
39 38 int main(int argv, char *argc[])
40 39 {
41 40   // PasswordVault class implements the program loop
42 41   PasswordVault vault;
43 42   vault.run();
44 43  
45 44   // normal termination
46 45   return 0;
47 46 }
48 47  
49 48 /**
50 49 * Default constructor
51 50 */
52 51 PasswordVault::PasswordVault()
53 52 {
54 53  
55 54 }
56 55  
57 56 /**
58 57 * Default destructor
59 58 */
60 59 PasswordVault::~PasswordVault()
61 60 {
62 61  
63 62 }
64 63  
65 64 /**
66 65 * This method implements the main program loop
67 66 */
68 67 void PasswordVault::run()
69 68 {
70 69  
71 70   // prompt for username and password for existing/new vault
72 71   doGetUserNameAndPassword();
73 72  
74 73   // try to open password store for existing vault
75 74   passwordStore.loadRecordsFromDisk();
76 75  
77 76   // main program loop that services user selections from the option menu
78 77   bool exitProgram = false;
79 78   while (!exitProgram)
80 79   {
81 80     int selection = doGetUserMenuSelection();
82 81     switch (selection)
83 82     {
84 83     case PasswordVaultConsoleUtil::DISPLAY_PASSWORD_RECORDS:
85 84       doDisplayRecords();
86 85       break;
87 86     case PasswordVaultConsoleUtil::CREATE_PASSWORD_RECORD:
88 87       doCreateNewRecord();
89 88       break;
90 89     case PasswordVaultConsoleUtil::EDIT_PASSWORD_RECORD:
91 90       doEditRecord();
92 91       break;
93 92     case PasswordVaultConsoleUtil::DELETE_PASSWORD_RECORD:
94 93       doDeleteRecord();
95 94       break;
96 95     case PasswordVaultConsoleUtil::CHANGE_VAULT_PASSWORD:
97 96       doChangeVaultPassword();
98 97       break;
99 98     case PasswordVaultConsoleUtil::QUIT_PROGRAM:
100 99       exitProgram = true;
101 100       break;
102 101     default:
103 102       PasswordVaultConsoleUtil::DisplayMessage(__invalidMenuOption, NULL, PasswordVaultConsoleUtil::ERROR_MESSAGE);
104 103     }
105 104   }
106 105  
107 106   // try to save password vault records to file
108 107   passwordStore.saveRecordsToDisk();
109 108  
110 109 }
111 110  
112 111 /**
113 112 * This method implements the interactive prompts for username and password
114 113 */
115 114 void PasswordVault::doGetUserNameAndPassword()
116 115 {
117 116  
118 117   // display program identification
119 118   PasswordVaultConsoleUtil::DisplayProgramBanner();
120 119  
121 120   // prompt for vault username
122 121   string username;
123 122   bool userNameSet = false;
124 123   do
125 124   {
126 125     PasswordVaultConsoleUtil::DisplayMessage(__specifyVaultUsername, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
127 126     getline(cin, username);
128 127     userNameSet = (passwordStore.setVaultUserName(username) == 0);
129 128   }
130 129   while (!userNameSet);
131 130  
132 131   // prompt for vault password
133 132   string password;
134 133   bool passwordSet = false;
135 134   do
136 135   {
137 136     PasswordVaultConsoleUtil::DisplayMessage(__specifyVaultPassword, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
138 137     getline(cin, password);
139 138     passwordSet = (passwordStore.setVaultPassword(password) == 0);
140 139   }
141 140   while (!passwordSet);
142 141  
143 142 }
144 143  
145 144 /**
146 145 * This method implements an interactive prompt for the options menu
147 146 */
148 147 int PasswordVault::doGetUserMenuSelection()
149 148 {
150 149  
151 150   // display program indentification
152 151   PasswordVaultConsoleUtil::DisplayProgramBanner();
153 152  
154 153   // display program   cout << plainText; options menu
155 154   PasswordVaultConsoleUtil::DisplayProgramMenu();
156 155  
157 156   // prompt for option selection
158 157   int selectionNum = 0;
159 158   do
160 159   {
161 160     string selection;
162 161     PasswordVaultConsoleUtil::DisplayMessage(__specifyOptionNumber, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
163 162     getline(cin, selection);
164 163     selectionNum = atoi(selection.c_str());
165 164   }
166 165   while (selectionNum == 0);
167 166  
168 167   // return option selection to caller
169 168   return selectionNum;
170 169  
171 170 }
172 171  
  172 #ifdef TRIALVERSION
173 173 /**
  174 * This method implements recursive and non-recursive control flow obfuscation of the record limit check.
  175 * The call stack depth is grown by a random increase between 16 and 64.
  176 * The record limit is represented as function of the limit, 2^limit, to mask it from a reverse engineer.
  177 */
  178 bool PasswordVault::isRecordLimitReached()
  179 {
  180   srand(time(NULL));
  181  
  182   controlFlowAltRemain = max(16, abs(rand()) % 64);
  183  
  184   return isRecordLimitReached_0();
  185 }
  186  
  187 bool PasswordVault::isRecordLimitReached_0()
  188 {
  189   while (controlFlowAltRemain > 0)
  190   {
  191     controlFlowAltRemain--;
  192     isRecordLimitReached_0();
  193   }
  194  
  195   bool reached = (pow(2.0, (double)passwordStore.getRecords().size()) >= pow(2.0, 5.0));
  196  
  197   randCallSum = 0;
  198  
  199   switch (abs(rand()) % 3)
  200   {
  201   case 0:
  202     randCallSum += isRecordLimitReached_1();
  203     break;
  204   case 1:
  205     randCallSum += isRecordLimitReached_2();
  206     break;
  207   case 2:
  208     randCallSum += isRecordLimitReached_3();
  209     break;
  210   }
  211  
  212   return reached;
  213 }
  214  
  215 unsigned int PasswordVault::isRecordLimitReached_1()
  216 {
  217   return abs(rand());
  218 }
  219  
  220 unsigned int PasswordVault::isRecordLimitReached_2()
  221 {
  222   return abs(rand());
  223 }
  224  
  225 unsigned int PasswordVault::isRecordLimitReached_3()
  226 {
  227   return abs(rand());
  228 }
  229  
  230 #endif
  231  
  232 /**
174 233 * This method implements interactive prompts for adding a new record to the password vault.
175 234 */
176 235 void PasswordVault::doCreateNewRecord()
177 236 {
178 237  
179 238 #ifdef TRIALVERSION 
180 239   // Add limit on record count for reversing exercise
181     if (passwordStore.getRecords().size() >= TRIAL_RECORD_LIMIT)
  240   if (isRecordLimitReached())
182 241   {
183 242     PasswordVaultConsoleUtil::DisplayMessage(__recordLimitReached, NULL, PasswordVaultConsoleUtil::ERROR_MESSAGE);
184 243     return;
185 244   }
186 245 #endif
187 246  
188 247   // instantiate new record object
189 248   PasswordRecord newRecord;
190 249  
191 250   // tell user what menu option they selected
192     const char *insert = PasswordVaultConsoleUtil::GetMessageText(__createPasswordRecord);
193     PasswordVaultConsoleUtil::DisplayMessage(__selected, insert, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
  251   string insert; PasswordVaultConsoleUtil::GetMessageText(__createPasswordRecord, &insert);
  252   PasswordVaultConsoleUtil::DisplayMessage(__selected, insert.c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
194 253  
195 254   // prompt for record name with validation
196 255   string name;
197 256   bool loopName = true;
198 257   do
199 258   {
200 259     PasswordVaultConsoleUtil::DisplayMessage(__specifyName, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
201 260     getline(cin, name);
202 261     if (name.length() == 0)
203 262     {
204 263       PasswordVaultConsoleUtil::DisplayMessage(__recordNameIsBlank, NULL, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
205 264       return;
206 265     }
207 266     else
208 267     {
209 268       loopName = passwordStore.recordExists(name);
210 269       if (loopName)
211 270       {
212 271         PasswordVaultConsoleUtil::DisplayMessage(__recordNameAlreadyExists, name.c_str(), PasswordVaultConsoleUtil::ERROR_MESSAGE);
213 272       }
214 273       else
215 274       {
216 275         loopName = (newRecord.setName(name) == -1);
217 276       }
218 277     }
219 278   }
220 279   while (loopName);
221 280  
222 281   // prompt for record username with validation
223 282   string username;
224 283   do
225 284   {
226 285     PasswordVaultConsoleUtil::DisplayMessage(__specifyUsername, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
227 286     getline(cin, username);
228 287   }
229 288   while (newRecord.setUsername(username) == -1);
230 289  
231 290   // prompt for record password with validation
232 291   string password;
233 292   do
234 293   {
235 294     PasswordVaultConsoleUtil::DisplayMessage(__specifyPassword, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
236 295     getline(cin, password);
237 296   }
238 297   while (newRecord.setPassword(password) == -1);
239 298  
240 299   // prompt for record description with validation
241 300   string description;
242 301   do
243 302   {
244 303     PasswordVaultConsoleUtil::DisplayMessage(__specifyDescription, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
245 304     getline(cin, description);
246 305   }
247 306   while (newRecord.setDescription(description) == -1);
248 307  
249 308  
250 309   // add new record to password store (not written to disk yet)
251 310   passwordStore.addRecord(newRecord);
252 311  
253 312   // tell user that record creation was successful
254 313   PasswordVaultConsoleUtil::DisplayMessage(__recordCreated, NULL, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
255 314  
256 315 }
257 316  
258 317 /**
259 318 * This method generates a list of the password vault records to the console
260 319 */
261 320 void PasswordVault::doDisplayRecords()
262 321 {
263 322  
264 323   // tell user what menu option they selected
265     const char *insert = PasswordVaultConsoleUtil::GetMessageText(__displayPasswordRecords);
266     PasswordVaultConsoleUtil::DisplayMessage(__selected, insert, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
  324   string insert; PasswordVaultConsoleUtil::GetMessageText(__displayPasswordRecords, &insert);
  325   PasswordVaultConsoleUtil::DisplayMessage(__selected, insert.c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
267 326  
268 327   // loop through password records in vault and display each one
269 328   vector<PasswordRecord> records = passwordStore.getRecords();
270 329   vector<PasswordRecord>::iterator iter;
271 330   for (iter = records.begin(); iter != records.end(); iter++)
272 331   {
273 332     PasswordRecord record = *iter;
274 333     record.displayRecord();
275 334   }
276 335  
277 336   // tell the user if no records were found in the vault
278 337   if (records.size() == 0)
279 338   {
280 339     PasswordVaultConsoleUtil::DisplayMessage(__noRecordsExist, NULL, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
281 340   }
282 341  
283 342 }
284 343  
285 344 /**
286 345 * This method implements an interactive prompt for deleting a record from the vault.
287 346 * User is returned to the main menu if they specify a name of a record that doesn't exist.
288 347 */
289 348 void PasswordVault::doDeleteRecord()
290 349 {
291 350  
292 351   // tell user what menu they selected
293     const char *insert = PasswordVaultConsoleUtil::GetMessageText(__deletePasswordRecord);
294     PasswordVaultConsoleUtil::DisplayMessage(__selected, insert, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
  352   string insert; PasswordVaultConsoleUtil::GetMessageText(__deletePasswordRecord, &insert);
  353   PasswordVaultConsoleUtil::DisplayMessage(__selected, insert.c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
295 354  
296 355   // prompt for name of the record to delete from the store with validation.
297 356   string name;
298 357   PasswordVaultConsoleUtil::DisplayMessage(__specifyNameToDelete, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
299 358   getline(cin, name);
300 359   if (!passwordStore.recordExists(name))
301 360   {
302 361     PasswordVaultConsoleUtil::DisplayMessage(__recordNotFound, name.c_str(), PasswordVaultConsoleUtil::ERROR_MESSAGE);
303 362   }
304 363   else
305 364   {
306 365     passwordStore.deleteRecord(name);
307 366     PasswordVaultConsoleUtil::DisplayMessage(__recordDeleted, name.c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
308 367   }
309 368  
310 369 }
311 370  
312 371 /**
313 372 * This method implements interactive prompts for editing an existing password in the vault.
314 373 * If the user specifies a name of a vault record that doesn't exist, they are returned to the main menu.
315 374 */
316 375 void PasswordVault::doEditRecord()
317 376 {
318 377  
319 378   // tell user what menu option they selected
320     const char *insert = PasswordVaultConsoleUtil::GetMessageText(__editPasswordRecord);
321     PasswordVaultConsoleUtil::DisplayMessage(__selected, insert, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
  379   string insert; PasswordVaultConsoleUtil::GetMessageText(__editPasswordRecord, &insert);
  380   PasswordVaultConsoleUtil::DisplayMessage(__selected, insert.c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
322 381  
323 382   // prompt user for the name of the vault record to edit
324 383   string name;
325 384   PasswordVaultConsoleUtil::DisplayMessage(__specifyNameToEdit, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
326 385   getline(cin, name);
327 386   PasswordRecord *editRecord = passwordStore.getRecord(name);
328 387   if (editRecord == NULL)
329 388   {
330 389     PasswordVaultConsoleUtil::DisplayMessage(__recordNotFound, name.c_str(), PasswordVaultConsoleUtil::ERROR_MESSAGE);
331 390     return;
332 391   }
333 392   else
334 393   {
335 394     PasswordVaultConsoleUtil::DisplayMessage(__recordFound, editRecord->getName().c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
336 395     PasswordVaultConsoleUtil::DisplayMessage(__pressEnterToRetainVal, NULL, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
337 396   }
338 397  
339 398   // prompt user to edit the name of the record.  Pressing Enter alone will retain current value.
340 399   bool nameSet = false;
341 400   do
342 401   {
343 402     PasswordVaultConsoleUtil::DisplayMessage(__specifyNameEdit, editRecord->getName().c_str(), PasswordVaultConsoleUtil::PROMPT_MESSAGE);
344 403     getline(cin, name);
345 404     if (name.length() == 0)
346 405     {
347 406       nameSet = true;
348 407     }
349 408     else
350 409     {
351 410       nameSet = !(passwordStore.recordExists(name));
352 411       if (!nameSet)
353 412       {
354 413         PasswordVaultConsoleUtil::DisplayMessage(__recordNameAlreadyExists, name.c_str(), PasswordVaultConsoleUtil::ERROR_MESSAGE);
355 414       }
356 415       else
357 416       {
358 417         nameSet = (editRecord->setName(name) == 0);
359 418       }
360 419     }
361 420   }
362 421   while (!nameSet);
363 422  
364 423   // prompt user to edit username of the record.  Pressing enter alone will retain current value.
365 424   string username;
366 425   bool userSet = false;
367 426   do
368 427   {
369 428     PasswordVaultConsoleUtil::DisplayMessage(__specifyUsernameEdit, editRecord->getUsername().c_str(), PasswordVaultConsoleUtil::PROMPT_MESSAGE);
370 429     getline(cin, username);
371 430     if (username.length() == 0)
372 431     {
373 432       userSet = true;
374 433     }
375 434     else
376 435     {
377 436       userSet = (editRecord->setUsername(username) == 0);
378 437     }
379 438   }
380 439   while (!userSet);
381 440  
382 441   // prompt user to edit password of the record.  Pressing enter alone will retain current value.
383 442   string password;
384 443   bool passSet = false;
385 444   do
386 445   {
387 446     PasswordVaultConsoleUtil::DisplayMessage(__specifyPasswordEdit, editRecord->getPassword().c_str(), PasswordVaultConsoleUtil::PROMPT_MESSAGE);
388 447     getline(cin, password);
389 448     if (password.length() == 0)
390 449     {
391 450       passSet = true;
392 451     }
393 452     else
394 453     {
395 454       passSet = (editRecord->setPassword(password) == 0);
396 455     }
397 456   }
398 457   while (!passSet);
399 458  
400 459   // prompt user to edit description of the record.  Pressing enter alone will retain current value.
401 460   string description;
402 461   bool descSet = false;
403 462   do
404 463   {
405 464     PasswordVaultConsoleUtil::DisplayMessage(__specifyDescriptionEdit, editRecord->getDescription().c_str(), PasswordVaultConsoleUtil::PROMPT_MESSAGE);
406 465     getline(cin, description);
407 466     if (description.length() == 0)
408 467     {
409 468       descSet = true;
410 469     }
411 470     else
412 471     {
413 472       descSet = (editRecord->setDescription(description) == 0);
414 473     }
415 474   }
416 475   while (!descSet);
417 476  
418 477  
419 478   // tell user that the record was succesfully edited
420 479   PasswordVaultConsoleUtil::DisplayMessage(__recordEdited, NULL, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
421 480  
422 481 }
423 482  
424 483 /**
425 484 * This method implements
426 485 */
427 486 void PasswordVault::doChangeVaultPassword()
428 487 {
429 488  
430 489   // tell user what menu option they selected
431     const char *insert = PasswordVaultConsoleUtil::GetMessageText(__changeVaultPassword);
432     PasswordVaultConsoleUtil::DisplayMessage(__selected, insert, PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
  490   string insert; PasswordVaultConsoleUtil::GetMessageText(__changeVaultPassword, &insert);
  491   PasswordVaultConsoleUtil::DisplayMessage(__selected, insert.c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
433 492  
434 493   // prompt user for current password
435 494   string password;
436 495   bool currentPasswordVerified = false;
437 496   PasswordVaultConsoleUtil::DisplayMessage(__specifyVaultPassCurrent, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
438 497   getline(cin, password);
439 498   if (password.length() > 0)
440 499   {
441 500     string passwordHash;
442 501     cryptoWrapper.hashString(password.c_str(), &passwordHash);
443 502     if (passwordHash == passwordStore.getVaultPasswordHash())
444 503     {
445 504       currentPasswordVerified = true;
446 505     }
447 506   }
448 507   if (!currentPasswordVerified)
449 508   {
450 509     // tell user they provided an incorrect current password and that we need to exit for safety
451 510     PasswordVaultConsoleUtil::DisplayMessage(__incorrectPassOnChange, NULL, PasswordVaultConsoleUtil::ERROR_MESSAGE);
452 511     exit(1);
453 512   }
454 513   else
455 514   {
456 515     // prompt for new vault password
457 516     string password;
458 517     bool passwordSet = false;
459 518     do
460 519     {
461 520       PasswordVaultConsoleUtil::DisplayMessage(__specifyVaultPassNew, NULL, PasswordVaultConsoleUtil::PROMPT_MESSAGE);
462 521       getline(cin, password);
463 522       passwordSet = (passwordStore.setVaultPassword(password) == 0);
464 523     }
465 524     while (!passwordSet);
466 525   }
467 526  
468 527   // tell user that vault password change was successful
469 528   PasswordVaultConsoleUtil::DisplayMessage(__vaultPasswordChangeOK, passwordStore.getVaultUserName().c_str(), PasswordVaultConsoleUtil::INFORMATIONAL_MESSAGE);
470 529  
471 530 }
472 531  
473 532  
474 533