You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

228 lines
5.6 KiB

  1. /*
  2. * neercs console-based window manager
  3. * Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
  4. * 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
  5. * All Rights Reserved
  6. *
  7. * This program is free software. It comes without any warranty, to
  8. * the extent permitted by applicable law. You can redistribute it
  9. * and/or modify it under the terms of the Do What The Fuck You Want
  10. * To Public License, Version 2, as published by Sam Hocevar. See
  11. * http://sam.zoy.org/wtfpl/COPYING for more details.
  12. */
  13. #if defined HAVE_CONFIG_H
  14. # include "config.h"
  15. #endif
  16. #if !defined _WIN32
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <caca.h>
  21. #include <time.h>
  22. #include <sys/wait.h>
  23. #include <sys/types.h>
  24. #if defined USE_LOCK
  25. #if defined HAVE_PAM_PAM_MISC_H
  26. # include <pam/pam_appl.h>
  27. # include <pam/pam_misc.h>
  28. #else
  29. # include <security/pam_appl.h>
  30. # include <security/pam_misc.h>
  31. #endif
  32. # include <pwd.h>
  33. #endif
  34. #include "neercs.h"
  35. #if defined USE_LOCK
  36. static int convpam(int num_msg, const struct pam_message **msg,
  37. struct pam_response **resp, void *appdata_ptr);
  38. #endif
  39. int update_lock(int c, struct screen_list *screen_list)
  40. {
  41. int refresh = 0;
  42. #if defined USE_LOCK
  43. if (!screen_list->lock.locked)
  44. return 0;
  45. if (c == 0x08) // BACKSPACE
  46. {
  47. if (screen_list->lock.lock_offset)
  48. {
  49. screen_list->lock.lockpass[screen_list->lock.lock_offset - 1] = 0;
  50. screen_list->lock.lock_offset--;
  51. }
  52. }
  53. else if (c == 0x0d) // RETURN
  54. {
  55. memset(screen_list->lock.lockmsg, 0, 1024);
  56. if (validate_lock(screen_list, getenv("USER"), screen_list->lock.lockpass))
  57. {
  58. memset(screen_list->lock.lockpass, 0, 1024);
  59. screen_list->lock.locked = 0;
  60. screen_list->lock.lock_offset = 0;
  61. refresh = 1;
  62. }
  63. else
  64. {
  65. memset(screen_list->lock.lockpass, 0, 1024);
  66. screen_list->lock.lock_offset = 0;
  67. refresh = 1;
  68. }
  69. }
  70. else
  71. {
  72. if (screen_list->lock.lock_offset < 1023)
  73. {
  74. screen_list->lock.lockpass[screen_list->lock.lock_offset++] = c;
  75. screen_list->lock.lockpass[screen_list->lock.lock_offset] = 0;
  76. }
  77. }
  78. #endif
  79. return refresh;
  80. }
  81. void draw_lock(struct screen_list *screen_list)
  82. {
  83. #if defined USE_LOCK
  84. unsigned int i;
  85. char buffer[1024];
  86. caca_canvas_t *cv = screen_list->cv;
  87. gethostname(buffer, sizeof(buffer) - 1);
  88. int w = 65, h = 20;
  89. int x = (caca_get_canvas_width(cv) - w) / 2;
  90. int y = (caca_get_canvas_height(cv) - h) / 2;
  91. caca_set_color_ansi(cv, CACA_BLUE, CACA_BLUE);
  92. caca_fill_box(cv, x, y, w, h, '#');
  93. caca_set_color_ansi(cv, CACA_DEFAULT, CACA_BLUE);
  94. caca_draw_cp437_box(cv, x, y, w, h);
  95. x += 2;
  96. y++;
  97. caca_printf(cv,
  98. (caca_get_canvas_width(cv) -
  99. strlen(PACKAGE_STRING " locked")) / 2, y - 1,
  100. PACKAGE_STRING " locked");
  101. caca_printf(cv, x, y++, "Please type in your password for %s@%s :",
  102. getenv("USER"), buffer);
  103. y += 2;
  104. x = (caca_get_canvas_width(cv) / 2) -
  105. ((strlen(screen_list->lock.lockpass) / 2) + strlen("Password : "));
  106. caca_printf(cv, x, y, "Password : ");
  107. x += strlen("Password : ");
  108. for (i = 0; i < strlen(screen_list->lock.lockpass); i++)
  109. {
  110. caca_put_str(cv, x, y, "*");
  111. x++;
  112. }
  113. if (strlen(screen_list->lock.lockmsg))
  114. {
  115. x = ((caca_get_canvas_width(cv) - w) / 2) +
  116. (strlen(screen_list->lock.lockmsg));
  117. y += 2;
  118. caca_set_color_ansi(cv, CACA_RED, CACA_BLUE);
  119. caca_printf(cv, x, y, "Error : %s", screen_list->lock.lockmsg);
  120. }
  121. #endif
  122. }
  123. #if defined USE_LOCK
  124. /* FIXME, handle this without assuming this is a password auth */
  125. static int convpam(int num_msg, const struct pam_message **msg,
  126. struct pam_response **resp, void *appdata_ptr)
  127. {
  128. struct pam_response *aresp;
  129. int i;
  130. aresp = calloc(num_msg, sizeof(*aresp));
  131. for (i = 0; i < num_msg; ++i)
  132. {
  133. switch (msg[i]->msg_style)
  134. {
  135. case PAM_PROMPT_ECHO_ON:
  136. case PAM_PROMPT_ECHO_OFF:
  137. aresp[i].resp = strdup(appdata_ptr);
  138. aresp[i].resp_retcode = 0;
  139. break;
  140. case PAM_ERROR_MSG:
  141. break;
  142. default:
  143. printf("Unknow message type from PAM\n");
  144. break;
  145. }
  146. }
  147. *resp = aresp;
  148. return (PAM_SUCCESS);
  149. }
  150. #endif
  151. int validate_lock(struct screen_list *screen_list, char *user, char *pass)
  152. {
  153. #if USE_LOCK
  154. int ret;
  155. pam_handle_t *pamh = NULL;
  156. char buffer[100];
  157. const char *service = "neercs";
  158. struct pam_conv conv = {
  159. convpam,
  160. pass,
  161. };
  162. ret = pam_start(service, user, &conv, &pamh);
  163. if (ret != PAM_SUCCESS)
  164. return 0;
  165. pam_set_item(pamh, PAM_RUSER, user);
  166. ret = gethostname(buffer, sizeof(buffer) - 1);
  167. if (ret)
  168. {
  169. perror("failed to look up hostname");
  170. ret = pam_end(pamh, PAM_ABORT);
  171. sprintf(screen_list->lock.lockmsg, "Can't get hostname");
  172. pam_end(pamh, PAM_SUCCESS);
  173. return 0;
  174. }
  175. ret = pam_set_item(pamh, PAM_RHOST, buffer);
  176. if (ret != PAM_SUCCESS)
  177. {
  178. sprintf(screen_list->lock.lockmsg, "Can't set hostname");
  179. pam_end(pamh, PAM_SUCCESS);
  180. return 0;
  181. }
  182. ret = pam_authenticate(pamh, 0);
  183. if (ret != PAM_SUCCESS)
  184. {
  185. sprintf(screen_list->lock.lockmsg, "Can't authenticate");
  186. pam_end(pamh, PAM_SUCCESS);
  187. return 0;
  188. }
  189. ret = pam_end(pamh, PAM_SUCCESS);
  190. #endif
  191. return 1;
  192. }
  193. #endif