password.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. /* Code to save and retrieve password info from an open file and to
  22. derive an xor code from the current password. */
  23. /* Also contains password checking and changing code/dialogs. */
  24. #include "helpsys.h"
  25. #include "graphics.h"
  26. #include "error.h"
  27. #include "data.h"
  28. #include "password.h"
  29. #include <stdio.h>
  30. #include "string.h"
  31. #include "window.h"
  32. #include "intake.h"
  33. /* Note that all comparisons between stored and entered passwords should
  34. not be case sensitive. The stored version can have any mixture of
  35. upper and lower- it won't affect the comparison any. It WILL affect the
  36. XOR code, but since the upper/lower is saved also it doesn't matter. */
  37. char far magic_code[16]="æRëòmMJ·‡²’ˆÞ‘$";
  38. char far work_area[16];
  39. //Write password info to an open file
  40. void write_password(FILE *fp) {
  41. int t1;
  42. //First write code for protection mode
  43. fputc(protection_method,fp);
  44. //If it was 0, we're done!
  45. if(!protection_method) return;
  46. //Otherwise, let's fiddle with the 15 byte password and output
  47. str_cpy(work_area,magic_code);
  48. for(t1=0;t1<15;t1++)
  49. work_area[t1]^=(password[t1]^0x8D)+0x12+protection_method;
  50. fwrite(work_area,1,15,fp);
  51. //Done!
  52. }
  53. //Read password info from an open file
  54. void read_password(FILE *fp) {
  55. int t1;
  56. //First get code for protection mode
  57. protection_method=fgetc(fp);
  58. //If it was 0, we're done!
  59. if(!protection_method) {
  60. password[0]=0;
  61. return;
  62. }
  63. //Otherwise, let's read the 15 byte code and fiddle for the password
  64. fread(work_area,1,15,fp);
  65. for(t1=0;t1<15;t1++) {
  66. work_area[t1]^=magic_code[t1];
  67. work_area[t1]-=0x12+protection_method;
  68. work_area[t1]^=0x8D;
  69. }
  70. str_cpy(password,work_area);
  71. //Done!
  72. }
  73. //Get xor code for the current password
  74. unsigned char get_pw_xor_code(void) {
  75. int work=85;//Start with 85... (01010101)
  76. int t1;
  77. if(protection_method==0) return 0;
  78. //Clear pw after first null
  79. for(t1=str_len(password);t1<16;t1++)
  80. password[t1]=0;
  81. for(t1=0;t1<15;t1++) {
  82. //For each byte, roll once to the left and xor in pw byte if it
  83. //is an odd character, or add in pw byte if it is an even character.
  84. work<<=1;
  85. if(work>255) work^=257;//Wraparound from roll
  86. if(t1&1) {
  87. work+=password[t1];//Add (even byte)
  88. if(work>255) work^=257;//Wraparound from add
  89. }
  90. else work^=password[t1];//XOR (odd byte);
  91. }
  92. //To factor in protection method, add it in and roll one last time
  93. work+=protection_method;
  94. if(work>255) work^=257;
  95. work<<=1;
  96. if(work>255) work^=257;
  97. //Can't be 0-
  98. if(work==0) work=86;//(01010110)
  99. //Done!
  100. return (unsigned char)work;
  101. }
  102. //Checks an inputted password against the current password. Gives error
  103. //and returns non-0 if wrong.
  104. char check_pw(void) {
  105. char temp[16]="";
  106. if(protection_method==0) return 0;
  107. if(password[0]==0) return 0;
  108. set_context(95);
  109. retry:
  110. save_screen(current_pg_seg);
  111. draw_window_box(16,12,44,14,current_pg_seg,143,128,135);
  112. write_string("Password:",18,13,143,current_pg_seg);
  113. if(intake(temp,15,28,13,current_pg_seg,142,1,0,1)==27) {
  114. restore_screen(current_pg_seg);
  115. pop_context();
  116. return -1;
  117. }
  118. restore_screen(current_pg_seg);
  119. if(str_cmp(temp,password)) {
  120. //Error
  121. if(error("Invalid password",0,26,current_pg_seg,0x1001)==2)
  122. goto retry;//Chose RETRY.
  123. pop_context();
  124. return -1;
  125. }
  126. //Correct.
  127. pop_context();
  128. return 0;
  129. }
  130. //After checking password if one is present, we allow editing of the
  131. //password and protection method.
  132. //--------------------------------------
  133. //
  134. // ( ) No protection
  135. // ( ) No-save protection (anti-ripoff)
  136. // ( ) No-edit protection
  137. // ( ) No-play protection
  138. //
  139. // Password: ***************_
  140. //
  141. // _OK_ _Cancel_
  142. //
  143. //--------------------------------------
  144. char pdi_types[4]={ DE_RADIO,DE_INPUT,DE_BUTTON,DE_BUTTON };
  145. char pdi_xs[4]={ 2,2,7,20 };
  146. char pdi_ys[4]={ 2,7,9,9 };
  147. char far *pdi_strs[4]={ "No protection\nNo-save protection (anti-ripoff)\n\
  148. No-edit protection\nNo-play protection","Password: ","OK","Cancel" };
  149. int pdi_p1s[4]={ 4,15,0,-1 };
  150. int pdi_p2s[2]={ 32,0 };
  151. void far *pdi_storage[2]={ NULL,NULL };
  152. dialog pdi={
  153. 20,5,59,16,"Password protection",4,
  154. pdi_types,
  155. pdi_xs,
  156. pdi_ys,
  157. pdi_strs,
  158. pdi_p1s,
  159. pdi_p2s,
  160. pdi_storage,0 };
  161. void password_dialog(void) {
  162. int p_m=protection_method;
  163. char temp[16];
  164. if(check_pw()) return;
  165. set_context(95);
  166. pdi_storage[0]=&p_m;
  167. pdi_storage[1]=temp;
  168. str_cpy(temp,password);
  169. if(run_dialog(&pdi,current_pg_seg)) {
  170. pop_context();
  171. return;//No changy
  172. }
  173. if(temp[0]==0) p_m=NO_PROTECTION;//No protection w/o a password!
  174. str_cpy(password,temp);
  175. protection_method=p_m;
  176. pop_context();
  177. return;
  178. }