input.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /* SLiM - Simple Login Manager
  2. Copyright (C) 1997, 1998 Per Liden
  3. Copyright (C) 2004-05 Simone Rota <sip@varlock.com>
  4. Copyright (C) 2004-05 Johannes Winkelmann <jw@tks6.net>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. */
  10. #include "input.h"
  11. #include <cstdlib>
  12. Input::Input(Cfg* c) {
  13. NameBuffer[0] = '\0';
  14. PasswdBuffer[0] = '\0';
  15. HiddenPasswdBuffer[0] = '\0';
  16. Field = GET_NAME;
  17. Action = WAIT;
  18. cfg = c;
  19. }
  20. Input::~Input() {
  21. // Does nothing
  22. }
  23. char Input::Key(char ascii, KeySym keysym, bool singleInputMode) {
  24. char tmp = 0;
  25. // Take a screenshot
  26. if(keysym == XK_F11) {
  27. system(cfg->getOption("screenshot_cmd").c_str());
  28. }
  29. if (!singleInputMode && (keysym == XK_Tab || keysym == XK_ISO_Left_Tab)) {
  30. if (Field == GET_NAME) {
  31. // Move to next field
  32. Field = GET_PASSWD;
  33. } else {
  34. Field = GET_NAME;
  35. }
  36. } else if(keysym == XK_Return) {
  37. if(!strcmp(NameBuffer, ""))
  38. return tmp;
  39. // Check for special command (console, halt, reboot, exit)
  40. int special = SpecialWanted();
  41. if(Field == GET_NAME) {
  42. // Move to next field
  43. Field = GET_PASSWD;
  44. // Check for special command (console, exit)
  45. if(special == CONSOLE || special == EXIT)
  46. Action = special;
  47. } else {
  48. // Check for special command (halt, reboot)
  49. if(special == REBOOT || special == HALT || special == SUSPEND)
  50. Action = SpecialCorrect(special);
  51. // Regular login
  52. else {
  53. if(Correct())
  54. Action = LOGIN;
  55. else
  56. Action = FAIL;
  57. }
  58. }
  59. } else if(keysym == XK_Delete || keysym == XK_BackSpace)
  60. tmp = DeleteLast();
  61. else if(isprint(ascii))
  62. if(keysym < XK_Shift_L || keysym > XK_Hyper_R)
  63. Add(ascii);
  64. return tmp;
  65. }
  66. int Input::GetAction() {
  67. return Action;
  68. }
  69. int Input::GetField() {
  70. return Field;
  71. }
  72. char* Input::GetName() {
  73. return NameBuffer;
  74. }
  75. char* Input::GetHiddenPasswd() {
  76. return HiddenPasswdBuffer;
  77. }
  78. struct passwd* Input::GetPasswdStruct() {
  79. struct passwd* pw = getpwnam(NameBuffer);
  80. endpwent();
  81. if (pw->pw_shell[0] == '\0') {
  82. setusershell();
  83. pw->pw_shell = getusershell();
  84. endusershell();
  85. }
  86. return pw;
  87. }
  88. void Input::Add(char ascii) {
  89. char tmp[2];
  90. tmp[0] = ascii;
  91. tmp[1] = '\0';
  92. switch(Field) {
  93. case GET_NAME:
  94. if(strlen(NameBuffer) < INPUT_MAXLENGTH_NAME-1)
  95. strcat(NameBuffer, tmp);
  96. break;
  97. case GET_PASSWD:
  98. if(strlen(PasswdBuffer) < INPUT_MAXLENGTH_PASSWD-1) {
  99. strcat(PasswdBuffer, tmp);
  100. tmp[0] = '*';
  101. strcat(HiddenPasswdBuffer, tmp);
  102. }
  103. break;
  104. }
  105. }
  106. char Input::DeleteLast() {
  107. char tmp = 0;
  108. int len = 0;
  109. switch(Field) {
  110. case GET_NAME:
  111. len = strlen(NameBuffer) - 1;
  112. tmp = NameBuffer[len];
  113. NameBuffer[len] = '\0';
  114. break;
  115. case GET_PASSWD:
  116. len = strlen(PasswdBuffer) - 1;
  117. tmp = '*';
  118. PasswdBuffer[len] = '\0';
  119. HiddenPasswdBuffer[len] = '\0';
  120. break;
  121. }
  122. return tmp;
  123. }
  124. void Input::Reset() {
  125. ResetName();
  126. ResetPassword();
  127. Field = GET_NAME;
  128. Action = WAIT;
  129. }
  130. void Input::ResetName() {
  131. NameBuffer[0] = '\0';
  132. Action = WAIT;
  133. }
  134. void Input::ResetPassword() {
  135. PasswdBuffer[0] = '\0';
  136. HiddenPasswdBuffer[0] = '\0';
  137. Action = WAIT;
  138. }
  139. // used for automatically fill name at startup
  140. void Input::SetName(string name) {
  141. NameBuffer[0] = '\0';
  142. if(name.size() < INPUT_MAXLENGTH_NAME) {
  143. strcat(NameBuffer, name.c_str());
  144. }
  145. Field = GET_PASSWD;
  146. Action = WAIT;
  147. }
  148. int Input::Correct() {
  149. char *unencrypted, *encrypted, *correct;
  150. struct passwd *pw;
  151. pw = getpwnam(NameBuffer);
  152. endpwent();
  153. if(pw == 0)
  154. return 0;
  155. #ifdef HAVE_SHADOW
  156. struct spwd *sp = getspnam(pw->pw_name);
  157. endspent();
  158. if(sp)
  159. correct = sp->sp_pwdp;
  160. else
  161. #endif
  162. correct = pw->pw_passwd;
  163. if(correct == 0 || correct[0] == '\0')
  164. return 1;
  165. unencrypted = PasswdBuffer;
  166. encrypted = crypt(unencrypted, correct);
  167. memset(unencrypted, 0, strlen (unencrypted));
  168. return (strcmp(encrypted, correct) == 0);
  169. }
  170. int Input::SpecialWanted() {
  171. int result;
  172. if(!strcmp(NameBuffer, CONSOLE_STR))
  173. result = CONSOLE;
  174. else if(!strcmp(NameBuffer, HALT_STR))
  175. result = HALT;
  176. else if(!strcmp(NameBuffer, REBOOT_STR))
  177. result = REBOOT;
  178. else if(!strcmp(NameBuffer, SUSPEND_STR))
  179. result = SUSPEND;
  180. else if(!strcmp(NameBuffer, EXIT_STR))
  181. result = EXIT;
  182. else
  183. result = 0;
  184. return result;
  185. }
  186. int Input::SpecialCorrect(int special) {
  187. int result, c;
  188. char tmp[INPUT_MAXLENGTH_NAME];
  189. strcpy(tmp, NameBuffer);
  190. strcpy(NameBuffer, "root");
  191. c = Correct();
  192. strcpy(NameBuffer, tmp);
  193. if(c)
  194. result = special;
  195. else
  196. result = FAIL;
  197. return result;
  198. }