/cracklib-2.8.19/lib/fascist.c

# · C · 886 lines · 764 code · 92 blank · 30 comment · 76 complexity · 0a39ca007af600b9333a39663515b8c2 MD5 · raw file

  1. /*
  2. * This program is copyright Alec Muffett 1993, portions copyright other authors.
  3. * The authors disclaim all responsibility or liability with respect to it's usage
  4. * or its effect upon hardware or computer systems.
  5. */
  6. #include "config.h"
  7. #include <sys/types.h>
  8. #include <errno.h>
  9. #include <limits.h>
  10. #include <pwd.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #ifdef HAVE_UNISTD_H
  14. #include <unistd.h>
  15. #endif
  16. #if defined(HAVE_INTTYPES_H)
  17. #include <inttypes.h>
  18. #else
  19. #if defined(HAVE_STDINT_H)
  20. #include <stdint.h>
  21. #else
  22. typedef unsigned int uint32_t;
  23. typedef unsigned short uint16_t;
  24. #endif
  25. #endif
  26. #include "packer.h"
  27. #define ISSKIP(x) (isspace(x) || ispunct(x))
  28. #define MINDIFF 5
  29. #define MINLEN 6
  30. #undef DEBUG
  31. #undef DEBUG2
  32. extern char *Reverse(char *buf);
  33. extern char *Lowercase(char *buf);
  34. static char *r_destructors[] = {
  35. ":", /* noop - must do this to test raw word. */
  36. #ifdef DEBUG2
  37. (char *) 0,
  38. #endif
  39. "[", /* trimming leading/trailing junk */
  40. "]",
  41. "[[",
  42. "]]",
  43. "[[[",
  44. "]]]",
  45. "/?p@?p", /* purging out punctuation/symbols/junk */
  46. "/?s@?s",
  47. "/?X@?X",
  48. /* attempt reverse engineering of password strings */
  49. "/$s$s",
  50. "/$s$s/0s0o",
  51. "/$s$s/0s0o/2s2a",
  52. "/$s$s/0s0o/2s2a/3s3e",
  53. "/$s$s/0s0o/2s2a/3s3e/5s5s",
  54. "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i",
  55. "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l",
  56. "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i/4s4a",
  57. "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i/4s4h",
  58. "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l/4s4a",
  59. "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l/4s4h",
  60. "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4a",
  61. "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4h",
  62. "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4a",
  63. "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4h",
  64. "/$s$s/0s0o/2s2a/3s3e/1s1i",
  65. "/$s$s/0s0o/2s2a/3s3e/1s1l",
  66. "/$s$s/0s0o/2s2a/3s3e/1s1i/4s4a",
  67. "/$s$s/0s0o/2s2a/3s3e/1s1i/4s4h",
  68. "/$s$s/0s0o/2s2a/3s3e/1s1l/4s4a",
  69. "/$s$s/0s0o/2s2a/3s3e/1s1l/4s4h",
  70. "/$s$s/0s0o/2s2a/3s3e/4s4a",
  71. "/$s$s/0s0o/2s2a/3s3e/4s4h",
  72. "/$s$s/0s0o/2s2a/3s3e/4s4a",
  73. "/$s$s/0s0o/2s2a/3s3e/4s4h",
  74. "/$s$s/0s0o/2s2a/5s5s",
  75. "/$s$s/0s0o/2s2a/5s5s/1s1i",
  76. "/$s$s/0s0o/2s2a/5s5s/1s1l",
  77. "/$s$s/0s0o/2s2a/5s5s/1s1i/4s4a",
  78. "/$s$s/0s0o/2s2a/5s5s/1s1i/4s4h",
  79. "/$s$s/0s0o/2s2a/5s5s/1s1l/4s4a",
  80. "/$s$s/0s0o/2s2a/5s5s/1s1l/4s4h",
  81. "/$s$s/0s0o/2s2a/5s5s/4s4a",
  82. "/$s$s/0s0o/2s2a/5s5s/4s4h",
  83. "/$s$s/0s0o/2s2a/5s5s/4s4a",
  84. "/$s$s/0s0o/2s2a/5s5s/4s4h",
  85. "/$s$s/0s0o/2s2a/1s1i",
  86. "/$s$s/0s0o/2s2a/1s1l",
  87. "/$s$s/0s0o/2s2a/1s1i/4s4a",
  88. "/$s$s/0s0o/2s2a/1s1i/4s4h",
  89. "/$s$s/0s0o/2s2a/1s1l/4s4a",
  90. "/$s$s/0s0o/2s2a/1s1l/4s4h",
  91. "/$s$s/0s0o/2s2a/4s4a",
  92. "/$s$s/0s0o/2s2a/4s4h",
  93. "/$s$s/0s0o/2s2a/4s4a",
  94. "/$s$s/0s0o/2s2a/4s4h",
  95. "/$s$s/0s0o/3s3e",
  96. "/$s$s/0s0o/3s3e/5s5s",
  97. "/$s$s/0s0o/3s3e/5s5s/1s1i",
  98. "/$s$s/0s0o/3s3e/5s5s/1s1l",
  99. "/$s$s/0s0o/3s3e/5s5s/1s1i/4s4a",
  100. "/$s$s/0s0o/3s3e/5s5s/1s1i/4s4h",
  101. "/$s$s/0s0o/3s3e/5s5s/1s1l/4s4a",
  102. "/$s$s/0s0o/3s3e/5s5s/1s1l/4s4h",
  103. "/$s$s/0s0o/3s3e/5s5s/4s4a",
  104. "/$s$s/0s0o/3s3e/5s5s/4s4h",
  105. "/$s$s/0s0o/3s3e/5s5s/4s4a",
  106. "/$s$s/0s0o/3s3e/5s5s/4s4h",
  107. "/$s$s/0s0o/3s3e/1s1i",
  108. "/$s$s/0s0o/3s3e/1s1l",
  109. "/$s$s/0s0o/3s3e/1s1i/4s4a",
  110. "/$s$s/0s0o/3s3e/1s1i/4s4h",
  111. "/$s$s/0s0o/3s3e/1s1l/4s4a",
  112. "/$s$s/0s0o/3s3e/1s1l/4s4h",
  113. "/$s$s/0s0o/3s3e/4s4a",
  114. "/$s$s/0s0o/3s3e/4s4h",
  115. "/$s$s/0s0o/3s3e/4s4a",
  116. "/$s$s/0s0o/3s3e/4s4h",
  117. "/$s$s/0s0o/5s5s",
  118. "/$s$s/0s0o/5s5s/1s1i",
  119. "/$s$s/0s0o/5s5s/1s1l",
  120. "/$s$s/0s0o/5s5s/1s1i/4s4a",
  121. "/$s$s/0s0o/5s5s/1s1i/4s4h",
  122. "/$s$s/0s0o/5s5s/1s1l/4s4a",
  123. "/$s$s/0s0o/5s5s/1s1l/4s4h",
  124. "/$s$s/0s0o/5s5s/4s4a",
  125. "/$s$s/0s0o/5s5s/4s4h",
  126. "/$s$s/0s0o/5s5s/4s4a",
  127. "/$s$s/0s0o/5s5s/4s4h",
  128. "/$s$s/0s0o/1s1i",
  129. "/$s$s/0s0o/1s1l",
  130. "/$s$s/0s0o/1s1i/4s4a",
  131. "/$s$s/0s0o/1s1i/4s4h",
  132. "/$s$s/0s0o/1s1l/4s4a",
  133. "/$s$s/0s0o/1s1l/4s4h",
  134. "/$s$s/0s0o/4s4a",
  135. "/$s$s/0s0o/4s4h",
  136. "/$s$s/0s0o/4s4a",
  137. "/$s$s/0s0o/4s4h",
  138. "/$s$s/2s2a",
  139. "/$s$s/2s2a/3s3e",
  140. "/$s$s/2s2a/3s3e/5s5s",
  141. "/$s$s/2s2a/3s3e/5s5s/1s1i",
  142. "/$s$s/2s2a/3s3e/5s5s/1s1l",
  143. "/$s$s/2s2a/3s3e/5s5s/1s1i/4s4a",
  144. "/$s$s/2s2a/3s3e/5s5s/1s1i/4s4h",
  145. "/$s$s/2s2a/3s3e/5s5s/1s1l/4s4a",
  146. "/$s$s/2s2a/3s3e/5s5s/1s1l/4s4h",
  147. "/$s$s/2s2a/3s3e/5s5s/4s4a",
  148. "/$s$s/2s2a/3s3e/5s5s/4s4h",
  149. "/$s$s/2s2a/3s3e/5s5s/4s4a",
  150. "/$s$s/2s2a/3s3e/5s5s/4s4h",
  151. "/$s$s/2s2a/3s3e/1s1i",
  152. "/$s$s/2s2a/3s3e/1s1l",
  153. "/$s$s/2s2a/3s3e/1s1i/4s4a",
  154. "/$s$s/2s2a/3s3e/1s1i/4s4h",
  155. "/$s$s/2s2a/3s3e/1s1l/4s4a",
  156. "/$s$s/2s2a/3s3e/1s1l/4s4h",
  157. "/$s$s/2s2a/3s3e/4s4a",
  158. "/$s$s/2s2a/3s3e/4s4h",
  159. "/$s$s/2s2a/3s3e/4s4a",
  160. "/$s$s/2s2a/3s3e/4s4h",
  161. "/$s$s/2s2a/5s5s",
  162. "/$s$s/2s2a/5s5s/1s1i",
  163. "/$s$s/2s2a/5s5s/1s1l",
  164. "/$s$s/2s2a/5s5s/1s1i/4s4a",
  165. "/$s$s/2s2a/5s5s/1s1i/4s4h",
  166. "/$s$s/2s2a/5s5s/1s1l/4s4a",
  167. "/$s$s/2s2a/5s5s/1s1l/4s4h",
  168. "/$s$s/2s2a/5s5s/4s4a",
  169. "/$s$s/2s2a/5s5s/4s4h",
  170. "/$s$s/2s2a/5s5s/4s4a",
  171. "/$s$s/2s2a/5s5s/4s4h",
  172. "/$s$s/2s2a/1s1i",
  173. "/$s$s/2s2a/1s1l",
  174. "/$s$s/2s2a/1s1i/4s4a",
  175. "/$s$s/2s2a/1s1i/4s4h",
  176. "/$s$s/2s2a/1s1l/4s4a",
  177. "/$s$s/2s2a/1s1l/4s4h",
  178. "/$s$s/2s2a/4s4a",
  179. "/$s$s/2s2a/4s4h",
  180. "/$s$s/2s2a/4s4a",
  181. "/$s$s/2s2a/4s4h",
  182. "/$s$s/3s3e",
  183. "/$s$s/3s3e/5s5s",
  184. "/$s$s/3s3e/5s5s/1s1i",
  185. "/$s$s/3s3e/5s5s/1s1l",
  186. "/$s$s/3s3e/5s5s/1s1i/4s4a",
  187. "/$s$s/3s3e/5s5s/1s1i/4s4h",
  188. "/$s$s/3s3e/5s5s/1s1l/4s4a",
  189. "/$s$s/3s3e/5s5s/1s1l/4s4h",
  190. "/$s$s/3s3e/5s5s/4s4a",
  191. "/$s$s/3s3e/5s5s/4s4h",
  192. "/$s$s/3s3e/5s5s/4s4a",
  193. "/$s$s/3s3e/5s5s/4s4h",
  194. "/$s$s/3s3e/1s1i",
  195. "/$s$s/3s3e/1s1l",
  196. "/$s$s/3s3e/1s1i/4s4a",
  197. "/$s$s/3s3e/1s1i/4s4h",
  198. "/$s$s/3s3e/1s1l/4s4a",
  199. "/$s$s/3s3e/1s1l/4s4h",
  200. "/$s$s/3s3e/4s4a",
  201. "/$s$s/3s3e/4s4h",
  202. "/$s$s/3s3e/4s4a",
  203. "/$s$s/3s3e/4s4h",
  204. "/$s$s/5s5s",
  205. "/$s$s/5s5s/1s1i",
  206. "/$s$s/5s5s/1s1l",
  207. "/$s$s/5s5s/1s1i/4s4a",
  208. "/$s$s/5s5s/1s1i/4s4h",
  209. "/$s$s/5s5s/1s1l/4s4a",
  210. "/$s$s/5s5s/1s1l/4s4h",
  211. "/$s$s/5s5s/4s4a",
  212. "/$s$s/5s5s/4s4h",
  213. "/$s$s/5s5s/4s4a",
  214. "/$s$s/5s5s/4s4h",
  215. "/$s$s/1s1i",
  216. "/$s$s/1s1l",
  217. "/$s$s/1s1i/4s4a",
  218. "/$s$s/1s1i/4s4h",
  219. "/$s$s/1s1l/4s4a",
  220. "/$s$s/1s1l/4s4h",
  221. "/$s$s/4s4a",
  222. "/$s$s/4s4h",
  223. "/$s$s/4s4a",
  224. "/$s$s/4s4h",
  225. "/0s0o",
  226. "/0s0o/2s2a",
  227. "/0s0o/2s2a/3s3e",
  228. "/0s0o/2s2a/3s3e/5s5s",
  229. "/0s0o/2s2a/3s3e/5s5s/1s1i",
  230. "/0s0o/2s2a/3s3e/5s5s/1s1l",
  231. "/0s0o/2s2a/3s3e/5s5s/1s1i/4s4a",
  232. "/0s0o/2s2a/3s3e/5s5s/1s1i/4s4h",
  233. "/0s0o/2s2a/3s3e/5s5s/1s1l/4s4a",
  234. "/0s0o/2s2a/3s3e/5s5s/1s1l/4s4h",
  235. "/0s0o/2s2a/3s3e/5s5s/4s4a",
  236. "/0s0o/2s2a/3s3e/5s5s/4s4h",
  237. "/0s0o/2s2a/3s3e/5s5s/4s4a",
  238. "/0s0o/2s2a/3s3e/5s5s/4s4h",
  239. "/0s0o/2s2a/3s3e/1s1i",
  240. "/0s0o/2s2a/3s3e/1s1l",
  241. "/0s0o/2s2a/3s3e/1s1i/4s4a",
  242. "/0s0o/2s2a/3s3e/1s1i/4s4h",
  243. "/0s0o/2s2a/3s3e/1s1l/4s4a",
  244. "/0s0o/2s2a/3s3e/1s1l/4s4h",
  245. "/0s0o/2s2a/3s3e/4s4a",
  246. "/0s0o/2s2a/3s3e/4s4h",
  247. "/0s0o/2s2a/3s3e/4s4a",
  248. "/0s0o/2s2a/3s3e/4s4h",
  249. "/0s0o/2s2a/5s5s",
  250. "/0s0o/2s2a/5s5s/1s1i",
  251. "/0s0o/2s2a/5s5s/1s1l",
  252. "/0s0o/2s2a/5s5s/1s1i/4s4a",
  253. "/0s0o/2s2a/5s5s/1s1i/4s4h",
  254. "/0s0o/2s2a/5s5s/1s1l/4s4a",
  255. "/0s0o/2s2a/5s5s/1s1l/4s4h",
  256. "/0s0o/2s2a/5s5s/4s4a",
  257. "/0s0o/2s2a/5s5s/4s4h",
  258. "/0s0o/2s2a/5s5s/4s4a",
  259. "/0s0o/2s2a/5s5s/4s4h",
  260. "/0s0o/2s2a/1s1i",
  261. "/0s0o/2s2a/1s1l",
  262. "/0s0o/2s2a/1s1i/4s4a",
  263. "/0s0o/2s2a/1s1i/4s4h",
  264. "/0s0o/2s2a/1s1l/4s4a",
  265. "/0s0o/2s2a/1s1l/4s4h",
  266. "/0s0o/2s2a/4s4a",
  267. "/0s0o/2s2a/4s4h",
  268. "/0s0o/2s2a/4s4a",
  269. "/0s0o/2s2a/4s4h",
  270. "/0s0o/3s3e",
  271. "/0s0o/3s3e/5s5s",
  272. "/0s0o/3s3e/5s5s/1s1i",
  273. "/0s0o/3s3e/5s5s/1s1l",
  274. "/0s0o/3s3e/5s5s/1s1i/4s4a",
  275. "/0s0o/3s3e/5s5s/1s1i/4s4h",
  276. "/0s0o/3s3e/5s5s/1s1l/4s4a",
  277. "/0s0o/3s3e/5s5s/1s1l/4s4h",
  278. "/0s0o/3s3e/5s5s/4s4a",
  279. "/0s0o/3s3e/5s5s/4s4h",
  280. "/0s0o/3s3e/5s5s/4s4a",
  281. "/0s0o/3s3e/5s5s/4s4h",
  282. "/0s0o/3s3e/1s1i",
  283. "/0s0o/3s3e/1s1l",
  284. "/0s0o/3s3e/1s1i/4s4a",
  285. "/0s0o/3s3e/1s1i/4s4h",
  286. "/0s0o/3s3e/1s1l/4s4a",
  287. "/0s0o/3s3e/1s1l/4s4h",
  288. "/0s0o/3s3e/4s4a",
  289. "/0s0o/3s3e/4s4h",
  290. "/0s0o/3s3e/4s4a",
  291. "/0s0o/3s3e/4s4h",
  292. "/0s0o/5s5s",
  293. "/0s0o/5s5s/1s1i",
  294. "/0s0o/5s5s/1s1l",
  295. "/0s0o/5s5s/1s1i/4s4a",
  296. "/0s0o/5s5s/1s1i/4s4h",
  297. "/0s0o/5s5s/1s1l/4s4a",
  298. "/0s0o/5s5s/1s1l/4s4h",
  299. "/0s0o/5s5s/4s4a",
  300. "/0s0o/5s5s/4s4h",
  301. "/0s0o/5s5s/4s4a",
  302. "/0s0o/5s5s/4s4h",
  303. "/0s0o/1s1i",
  304. "/0s0o/1s1l",
  305. "/0s0o/1s1i/4s4a",
  306. "/0s0o/1s1i/4s4h",
  307. "/0s0o/1s1l/4s4a",
  308. "/0s0o/1s1l/4s4h",
  309. "/0s0o/4s4a",
  310. "/0s0o/4s4h",
  311. "/0s0o/4s4a",
  312. "/0s0o/4s4h",
  313. "/2s2a",
  314. "/2s2a/3s3e",
  315. "/2s2a/3s3e/5s5s",
  316. "/2s2a/3s3e/5s5s/1s1i",
  317. "/2s2a/3s3e/5s5s/1s1l",
  318. "/2s2a/3s3e/5s5s/1s1i/4s4a",
  319. "/2s2a/3s3e/5s5s/1s1i/4s4h",
  320. "/2s2a/3s3e/5s5s/1s1l/4s4a",
  321. "/2s2a/3s3e/5s5s/1s1l/4s4h",
  322. "/2s2a/3s3e/5s5s/4s4a",
  323. "/2s2a/3s3e/5s5s/4s4h",
  324. "/2s2a/3s3e/5s5s/4s4a",
  325. "/2s2a/3s3e/5s5s/4s4h",
  326. "/2s2a/3s3e/1s1i",
  327. "/2s2a/3s3e/1s1l",
  328. "/2s2a/3s3e/1s1i/4s4a",
  329. "/2s2a/3s3e/1s1i/4s4h",
  330. "/2s2a/3s3e/1s1l/4s4a",
  331. "/2s2a/3s3e/1s1l/4s4h",
  332. "/2s2a/3s3e/4s4a",
  333. "/2s2a/3s3e/4s4h",
  334. "/2s2a/3s3e/4s4a",
  335. "/2s2a/3s3e/4s4h",
  336. "/2s2a/5s5s",
  337. "/2s2a/5s5s/1s1i",
  338. "/2s2a/5s5s/1s1l",
  339. "/2s2a/5s5s/1s1i/4s4a",
  340. "/2s2a/5s5s/1s1i/4s4h",
  341. "/2s2a/5s5s/1s1l/4s4a",
  342. "/2s2a/5s5s/1s1l/4s4h",
  343. "/2s2a/5s5s/4s4a",
  344. "/2s2a/5s5s/4s4h",
  345. "/2s2a/5s5s/4s4a",
  346. "/2s2a/5s5s/4s4h",
  347. "/2s2a/1s1i",
  348. "/2s2a/1s1l",
  349. "/2s2a/1s1i/4s4a",
  350. "/2s2a/1s1i/4s4h",
  351. "/2s2a/1s1l/4s4a",
  352. "/2s2a/1s1l/4s4h",
  353. "/2s2a/4s4a",
  354. "/2s2a/4s4h",
  355. "/2s2a/4s4a",
  356. "/2s2a/4s4h",
  357. "/3s3e",
  358. "/3s3e/5s5s",
  359. "/3s3e/5s5s/1s1i",
  360. "/3s3e/5s5s/1s1l",
  361. "/3s3e/5s5s/1s1i/4s4a",
  362. "/3s3e/5s5s/1s1i/4s4h",
  363. "/3s3e/5s5s/1s1l/4s4a",
  364. "/3s3e/5s5s/1s1l/4s4h",
  365. "/3s3e/5s5s/4s4a",
  366. "/3s3e/5s5s/4s4h",
  367. "/3s3e/5s5s/4s4a",
  368. "/3s3e/5s5s/4s4h",
  369. "/3s3e/1s1i",
  370. "/3s3e/1s1l",
  371. "/3s3e/1s1i/4s4a",
  372. "/3s3e/1s1i/4s4h",
  373. "/3s3e/1s1l/4s4a",
  374. "/3s3e/1s1l/4s4h",
  375. "/3s3e/4s4a",
  376. "/3s3e/4s4h",
  377. "/3s3e/4s4a",
  378. "/3s3e/4s4h",
  379. "/5s5s",
  380. "/5s5s/1s1i",
  381. "/5s5s/1s1l",
  382. "/5s5s/1s1i/4s4a",
  383. "/5s5s/1s1i/4s4h",
  384. "/5s5s/1s1l/4s4a",
  385. "/5s5s/1s1l/4s4h",
  386. "/5s5s/4s4a",
  387. "/5s5s/4s4h",
  388. "/5s5s/4s4a",
  389. "/5s5s/4s4h",
  390. "/1s1i",
  391. "/1s1l",
  392. "/1s1i/4s4a",
  393. "/1s1i/4s4h",
  394. "/1s1l/4s4a",
  395. "/1s1l/4s4h",
  396. "/4s4a",
  397. "/4s4h",
  398. "/4s4a",
  399. "/4s4h",
  400. /* done */
  401. (char *) 0
  402. };
  403. static char *r_constructors[] = {
  404. ":",
  405. #ifdef DEBUG2
  406. (char *) 0,
  407. #endif
  408. "r",
  409. "d",
  410. "f",
  411. "dr",
  412. "fr",
  413. "rf",
  414. (char *) 0
  415. };
  416. int
  417. GTry(rawtext, password)
  418. char *rawtext;
  419. char *password;
  420. {
  421. int i;
  422. int len;
  423. char *mp;
  424. /* use destructors to turn password into rawtext */
  425. /* note use of Reverse() to save duplicating all rules */
  426. len = strlen(password);
  427. for (i = 0; r_destructors[i]; i++)
  428. {
  429. if (!(mp = Mangle(password, r_destructors[i])))
  430. {
  431. continue;
  432. }
  433. #ifdef DEBUG
  434. printf("%-16s = %-16s (destruct %s)\n", mp, rawtext, r_destructors[i]);
  435. #endif
  436. if (!strncmp(mp, rawtext, len))
  437. {
  438. return (1);
  439. }
  440. #ifdef DEBUG
  441. printf("%-16s = %-16s (destruct %s reversed)\n", Reverse(mp), rawtext, r_destructors[i]);
  442. #endif
  443. if (!strncmp(Reverse(mp), rawtext, len))
  444. {
  445. return (1);
  446. }
  447. }
  448. for (i = 0; r_constructors[i]; i++)
  449. {
  450. if (!(mp = Mangle(rawtext, r_constructors[i])))
  451. {
  452. continue;
  453. }
  454. #ifdef DEBUG
  455. printf("%-16s = %-16s (construct %s)\n", mp, password, r_constructors[i]);
  456. #endif
  457. if (!strncmp(mp, password, len))
  458. {
  459. return (1);
  460. }
  461. }
  462. return (0);
  463. }
  464. char *
  465. FascistGecos(password, uid)
  466. char *password;
  467. int uid;
  468. {
  469. int i;
  470. int j;
  471. int wc;
  472. char *ptr;
  473. int gwords;
  474. struct passwd *pwp, passwd;
  475. char gbuffer[STRINGSIZE];
  476. char tbuffer[STRINGSIZE];
  477. char *sbuffer = NULL;
  478. #ifdef HAVE_GETPWUID_R
  479. size_t sbufferlen = LINE_MAX;
  480. #endif
  481. char *uwords[STRINGSIZE];
  482. char longbuffer[STRINGSIZE * 2];
  483. #ifdef HAVE_GETPWUID_R
  484. sbuffer = malloc(sbufferlen);
  485. if (sbuffer == NULL)
  486. {
  487. return ("memory allocation error");
  488. }
  489. while ((i = getpwuid_r(uid, &passwd, sbuffer, sbufferlen, &pwp)) != 0)
  490. {
  491. if (i == ERANGE)
  492. {
  493. free(sbuffer);
  494. sbufferlen += LINE_MAX;
  495. sbuffer = malloc(sbufferlen);
  496. if (sbuffer == NULL)
  497. {
  498. return ("memory allocation error");
  499. }
  500. } else {
  501. pwp = NULL;
  502. break;
  503. }
  504. }
  505. #else
  506. /* Non-reentrant, but no choice since no _r routine */
  507. pwp = getpwuid(uid);
  508. #endif
  509. if (pwp == NULL)
  510. {
  511. if (sbuffer)
  512. {
  513. free(sbuffer);
  514. sbuffer = NULL;
  515. }
  516. return _("you are not registered in the password file");
  517. }
  518. /* lets get really paranoid and assume a dangerously long gecos entry */
  519. strncpy(tbuffer, pwp->pw_name, STRINGSIZE);
  520. tbuffer[STRINGSIZE-1] = '\0';
  521. if (GTry(tbuffer, password))
  522. {
  523. if (sbuffer)
  524. {
  525. free(sbuffer);
  526. sbuffer = NULL;
  527. }
  528. return _("it is based on your username");
  529. }
  530. /* it never used to be that you got passwd strings > 1024 chars, but now... */
  531. strncpy(tbuffer, pwp->pw_gecos, STRINGSIZE);
  532. tbuffer[STRINGSIZE-1] = '\0';
  533. strcpy(gbuffer, Lowercase(tbuffer));
  534. wc = 0;
  535. ptr = gbuffer;
  536. gwords = 0;
  537. uwords[0] = (char *)0;
  538. while (*ptr)
  539. {
  540. while (*ptr && ISSKIP(*ptr))
  541. {
  542. ptr++;
  543. }
  544. if (ptr != gbuffer)
  545. {
  546. ptr[-1] = '\0';
  547. }
  548. gwords++;
  549. uwords[wc++] = ptr;
  550. if (wc == STRINGSIZE)
  551. {
  552. uwords[--wc] = (char *) 0; /* to hell with it */
  553. break;
  554. } else
  555. {
  556. uwords[wc] = (char *) 0;
  557. }
  558. while (*ptr && !ISSKIP(*ptr))
  559. {
  560. ptr++;
  561. }
  562. if (*ptr)
  563. {
  564. *(ptr++) = '\0';
  565. }
  566. }
  567. #ifdef DEBUG
  568. for (i = 0; uwords[i]; i++)
  569. {
  570. printf("gecosword %s\n", uwords[i]);
  571. }
  572. #endif
  573. for (i = 0; uwords[i]; i++)
  574. {
  575. if (GTry(uwords[i], password))
  576. {
  577. if (sbuffer)
  578. {
  579. free(sbuffer);
  580. sbuffer = NULL;
  581. }
  582. return _("it is based upon your password entry");
  583. }
  584. }
  585. /* since uwords are taken from gbuffer, no uword can be longer than gbuffer */
  586. for (j = 1; (j < gwords) && uwords[j]; j++)
  587. {
  588. for (i = 0; i < j; i++)
  589. {
  590. strcpy(longbuffer, uwords[i]);
  591. strcat(longbuffer, uwords[j]);
  592. if (GTry(longbuffer, password))
  593. {
  594. if (sbuffer)
  595. {
  596. free(sbuffer);
  597. sbuffer = NULL;
  598. }
  599. return _("it is derived from your password entry");
  600. }
  601. strcpy(longbuffer, uwords[j]);
  602. strcat(longbuffer, uwords[i]);
  603. if (GTry(longbuffer, password))
  604. {
  605. if (sbuffer)
  606. {
  607. free(sbuffer);
  608. sbuffer = NULL;
  609. }
  610. return _("it's derived from your password entry");
  611. }
  612. longbuffer[0] = uwords[i][0];
  613. longbuffer[1] = '\0';
  614. strcat(longbuffer, uwords[j]);
  615. if (GTry(longbuffer, password))
  616. {
  617. if (sbuffer)
  618. {
  619. free(sbuffer);
  620. sbuffer = NULL;
  621. }
  622. return _("it is derivable from your password entry");
  623. }
  624. longbuffer[0] = uwords[j][0];
  625. longbuffer[1] = '\0';
  626. strcat(longbuffer, uwords[i]);
  627. if (GTry(longbuffer, password))
  628. {
  629. if (sbuffer)
  630. {
  631. free(sbuffer);
  632. sbuffer = NULL;
  633. }
  634. return _("it's derivable from your password entry");
  635. }
  636. }
  637. }
  638. if (sbuffer)
  639. {
  640. free(sbuffer);
  641. sbuffer = NULL;
  642. }
  643. return ((char *) 0);
  644. }
  645. char *
  646. FascistLook(pwp, instring)
  647. PWDICT *pwp;
  648. char *instring;
  649. {
  650. int i,maxrepeat;
  651. char *ptr;
  652. char *jptr;
  653. char junk[STRINGSIZE];
  654. char *password;
  655. char rpassword[STRINGSIZE];
  656. uint32_t notfound;
  657. notfound = PW_WORDS(pwp);
  658. /* already truncated if from FascistCheck() */
  659. /* but pretend it wasn't ... */
  660. strncpy(rpassword, instring, TRUNCSTRINGSIZE);
  661. rpassword[TRUNCSTRINGSIZE - 1] = '\0';
  662. password = rpassword;
  663. if (strlen(password) < 4)
  664. {
  665. return _("it is WAY too short");
  666. }
  667. if (strlen(password) < MINLEN)
  668. {
  669. return _("it is too short");
  670. }
  671. jptr = junk;
  672. *jptr = '\0';
  673. for (i = 0; i < STRINGSIZE && password[i]; i++)
  674. {
  675. if (!strchr(junk, password[i]))
  676. {
  677. *(jptr++) = password[i];
  678. *jptr = '\0';
  679. }
  680. }
  681. if (strlen(junk) < MINDIFF)
  682. {
  683. return _("it does not contain enough DIFFERENT characters");
  684. }
  685. strcpy(password, (char *)Lowercase(password));
  686. Trim(password);
  687. while (*password && isspace(*password))
  688. {
  689. password++;
  690. }
  691. if (!*password)
  692. {
  693. return _("it is all whitespace");
  694. }
  695. i = 0;
  696. ptr = password;
  697. while (ptr[0] && ptr[1])
  698. {
  699. if ((ptr[1] == (ptr[0] + 1)) || (ptr[1] == (ptr[0] - 1)))
  700. {
  701. i++;
  702. }
  703. ptr++;
  704. }
  705. /* Change by Ben Karsin from ITS at University of Hawaii at Manoa. Static MAXSTEP
  706. would generate many false positives for long passwords. */
  707. maxrepeat = 3+(0.09*strlen(password));
  708. if (i > maxrepeat)
  709. {
  710. return _("it is too simplistic/systematic");
  711. }
  712. if (PMatch("aadddddda", password)) /* smirk */
  713. {
  714. return _("it looks like a National Insurance number.");
  715. }
  716. if ((ptr = FascistGecos(password, getuid())))
  717. {
  718. return (ptr);
  719. }
  720. /* it should be safe to use Mangle with its reliance on STRINGSIZE
  721. since password cannot be longer than TRUNCSTRINGSIZE;
  722. nonetheless this is not an elegant solution */
  723. for (i = 0; r_destructors[i]; i++)
  724. {
  725. char *a;
  726. if (!(a = Mangle(password, r_destructors[i])))
  727. {
  728. continue;
  729. }
  730. #ifdef DEBUG
  731. printf("%-16s (dict)\n", a);
  732. #endif
  733. if (FindPW(pwp, a) != notfound)
  734. {
  735. return _("it is based on a dictionary word");
  736. }
  737. }
  738. strcpy(password, (char *)Reverse(password));
  739. for (i = 0; r_destructors[i]; i++)
  740. {
  741. char *a;
  742. if (!(a = Mangle(password, r_destructors[i])))
  743. {
  744. continue;
  745. }
  746. #ifdef DEBUG
  747. printf("%-16s (reversed dict)\n", a);
  748. #endif
  749. if (FindPW(pwp, a) != notfound)
  750. {
  751. return _("it is based on a (reversed) dictionary word");
  752. }
  753. }
  754. return ((char *) 0);
  755. }
  756. const char *
  757. FascistCheck(password, path)
  758. const char *password;
  759. const char *path;
  760. {
  761. PWDICT *pwp;
  762. char pwtrunced[STRINGSIZE];
  763. char *res;
  764. /* If passed null for the path, use a compiled-in default */
  765. if ( ! path )
  766. {
  767. path = DEFAULT_CRACKLIB_DICT;
  768. }
  769. /* security problem: assume we may have been given a really long
  770. password (buffer attack) and so truncate it to a workable size;
  771. try to define workable size as something from which we cannot
  772. extend a buffer beyond its limits in the rest of the code */
  773. strncpy(pwtrunced, password, TRUNCSTRINGSIZE);
  774. pwtrunced[TRUNCSTRINGSIZE - 1] = '\0'; /* enforce */
  775. /* perhaps someone should put something here to check if password
  776. is really long and syslog() a message denoting buffer attacks? */
  777. if (!(pwp = PWOpen(path, "r")))
  778. {
  779. /* shouldn't perror in a library or exit */
  780. /* but should we return a "bad password" or "good password" if this error occurs */
  781. perror("PWOpen");
  782. exit(-1);
  783. }
  784. /* sure seems like we should close the database, since we're only likely to check one password */
  785. res = FascistLook(pwp, pwtrunced);
  786. PWClose(pwp);
  787. pwp = (PWDICT *)0;
  788. return res;
  789. }
  790. const char *
  791. GetDefaultCracklibDict()
  792. {
  793. return DEFAULT_CRACKLIB_DICT;
  794. }