home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / crack / part03 < prev    next >
Encoding:
Internet Message Format  |  1992-03-18  |  39.6 KB

  1. From: aem@aber.ac.uk (Alec David Muffett)
  2. Newsgroups: comp.sources.misc
  3. Subject: v28i112: crack - The Unix Password Cracker, version 4.1, Part03/05
  4. Message-ID: <1992Mar18.143847.23911@aber.ac.uk>
  5. Date: 18 Mar 92 14:38:47 GMT
  6. Approved: aem@aber.ac.uk
  7. X-Md4-Signature: 5181c858338f3427fbc8d13540a2577a
  8.  
  9. Submitted-by: aem@aber.ac.uk (Alec David Muffett)
  10. Posting-number: Volume 28, Issue 112
  11. Archive-name: crack/part03
  12. Environment: UNIX
  13. Supersedes: crack: Volume 25, Issue 5-9
  14.  
  15. #! /bin/sh
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 3 (of 5)."
  21. # Contents:  Sources/crack-lib.c Sources/crack-pwc.c
  22. # Wrapped by aem@aberfa on Wed Mar 18 14:08:34 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'Sources/crack-lib.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'Sources/crack-lib.c'\"
  26. else
  27. echo shar: Extracting \"'Sources/crack-lib.c'\" \(14104 characters\)
  28. sed "s/^X//" >'Sources/crack-lib.c' <<'END_OF_FILE'
  29. X/*
  30. X * This program is copyright Alec Muffett 1991 except for some portions of
  31. X * code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus Sparry
  32. X * and Alec Muffett.  The author(s) disclaims all responsibility or liability
  33. X * with respect to it's usage or its effect upon hardware or computer
  34. X * systems, and maintain copyright as set out in the "LICENCE" document which
  35. X * accompanies distributions of Crack v4.0 and upwards.
  36. X */
  37. X
  38. X#include "crack.h"
  39. X
  40. X#define RULE_NOOP    ':'
  41. X#define RULE_PREPEND    '^'
  42. X#define RULE_APPEND    '$'
  43. X#define RULE_REVERSE    'r'
  44. X#define RULE_UPPERCASE    'u'
  45. X#define RULE_LOWERCASE    'l'
  46. X#define RULE_PLURALISE    'p'
  47. X#define RULE_CAPITALISE    'c'
  48. X#define RULE_DUPLICATE    'd'
  49. X#define RULE_REFLECT    'f'
  50. X#define RULE_SUBSTITUTE    's'
  51. X#define RULE_MATCH    '/'
  52. X#define RULE_NOT    '!'
  53. X#define RULE_LT        '<'
  54. X#define RULE_GT        '>'
  55. X#define RULE_EXTRACT    'x'
  56. X#define RULE_OVERSTRIKE    'o'
  57. X#define RULE_INSERT    'i'
  58. X#define RULE_EQUALS    '='
  59. X#define RULE_PURGE    '@'
  60. X#define RULE_CLASS    '?'    /* class rule? socialist ethic in cracker? */
  61. X
  62. Xvoid
  63. XTrim (string)            /* remove trailing whitespace from a string */
  64. X    register char *string;
  65. X{
  66. X    register char *ptr;
  67. X
  68. X    for (ptr = string; *ptr; ptr++);
  69. X    while ((--ptr >= string) && isspace (*ptr));
  70. X    *(++ptr) = '\0';
  71. X}
  72. X
  73. Xchar *
  74. XClone (string)
  75. X    char *string;
  76. X{
  77. X    register char *retval;
  78. X
  79. X    retval = (char *) malloc (strlen (string) + 1);
  80. X    if (retval)
  81. X    {
  82. X    strcpy (retval, string);
  83. X    }
  84. X    return (retval);
  85. X}
  86. X
  87. Xint
  88. XSuffix (word, suffix)
  89. X    char *word;
  90. X    char *suffix;
  91. X{
  92. X    register int i;
  93. X    register int j;
  94. X
  95. X    i = strlen (word);
  96. X    j = strlen (suffix);
  97. X
  98. X    if (i > j)
  99. X    {
  100. X    return (STRCMP ((word + i - j), suffix));
  101. X    } else
  102. X    {
  103. X    return (-1);
  104. X    }
  105. X}
  106. X
  107. Xchar *
  108. XReverse (str)            /* return a pointer to a reversal */
  109. X    register char *str;
  110. X{
  111. X    register int i;
  112. X    register int j;
  113. X    static char area[STRINGSIZE];
  114. X
  115. X    j = i = strlen (str);
  116. X    while (*str)
  117. X    {
  118. X    area[--i] = *str++;
  119. X    }
  120. X    area[j] = '\0';
  121. X    return (area);
  122. X}
  123. X
  124. Xchar *
  125. XUppercase (str)            /* return a pointer to an uppercase */
  126. X    register char *str;
  127. X{
  128. X    register char *ptr;
  129. X    static char area[STRINGSIZE];
  130. X
  131. X    ptr = area;
  132. X    while (*str)
  133. X    {
  134. X    *(ptr++) = CRACK_TOUPPER (*str);
  135. X    str++;
  136. X    }
  137. X    *ptr = '\0';
  138. X
  139. X    return (area);
  140. X}
  141. X
  142. Xchar *
  143. XLowercase (str)            /* return a pointer to an lowercase */
  144. X    register char *str;
  145. X{
  146. X    register char *ptr;
  147. X    static char area[STRINGSIZE];
  148. X
  149. X    ptr = area;
  150. X    while (*str)
  151. X    {
  152. X    *(ptr++) = CRACK_TOLOWER (*str);
  153. X    str++;
  154. X    }
  155. X    *ptr = '\0';
  156. X
  157. X    return (area);
  158. X}
  159. X
  160. Xchar *
  161. XCapitalise (str)        /* return a pointer to an capitalised */
  162. X    register char *str;
  163. X{
  164. X    register char *ptr;
  165. X    static char area[STRINGSIZE];
  166. X
  167. X    ptr = area;
  168. X
  169. X    while (*str)
  170. X    {
  171. X    *(ptr++) = CRACK_TOLOWER (*str);
  172. X    str++;
  173. X    }
  174. X
  175. X    *ptr = '\0';
  176. X    area[0] = CRACK_TOUPPER (area[0]);
  177. X    return (area);
  178. X}
  179. X
  180. Xchar *
  181. XPluralise (string)        /* returns a pointer to a plural */
  182. X    register char *string;
  183. X{
  184. X    register int length;
  185. X    static char area[STRINGSIZE];
  186. X
  187. X    length = strlen (string);
  188. X    strcpy (area, string);
  189. X
  190. X    if (!Suffix (string, "ch") ||
  191. X    !Suffix (string, "ex") ||
  192. X    !Suffix (string, "ix") ||
  193. X    !Suffix (string, "sh") ||
  194. X    !Suffix (string, "ss"))
  195. X    {
  196. X    /* bench -> benches */
  197. X    strcat (area, "es");
  198. X    } else if (length > 2 && string[length - 1] == 'y')
  199. X    {
  200. X    if (strchr ("aeiou", string[length - 2]))
  201. X    {
  202. X        /* alloy -> alloys */
  203. X        strcat (area, "s");
  204. X    } else
  205. X    {
  206. X        /* gully -> gullies */
  207. X        strcpy (area + length - 1, "ies");
  208. X    }
  209. X    } else if (string[length - 1] == 's')
  210. X    {
  211. X    /* bias -> biases */
  212. X    strcat (area, "es");
  213. X    } else
  214. X    {
  215. X    /* catchall */
  216. X    strcat (area, "s");
  217. X    }
  218. X
  219. X    return (area);
  220. X}
  221. X
  222. Xchar *
  223. XSubstitute (string, old, new)    /* returns pointer to a swapped about copy */
  224. X    register char *string;
  225. X    register char old;
  226. X    register char new;
  227. X{
  228. X    register char *ptr;
  229. X    static char area[STRINGSIZE];
  230. X
  231. X    ptr = area;
  232. X    while (*string)
  233. X    {
  234. X    *(ptr++) = (*string == old ? new : *string);
  235. X    string++;
  236. X    }
  237. X    *ptr = '\0';
  238. X    return (area);
  239. X}
  240. X
  241. Xchar *
  242. XPurge (string, target)        /* returns pointer to a purged copy */
  243. X    register char *string;
  244. X    register char target;
  245. X{
  246. X    register char *ptr;
  247. X    static char area[STRINGSIZE];
  248. X
  249. X    ptr = area;
  250. X    while (*string)
  251. X    {
  252. X    if (*string != target)
  253. X    {
  254. X        *(ptr++) = *string;
  255. X    }
  256. X    string++;
  257. X    }
  258. X    *ptr = '\0';
  259. X    return (area);
  260. X}
  261. X/* -------- CHARACTER CLASSES START HERE -------- */
  262. X
  263. X/*
  264. X * this function takes two inputs, a class identifier and a character, and
  265. X * returns non-null if the given character is a member of the class, based
  266. X * upon restrictions set out below
  267. X */
  268. X
  269. Xint
  270. XMatchClass (class, input)
  271. X    register char class;
  272. X    register char input;
  273. X{
  274. X    register char c;
  275. X    register int retval;
  276. X
  277. X    retval = 0;
  278. X
  279. X    switch (class)
  280. X    {
  281. X    /* ESCAPE */
  282. X
  283. X    case '?':            /* ?? -> ? */
  284. X    if (input == '?')
  285. X    {
  286. X        retval = 1;
  287. X    }
  288. X    break;
  289. X
  290. X    /* ILLOGICAL GROUPINGS (ie: not in ctype.h) */
  291. X
  292. X    case 'V':
  293. X    case 'v':            /* vowels */
  294. X    c = CRACK_TOLOWER (input);
  295. X    if (strchr ("aeiou", c))
  296. X    {
  297. X        retval = 1;
  298. X    }
  299. X    break;
  300. X
  301. X    case 'C':
  302. X    case 'c':            /* consonants */
  303. X    c = CRACK_TOLOWER (input);
  304. X    if (strchr ("bcdfghjklmnpqrstvwxyz", c))
  305. X    {
  306. X        retval = 1;
  307. X    }
  308. X    break;
  309. X
  310. X    case 'W':
  311. X    case 'w':            /* whitespace */
  312. X    if (strchr ("\t ", input))
  313. X    {
  314. X        retval = 1;
  315. X    }
  316. X    break;
  317. X
  318. X    case 'P':
  319. X    case 'p':            /* punctuation */
  320. X    if (strchr (".`,:;'!?\"", input))
  321. X    {
  322. X        retval = 1;
  323. X    }
  324. X    break;
  325. X
  326. X    case 'S':
  327. X    case 's':            /* symbols */
  328. X    if (strchr ("$%%^&*()-_+=|\\[]{}#@/~", input))
  329. X    {
  330. X        retval = 1;
  331. X    }
  332. X    break;
  333. X
  334. X    /* LOGICAL GROUPINGS */
  335. X
  336. X    case 'L':
  337. X    case 'l':            /* lowercase */
  338. X    if (islower (input))
  339. X    {
  340. X        retval = 1;
  341. X    }
  342. X    break;
  343. X
  344. X    case 'U':
  345. X    case 'u':            /* uppercase */
  346. X    if (isupper (input))
  347. X    {
  348. X        retval = 1;
  349. X    }
  350. X    break;
  351. X
  352. X    case 'A':
  353. X    case 'a':            /* alphabetic */
  354. X    if (isalpha (input))
  355. X    {
  356. X        retval = 1;
  357. X    }
  358. X    break;
  359. X
  360. X    case 'X':
  361. X    case 'x':            /* alphanumeric */
  362. X    if (isalnum (input))
  363. X    {
  364. X        retval = 1;
  365. X    }
  366. X    break;
  367. X
  368. X    case 'D':
  369. X    case 'd':            /* digits */
  370. X    if (isdigit (input))
  371. X    {
  372. X        retval = 1;
  373. X    }
  374. X    break;
  375. X
  376. X    default:
  377. X    Log ("MatchClass: unknown class %c\n", class);
  378. X    return (0);
  379. X    break;
  380. X    }
  381. X
  382. X    if (isupper (class))
  383. X    {
  384. X    return (!retval);
  385. X    }
  386. X    return (retval);
  387. X}
  388. X
  389. Xchar *
  390. XPolyStrchr (string, class)
  391. X    register char *string;
  392. X    register char class;
  393. X{
  394. X    while (*string)
  395. X    {
  396. X    if (MatchClass (class, *string))
  397. X    {
  398. X        return (string);
  399. X    }
  400. X    string++;
  401. X    }
  402. X    return ((char *) 0);
  403. X}
  404. X
  405. Xchar *
  406. XPolySubst (string, class, new)    /* returns pointer to a swapped about copy */
  407. X    register char *string;
  408. X    register char class;
  409. X    register char new;
  410. X{
  411. X    register char *ptr;
  412. X    static char area[STRINGSIZE];
  413. X
  414. X    ptr = area;
  415. X    while (*string)
  416. X    {
  417. X    *(ptr++) = (MatchClass (class, *string) ? new : *string);
  418. X    string++;
  419. X    }
  420. X    *ptr = '\0';
  421. X    return (area);
  422. X}
  423. X
  424. Xchar *
  425. XPolyPurge (string, class)    /* returns pointer to a purged copy */
  426. X    register char *string;
  427. X    register char class;
  428. X{
  429. X    register char *ptr;
  430. X    static char area[STRINGSIZE];
  431. X
  432. X    ptr = area;
  433. X    while (*string)
  434. X    {
  435. X    if (!MatchClass (class, *string))
  436. X    {
  437. X        *(ptr++) = *string;
  438. X    }
  439. X    string++;
  440. X    }
  441. X    *ptr = '\0';
  442. X    return (area);
  443. X}
  444. X/* -------- BACK TO NORMALITY -------- */
  445. X
  446. Xint
  447. XChar2Int (character)
  448. X    char character;
  449. X{
  450. X    if (isdigit (character))
  451. X    {
  452. X    return (character - '0');
  453. X    } else if (islower (character))
  454. X    {
  455. X    return (character - 'a' + 10);
  456. X    } else if (isupper (character))
  457. X    {
  458. X    return (character - 'A' + 10);
  459. X    }
  460. X    return (-1);
  461. X}
  462. X
  463. Xchar *
  464. XMangle (input, control)        /* returns a pointer to a controlled Mangle */
  465. X    char *input;
  466. X    char *control;
  467. X{
  468. X    int limit;
  469. X    register char *ptr;
  470. X    static char area[STRINGSIZE];
  471. X    char area2[STRINGSIZE];
  472. X
  473. X    area[0] = '\0';
  474. X    strcpy (area, input);
  475. X
  476. X    for (ptr = control; *ptr; ptr++)
  477. X    {
  478. X    switch (*ptr)
  479. X    {
  480. X    case RULE_NOOP:
  481. X        break;
  482. X    case RULE_REVERSE:
  483. X        strcpy (area, Reverse (area));
  484. X        break;
  485. X    case RULE_UPPERCASE:
  486. X        strcpy (area, Uppercase (area));
  487. X        break;
  488. X    case RULE_LOWERCASE:
  489. X        strcpy (area, Lowercase (area));
  490. X        break;
  491. X    case RULE_CAPITALISE:
  492. X        strcpy (area, Capitalise (area));
  493. X        break;
  494. X    case RULE_PLURALISE:
  495. X        strcpy (area, Pluralise (area));
  496. X        break;
  497. X    case RULE_REFLECT:
  498. X        strcat (area, Reverse (area));
  499. X        break;
  500. X    case RULE_DUPLICATE:
  501. X        strcpy (area2, area);
  502. X        strcat (area, area2);
  503. X        break;
  504. X    case RULE_GT:
  505. X        if (!ptr[1])
  506. X        {
  507. X        Log ("Mangle: '>' missing argument in '%s'\n", control);
  508. X        return ((char *) 0);
  509. X        } else
  510. X        {
  511. X        limit = Char2Int (*(++ptr));
  512. X        if (limit < 0)
  513. X        {
  514. X            Log ("Mangle: '>' weird argument in '%s'\n", control);
  515. X            return ((char *) 0);
  516. X        }
  517. X        if (strlen (area) <= limit)
  518. X        {
  519. X            return ((char *) 0);
  520. X        }
  521. X        }
  522. X        break;
  523. X    case RULE_LT:
  524. X        if (!ptr[1])
  525. X        {
  526. X        Log ("Mangle: '<' missing argument in '%s'\n", control);
  527. X        return ((char *) 0);
  528. X        } else
  529. X        {
  530. X        limit = Char2Int (*(++ptr));
  531. X        if (limit < 0)
  532. X        {
  533. X            Log ("Mangle: '<' weird argument in '%s'\n", control);
  534. X            return ((char *) 0);
  535. X        }
  536. X        if (strlen (area) >= limit)
  537. X        {
  538. X            return ((char *) 0);
  539. X        }
  540. X        }
  541. X        break;
  542. X    case RULE_PREPEND:
  543. X        if (!ptr[1])
  544. X        {
  545. X        Log ("Mangle: prepend missing argument in '%s'\n", control);
  546. X        return ((char *) 0);
  547. X        } else
  548. X        {
  549. X        area2[0] = *(++ptr);
  550. X        strcpy (area2 + 1, area);
  551. X        strcpy (area, area2);
  552. X        }
  553. X        break;
  554. X    case RULE_APPEND:
  555. X        if (!ptr[1])
  556. X        {
  557. X        Log ("Mangle: append missing argument in '%s'\n", control);
  558. X        return ((char *) 0);
  559. X        } else
  560. X        {
  561. X        register char *string;
  562. X
  563. X        string = area;
  564. X        while (*(string++));
  565. X        string[-1] = *(++ptr);
  566. X        *string = '\0';
  567. X        }
  568. X        break;
  569. X    case RULE_EXTRACT:
  570. X        if (!ptr[1] || !ptr[2])
  571. X        {
  572. X        Log ("Mangle: extract missing argument in '%s'\n", control);
  573. X        return ((char *) 0);
  574. X        } else
  575. X        {
  576. X        register int i;
  577. X        int start;
  578. X        int length;
  579. X
  580. X        start = Char2Int (*(++ptr));
  581. X        length = Char2Int (*(++ptr));
  582. X        if (start < 0 || length < 0)
  583. X        {
  584. X            Log ("Mangle: extract: weird argument in '%s'\n", control);
  585. X            return ((char *) 0);
  586. X        }
  587. X        strcpy (area2, area);
  588. X        for (i = 0; length-- && area2[start + i]; i++)
  589. X        {
  590. X            area[i] = area2[start + i];
  591. X        }
  592. X        /* cant use strncpy() - no trailing NUL */
  593. X        area[i] = '\0';
  594. X        }
  595. X        break;
  596. X    case RULE_OVERSTRIKE:
  597. X        if (!ptr[1] || !ptr[2])
  598. X        {
  599. X        Log ("Mangle: overstrike missing argument in '%s'\n", control);
  600. X        return ((char *) 0);
  601. X        } else
  602. X        {
  603. X        register int i;
  604. X
  605. X        i = Char2Int (*(++ptr));
  606. X        if (i < 0)
  607. X        {
  608. X            Log ("Mangle: overstrike weird argument in '%s'\n",
  609. X             control);
  610. X            return ((char *) 0);
  611. X        } else
  612. X        {
  613. X            ++ptr;
  614. X            if (area[i])
  615. X            {
  616. X            area[i] = *ptr;
  617. X            }
  618. X        }
  619. X        }
  620. X        break;
  621. X    case RULE_INSERT:
  622. X        if (!ptr[1] || !ptr[2])
  623. X        {
  624. X        Log ("Mangle: insert missing argument in '%s'\n", control);
  625. X        return ((char *) 0);
  626. X        } else
  627. X        {
  628. X        register int i;
  629. X        register char *p1;
  630. X        register char *p2;
  631. X
  632. X        i = Char2Int (*(++ptr));
  633. X        if (i < 0)
  634. X        {
  635. X            Log ("Mangle: insert weird argument in '%s'\n",
  636. X             control);
  637. X            return ((char *) 0);
  638. X        }
  639. X        p1 = area;
  640. X        p2 = area2;
  641. X        while (i && *p1)
  642. X        {
  643. X            i--;
  644. X            *(p2++) = *(p1++);
  645. X        }
  646. X        *(p2++) = *(++ptr);
  647. X        strcpy (p2, p1);
  648. X        strcpy (area, area2);
  649. X        }
  650. X        break;
  651. X        /* THE FOLLOWING RULES REQUIRE CLASS MATCHING */
  652. X
  653. X    case RULE_PURGE:    /* @x or @?c */
  654. X        if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  655. X        {
  656. X        Log ("Mangle: delete missing arguments in '%s'\n", control);
  657. X        return ((char *) 0);
  658. X        } else if (ptr[1] != RULE_CLASS)
  659. X        {
  660. X        strcpy (area, Purge (area, *(++ptr)));
  661. X        } else
  662. X        {
  663. X        strcpy (area, PolyPurge (area, ptr[2]));
  664. X        ptr += 2;
  665. X        }
  666. X        break;
  667. X    case RULE_SUBSTITUTE:    /* sxy || s?cy */
  668. X        if (!ptr[1] || !ptr[2] || (ptr[1] == RULE_CLASS && !ptr[3]))
  669. X        {
  670. X        Log ("Mangle: subst missing argument in '%s'\n", control);
  671. X        return ((char *) 0);
  672. X        } else if (ptr[1] != RULE_CLASS)
  673. X        {
  674. X        strcpy (area, Substitute (area, ptr[1], ptr[2]));
  675. X        ptr += 2;
  676. X        } else
  677. X        {
  678. X        strcpy (area, PolySubst (area, ptr[2], ptr[3]));
  679. X        ptr += 3;
  680. X        }
  681. X        break;
  682. X    case RULE_MATCH:    /* /x || /?c */
  683. X        if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  684. X        {
  685. X        Log ("Mangle: '/' missing argument in '%s'\n", control);
  686. X        return ((char *) 0);
  687. X        } else if (ptr[1] != RULE_CLASS)
  688. X        {
  689. X        if (!strchr (area, *(++ptr)))
  690. X        {
  691. X            return ((char *) 0);
  692. X        }
  693. X        } else
  694. X        {
  695. X        if (!PolyStrchr (area, ptr[2]))
  696. X        {
  697. X            return ((char *) 0);
  698. X        }
  699. X        ptr += 2;
  700. X        }
  701. X        break;
  702. X    case RULE_NOT:        /* !x || !?c */
  703. X        if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  704. X        {
  705. X        Log ("Mangle: '!' missing argument in '%s'\n", control);
  706. X        return ((char *) 0);
  707. X        } else if (ptr[1] != RULE_CLASS)
  708. X        {
  709. X        if (strchr (area, *(++ptr)))
  710. X        {
  711. X            return ((char *) 0);
  712. X        }
  713. X        } else
  714. X        {
  715. X        if (PolyStrchr (area, ptr[2]))
  716. X        {
  717. X            return ((char *) 0);
  718. X        }
  719. X        ptr += 2;
  720. X        }
  721. X        break;
  722. X
  723. X        /*
  724. X         * alternative use for a boomerang, number 1: a standard throwing
  725. X         * boomerang is an ideal thing to use to tuck the sheets under
  726. X         * the mattress when making your bed.  The streamlined shape of
  727. X         * the boomerang allows it to slip easily 'twixt mattress and
  728. X         * bedframe, and it's curve makes it very easy to hook sheets
  729. X         * into the gap.
  730. X         */
  731. X
  732. X    case RULE_EQUALS:    /* =nx || =n?c */
  733. X        if (!ptr[1] || !ptr[2] || (ptr[2] == RULE_CLASS && !ptr[3]))
  734. X        {
  735. X        Log ("Mangle: '=' missing argument in '%s'\n", control);
  736. X        return ((char *) 0);
  737. X        } else
  738. X        {
  739. X        register int i;
  740. X
  741. X        if ((i = Char2Int (ptr[1])) < 0)
  742. X        {
  743. X            Log ("Mangle: '=' weird argument in '%s'\n", control);
  744. X            return ((char *) 0);
  745. X        }
  746. X        if (ptr[2] != RULE_CLASS)
  747. X        {
  748. X            ptr += 2;
  749. X            if (area[i] != *ptr)
  750. X            {
  751. X            return ((char *) 0);
  752. X            }
  753. X        } else
  754. X        {
  755. X            ptr += 3;
  756. X            if (!MatchClass (*ptr, area[i]))
  757. X            {
  758. X            return ((char *) 0);
  759. X            }
  760. X        }
  761. X        }
  762. X        break;
  763. X    default:
  764. X        Log ("Mangle: unknown command %c in %s\n", *ptr, control);
  765. X        return ((char *) 0);
  766. X        break;
  767. X    }
  768. X    }
  769. X    if (!area[0])        /* have we deweted de poor widdle fing away? */
  770. X    {
  771. X    return ((char *) 0);
  772. X    }
  773. X    return (area);
  774. X}
  775. END_OF_FILE
  776. if test 14104 -ne `wc -c <'Sources/crack-lib.c'`; then
  777.     echo shar: \"'Sources/crack-lib.c'\" unpacked with wrong size!
  778. fi
  779. # end of 'Sources/crack-lib.c'
  780. fi
  781. if test -f 'Sources/crack-pwc.c' -a "${1}" != "-c" ; then 
  782.   echo shar: Will not clobber existing file \"'Sources/crack-pwc.c'\"
  783. else
  784. echo shar: Extracting \"'Sources/crack-pwc.c'\" \(22280 characters\)
  785. sed "s/^X//" >'Sources/crack-pwc.c' <<'END_OF_FILE'
  786. X/*
  787. X * This program is copyright Alec Muffett 1991 except for some portions of
  788. X * code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus Sparry
  789. X * and Alec Muffett.  The author(s) disclaims all responsibility or liability
  790. X * with respect to it's usage or its effect upon hardware or computer
  791. X * systems, and maintain copyright as set out in the "LICENCE" document which
  792. X * accompanies distributions of Crack v4.0 and upwards.
  793. X */
  794. X
  795. X#include "crack.h"
  796. X
  797. X#define DOTFILESIZE    1024
  798. X#define WORDSTACKSIZE    512
  799. X
  800. X/*
  801. X * crack-pwc.c - an optimised password cracker. (c) ADE Muffett, Feb 1992. If
  802. X * this won't break your password file, it's unlikely that anything else
  803. X * will.
  804. X */
  805. X
  806. X/* trap a signal on shutdown */
  807. X
  808. Xvoid
  809. XCatchTERM ()
  810. X{
  811. X    /* bury magnets */
  812. X    Log ("Caught a SIGTERM! Commiting suicide...\n");
  813. X    /* swallow the rapture */
  814. X    Log ("<argh!>\n");
  815. X    /* let's gather feathers */
  816. X    sync ();
  817. X    /* don't fall on me */
  818. X    exit (0);
  819. X    /* 'Fall on Me' by R.E.M. */
  820. X}
  821. X/* jump ':' separated fields in an input */
  822. X
  823. Xchar *
  824. XPWSkip (p)
  825. X    register char *p;
  826. X{
  827. X    while (*p && *p != ':')
  828. X    {
  829. X    p++;
  830. X    }
  831. X    if (*p)
  832. X    {
  833. X    *p++ = '\0';
  834. X    }
  835. X    return (p);
  836. X}
  837. X
  838. Xchar *
  839. XArchive (myword)
  840. X    register char *myword;
  841. X{
  842. X    register int i;
  843. X    register struct DICT *ptr;
  844. X    static struct DICT *arch_root;
  845. X
  846. X    for (ptr = arch_root; ptr; ptr = ptr -> next)
  847. X    {
  848. X    if (!STRCMP (ptr -> word, myword))
  849. X    {
  850. X        return (ptr -> word);
  851. X    }
  852. X    }
  853. X
  854. X    i = strlen (myword);
  855. X
  856. X    ptr = (struct DICT *) malloc (sizeof (struct DICT) + i);
  857. X
  858. X    if (ptr)
  859. X    {
  860. X    strcpy (ptr -> word, myword);
  861. X    ptr -> word[i] = '\0';
  862. X    ptr -> next = arch_root;
  863. X    arch_root = ptr;
  864. X    } else
  865. X    {
  866. X    Log ("Archive/malloc() failed! Fatal lack of memory!\n");
  867. X    exit (1);
  868. X    }
  869. X
  870. X    return (ptr -> word);
  871. X}
  872. X/* parse and store a password entry */
  873. X
  874. Xstruct USER *
  875. XParse (buffer)
  876. X    register char *buffer;
  877. X{
  878. X    register char *p;
  879. X    register struct USER *retval;
  880. X
  881. X    retval = (struct USER *) malloc (sizeof (struct USER));
  882. X
  883. X    if (!retval)
  884. X    {
  885. X    Log ("Parse/malloc() failed! Fatal lack of memory!\n");
  886. X    exit (1);
  887. X    }
  888. X    retval -> next = retval -> across = NULL;
  889. X    retval -> passwd_txt = NULL;
  890. X    retval -> done = 0;
  891. X    Trim (buffer);
  892. X
  893. X    p = PWSkip (buffer);
  894. X    retval -> filename = Archive (buffer);
  895. X
  896. X    p = Clone (p);
  897. X    if (!p)
  898. X    {
  899. X    Log ("Parse/Clone() failed! Fatal lack of memory!\n");
  900. X    exit (1);
  901. X    }
  902. X    retval -> passwd.pw_name = p;
  903. X
  904. X    p = PWSkip (p);
  905. X    retval -> passwd.pw_passwd = p;
  906. X
  907. X    p = PWSkip (p);
  908. X    retval -> passwd.pw_uid = atoi (p);
  909. X
  910. X    p = PWSkip (p);
  911. X    retval -> passwd.pw_gid = atoi (p);
  912. X
  913. X    p = PWSkip (p);
  914. X    retval -> passwd.pw_gecos = p;
  915. X
  916. X    p = PWSkip (p);
  917. X    retval -> passwd.pw_dir = p;
  918. X
  919. X    p = PWSkip (p);
  920. X    retval -> passwd.pw_shell = p;
  921. X
  922. X    return (retval);
  923. X}
  924. X/* load pre-formatted password entries off stdin into linked list */
  925. X
  926. Xint
  927. XLoadData ()
  928. X{
  929. X    int i;
  930. X    char *ptr;
  931. X    char salt[2];
  932. X    char buffer[STRINGSIZE];
  933. X    long int numlines;
  934. X    long int numentries;
  935. X    register struct USER *new_element;
  936. X    register struct USER *current_line;
  937. X
  938. X    numlines = 0L;
  939. X    numentries = 0L;
  940. X    current_line = NULL;
  941. X    salt[0] = salt[1] = '*';
  942. X
  943. X    while (fgets (buffer, STRINGSIZE, stdin))
  944. X    {
  945. X    if (!*buffer || isspace (*buffer))
  946. X    {
  947. X        continue;
  948. X    }
  949. X    new_element = Parse (buffer);
  950. X    ptr = new_element -> passwd.pw_passwd;
  951. X
  952. X    if (!ptr[0])
  953. X    {
  954. X        Log ("Warning! %s (%s in %s) has a NULL password!\n",
  955. X         new_element -> passwd.pw_name,
  956. X         new_element -> passwd.pw_shell,
  957. X         new_element -> filename);
  958. X        continue;
  959. X    }
  960. X    if (strchr (ptr, '*') ||
  961. X        strchr (ptr, '!') ||
  962. X        strchr (ptr, ' '))
  963. X    {
  964. X        Log ("User %s (in %s) has a locked password:- %s\n",
  965. X         new_element -> passwd.pw_name,
  966. X         new_element -> filename,
  967. X         new_element -> passwd.pw_passwd);
  968. X        continue;
  969. X    }
  970. X    i = strlen (ptr);
  971. X
  972. X    if (i < 13)
  973. X    {
  974. X        Log ("User %s (in %s) has a short pw_passwd field - skipping.\n",
  975. X         new_element -> passwd.pw_name,
  976. X         new_element -> filename);
  977. X        continue;
  978. X    }
  979. X    if (i > 13)
  980. X    {
  981. X        Log ("User %s (in %s) has a long pw_passwd field - truncating.\n",
  982. X         new_element -> passwd.pw_name,
  983. X         new_element -> filename);
  984. X        ptr[13] = '\0';
  985. X    }
  986. X    numentries++;
  987. X
  988. X    if (ptr[0] == salt[0] && ptr[1] == salt[1])
  989. X    {
  990. X        new_element -> across = current_line;
  991. X        current_line = new_element;
  992. X    } else
  993. X    {
  994. X        if (current_line)
  995. X        {
  996. X        current_line -> next = userroot;
  997. X        }
  998. X        userroot = current_line;
  999. X        current_line = new_element;
  1000. X        numlines++;
  1001. X        salt[0] = ptr[0];
  1002. X        salt[1] = ptr[1];
  1003. X    }
  1004. X    }
  1005. X
  1006. X    if (current_line)        /* last one tends to hang about */
  1007. X    {
  1008. X    current_line -> next = userroot;
  1009. X    userroot = current_line;
  1010. X    numlines++;
  1011. X    }
  1012. X    --numlines;
  1013. X
  1014. X    if (numentries)
  1015. X    {
  1016. X    Log ("Loaded %ld password entries with %ld different salts: %d%%\n",
  1017. X         numentries,
  1018. X         numlines,
  1019. X         ((numlines * 100) / numentries));
  1020. X    } else
  1021. X    {
  1022. X    Log ("No input supplied: everything removed by feedback ?\n");
  1023. X    }
  1024. X    return (numentries);
  1025. X}
  1026. X/* and load rules from a standard file into a similar list */
  1027. X
  1028. Xint
  1029. XLoadRules (file, rootpos)
  1030. X    char *file;
  1031. X    struct RULE **rootpos;
  1032. X{
  1033. X    FILE *fp;
  1034. X    int numrules;
  1035. X    struct RULE fencepost;
  1036. X    register struct RULE *addinto;
  1037. X    register struct RULE *scratch;
  1038. X    char buffer[STRINGSIZE];
  1039. X
  1040. X    if (!(fp = fopen (file, "r")))
  1041. X    {
  1042. X    Log ("cannot open rulefile %s\n", file);
  1043. X    perror (file);
  1044. X    return (-1);
  1045. X    }
  1046. X    numrules = 0;
  1047. X    addinto = &fencepost;
  1048. X    addinto -> next = (struct RULE *) 0;
  1049. X
  1050. X    while (fgets (buffer, STRINGSIZE, fp))
  1051. X    {
  1052. X    Trim (buffer);
  1053. X
  1054. X    if (!buffer[0] || buffer[0] == '#')
  1055. X    {
  1056. X        continue;
  1057. X    }
  1058. X    scratch = (struct RULE *) malloc (sizeof (struct RULE));
  1059. X
  1060. X    if (!scratch)
  1061. X    {
  1062. X        Log ("LoadRules/malloc() failed! Fatal lack of memory!\n");
  1063. X        exit (1);
  1064. X    }
  1065. X    scratch -> rule = Clone (buffer);
  1066. X
  1067. X    if (!scratch -> rule)
  1068. X    {
  1069. X        Log ("LoadRules/Clone() failed! Fatal lack of memory!\n");
  1070. X        exit (1);
  1071. X    }
  1072. X    scratch -> next = (struct RULE *) 0;
  1073. X    addinto -> next = scratch;
  1074. X    addinto = scratch;
  1075. X    numrules++;
  1076. X    }
  1077. X
  1078. X    fclose (fp);
  1079. X    Log ("Loaded %d rules from '%s'.\n", numrules, file);
  1080. X    *rootpos = fencepost.next;
  1081. X    return (numrules);
  1082. X}
  1083. X/* load a dictionary into a linked list, and sort it */
  1084. X
  1085. Xlong int
  1086. XLoadDict (file, rule, contdict)
  1087. X    char *file;
  1088. X    char *rule;
  1089. X    int contdict;
  1090. X{
  1091. X    int i;
  1092. X    int memfilled;
  1093. X    long int nelem;
  1094. X    long int rejected;
  1095. X    register char *mangle;
  1096. X    register struct DICT *scratch;
  1097. X    char pipebuff[STRINGSIZE];
  1098. X
  1099. X    static FILE *fp;
  1100. X    char buffer[STRINGSIZE];
  1101. X
  1102. X    if (contdict && fp)
  1103. X    {
  1104. X    goto files_open;
  1105. X    }
  1106. X#ifdef COMPRESSION
  1107. X    if (!Suffix (file, ".Z"))
  1108. X    {
  1109. X    sprintf (pipebuff, "%s %s", zcat, file);
  1110. X    if (!(fp = (FILE *) popen (pipebuff, "r")))
  1111. X    {
  1112. X        perror (pipebuff);
  1113. X        return (0);
  1114. X    }
  1115. X    } else if (!Suffix (file, ".z"))
  1116. X    {
  1117. X    sprintf (pipebuff, "%s %s", pcat, file);
  1118. X    if (!(fp = (FILE *) popen (pipebuff, "r")))
  1119. X    {
  1120. X        perror (pipebuff);
  1121. X        return (0);
  1122. X    }
  1123. X    } else
  1124. X#endif    /* COMPRESSION */
  1125. X    {
  1126. X    pipebuff[0] = '\0';
  1127. X    if (!(fp = fopen (file, "r")))
  1128. X    {
  1129. X        perror (file);
  1130. X        return (0);
  1131. X    }
  1132. X    }
  1133. X
  1134. X  files_open:
  1135. X
  1136. X    nelem = 0;
  1137. X    rejected = 0;
  1138. X    memfilled = 0;
  1139. X    dictroot = (struct DICT *) 0;
  1140. X
  1141. X    Log ("%s rule '%s' to file '%s'\n",
  1142. X     contdict ? "Continuing" : "Applying",
  1143. X     rule,
  1144. X     file);
  1145. X
  1146. X    while (fgets (buffer, STRINGSIZE, fp))
  1147. X    {
  1148. X    Trim (buffer);
  1149. X
  1150. X    if (!buffer[0] || buffer[0] == '#')
  1151. X    {
  1152. X        continue;
  1153. X    }
  1154. X    mangle = Mangle (buffer, rule);
  1155. X
  1156. X    if (!mangle)
  1157. X    {
  1158. X        rejected++;
  1159. X
  1160. X        if (verbose_bool)
  1161. X        {
  1162. X        Log ("Rejected '%s' due to rule specs.\n", buffer);
  1163. X        }
  1164. X        continue;
  1165. X    }
  1166. X    if (dictroot && !strncmp (mangle, dictroot -> word, pwlength))
  1167. X    {
  1168. X        rejected++;
  1169. X
  1170. X        if (verbose_bool)
  1171. X        {
  1172. X        Log ("Rejected '%s'; duplicated to %d chars.\n", buffer,
  1173. X             pwlength);
  1174. X        }
  1175. X        continue;
  1176. X    }
  1177. X    i = strlen (mangle);
  1178. X
  1179. X    if (i > pwlength)
  1180. X    {
  1181. X        i = pwlength;
  1182. X    }
  1183. X    scratch = (struct DICT *) malloc (sizeof (struct DICT) + i);
  1184. X
  1185. X    if (!scratch)
  1186. X    {
  1187. X        Log ("LoadDict/malloc() failed! Shameful lack of memory!\n");
  1188. X        memfilled = 1;
  1189. X        goto words_loaded;
  1190. X    }
  1191. X    strncpy (scratch -> word, mangle, i);
  1192. X    scratch -> word[i] = '\0';
  1193. X    scratch -> next = dictroot;
  1194. X    dictroot = scratch;
  1195. X    nelem++;
  1196. X
  1197. X    if (verbose_bool)
  1198. X    {
  1199. X        Log ("Loaded '%s' as '%s' using '%s'\n", buffer,
  1200. X         scratch -> word, rule);
  1201. X    }
  1202. X    }
  1203. X
  1204. X    if (pipebuff[0])
  1205. X    {
  1206. X    pclose (fp);
  1207. X    } else
  1208. X    {
  1209. X    fclose (fp);
  1210. X    }
  1211. X
  1212. X    fp = (FILE *) 0;
  1213. X
  1214. X  words_loaded:
  1215. X
  1216. X    if (nelem == 0)
  1217. X    {
  1218. X    return (0);
  1219. X    }
  1220. X    Log ("Rejected %ld words on loading, %ld words left to sort\n",
  1221. X     rejected, nelem);
  1222. X
  1223. X    dictroot = (struct DICT *) SortDict (dictroot, nelem);
  1224. X
  1225. X    if (memfilled)
  1226. X    {
  1227. X    nelem = -nelem;
  1228. X    }
  1229. X    return (nelem);        /* not strict number anymore... */
  1230. X}
  1231. X/* lose the current dictionary */
  1232. X
  1233. Xint
  1234. XDropDict ()
  1235. X{
  1236. X    register struct DICT *scratch1;
  1237. X    register struct DICT *scratch2;
  1238. X
  1239. X    scratch1 = dictroot;
  1240. X    while (scratch1)
  1241. X    {
  1242. X    scratch2 = scratch1 -> next;
  1243. X    free (scratch1);
  1244. X    scratch1 = scratch2;
  1245. X    }
  1246. X    return (0);
  1247. X}
  1248. X/*
  1249. X * write a feedback file if there is anything to save - return number
  1250. X * uncracked users
  1251. X */
  1252. X
  1253. Xint
  1254. XFeedBack (log_notdone)
  1255. X    int log_notdone;
  1256. X{
  1257. X    register FILE *fp;
  1258. X    static char fmt[] = "%s:%s:%s:%s\n";
  1259. X    register struct USER *head;
  1260. X    register struct USER *arm;
  1261. X    int done;
  1262. X    int notdone;
  1263. X
  1264. X    notdone = done = 0;
  1265. X
  1266. X    if (verbose_bool)
  1267. X    {
  1268. X    Log ("Sweeping data looking for feedback.\n");
  1269. X    }
  1270. X    fp = (FILE *) 0;
  1271. X
  1272. X    for (head = userroot; head; head = head -> next)
  1273. X    {
  1274. X    for (arm = head; arm; arm = arm -> across)
  1275. X    {
  1276. X        if (arm -> done)
  1277. X        {
  1278. X        done++;
  1279. X        /* horrible little hack, vile, sick, I love it */
  1280. X        if (!fp)
  1281. X        {
  1282. X            if (!(fp = fopen (feedbackfile, "w")))
  1283. X            {
  1284. X            perror (feedbackfile);
  1285. X            return (-1);
  1286. X            }
  1287. X            if (verbose_bool)
  1288. X            {
  1289. X            Log ("Feedback file opened for writing.\n");
  1290. X            }
  1291. X        }
  1292. X        fprintf (fp, fmt, feedback_string,
  1293. X             arm -> passwd.pw_passwd, "Y", arm -> passwd_txt);
  1294. X        } else
  1295. X        {
  1296. X        notdone++;
  1297. X        if (log_notdone)
  1298. X        {
  1299. X            if (!fp)    /* and again !!! heheheheheheh */
  1300. X            {
  1301. X            if (!(fp = fopen (feedbackfile, "w")))
  1302. X            {
  1303. X                perror (feedbackfile);
  1304. X                return (-1);
  1305. X            }
  1306. X            if (verbose_bool)
  1307. X            {
  1308. X                Log ("Feedback file opened for writing.\n");
  1309. X            }
  1310. X            }
  1311. X            /* I think I'm going slightly warped */
  1312. X            fprintf (fp, fmt, feedback_string,
  1313. X                 arm -> passwd.pw_passwd, "N", "");
  1314. X        }
  1315. X        }
  1316. X
  1317. X    }
  1318. X    }
  1319. X    if (fp)
  1320. X    {
  1321. X    fclose (fp);
  1322. X    Log ("Closing feedback file.\n");
  1323. X    }
  1324. X    Log ("FeedBack: %d users done, %d users left to crack.\n", done, notdone);
  1325. X    return (notdone);
  1326. X}
  1327. X/* try a chain of users with the same salt */
  1328. X
  1329. Xint
  1330. XTryManyUsers (eptr, guess)    /* returns 0 if all done this chain */
  1331. X    register struct USER *eptr;
  1332. X    char *guess;
  1333. X{
  1334. X    register int retval;
  1335. X    char guess_crypted[STRINGSIZE];
  1336. X
  1337. X    if (eptr -> done && !eptr -> across)
  1338. X    {
  1339. X    return (0);
  1340. X    }
  1341. X    strcpy (guess_crypted, crypt (guess, eptr -> passwd.pw_passwd));
  1342. X
  1343. X    retval = 0;
  1344. X
  1345. X    while (eptr)
  1346. X    {
  1347. X    if (verbose_bool)
  1348. X    {
  1349. X        Log ("Trying '%s' on %s from line %s\n",
  1350. X         guess,
  1351. X         eptr -> passwd.pw_name,
  1352. X         eptr -> filename);
  1353. X    }
  1354. X    if (!eptr -> done && !STRCMP (guess_crypted, eptr -> passwd.pw_passwd))
  1355. X    {
  1356. X        PrintGuess (eptr, guess);
  1357. X    }
  1358. X    retval += (!(eptr -> done));
  1359. X    eptr = eptr -> across;
  1360. X    }
  1361. X
  1362. X    return (retval);
  1363. X}
  1364. X/* try a word on an individual */
  1365. X
  1366. Xint
  1367. XTryOneUser (eptr, guess)    /* returns non-null on guessed user */
  1368. X    register struct USER *eptr;
  1369. X    register char *guess;
  1370. X{
  1371. X    if (!guess || !*guess || eptr -> done)
  1372. X    {
  1373. X    return (0);
  1374. X    }
  1375. X    if (verbose_bool)
  1376. X    {
  1377. X    Log ("Trying '%s' on %s from %s\n",
  1378. X         guess,
  1379. X         eptr -> passwd.pw_name,
  1380. X         eptr -> filename);
  1381. X    }
  1382. X    if (strcmp (crypt (guess, eptr -> passwd.pw_passwd),
  1383. X        eptr -> passwd.pw_passwd))
  1384. X    {
  1385. X    return (0);
  1386. X    }
  1387. X    PrintGuess (eptr, guess);
  1388. X
  1389. X    return (1);
  1390. X}
  1391. X/* frontend to TryOneUser() to save hassle */
  1392. X
  1393. Xint
  1394. XWordTry (entry_ptr, guess)
  1395. X    register struct USER *entry_ptr;
  1396. X    register char *guess;
  1397. X{
  1398. X    struct RULE *ruleptr;
  1399. X    register char *mangle;
  1400. X
  1401. X    if (!guess[0] || !guess[1])
  1402. X    {
  1403. X    return (0);
  1404. X    }
  1405. X    for (ruleptr = gecosroot; ruleptr; ruleptr = ruleptr -> next)
  1406. X    {
  1407. X    if (mangle = Mangle (guess, ruleptr -> rule))
  1408. X    {
  1409. X        if (TryOneUser (entry_ptr, mangle))
  1410. X        {
  1411. X        return (1);
  1412. X        }
  1413. X    }
  1414. X    }
  1415. X    return (0);
  1416. X}
  1417. X/* Special manipulations for the GECOS field and dotfiles */
  1418. X
  1419. Xint
  1420. XParseBuffer (entry_ptr, buffer, advanced)
  1421. X    register struct USER *entry_ptr;
  1422. X    char *buffer;
  1423. X    int advanced;
  1424. X{
  1425. X    int wordcount;
  1426. X    register int i;
  1427. X    register int j;
  1428. X    register char *ptr;
  1429. X    char junk[STRINGSIZE];
  1430. X    char *words[WORDSTACKSIZE];
  1431. X
  1432. X    /* zap all punctuation */
  1433. X    for (ptr = buffer; *ptr; ptr++)
  1434. X    {
  1435. X    if (ispunct (*ptr) || isspace (*ptr))
  1436. X    {
  1437. X        *ptr = ' ';
  1438. X    }
  1439. X    }
  1440. X
  1441. X    /* break up all individual words */
  1442. X    wordcount = 0;
  1443. X    ptr = buffer;
  1444. X    while (*ptr)
  1445. X    {
  1446. X    while (*ptr && isspace (*ptr))
  1447. X    {
  1448. X        ptr++;
  1449. X    }
  1450. X
  1451. X    if (*ptr)
  1452. X    {
  1453. X        words[wordcount++] = ptr;
  1454. X        if (wordcount >= WORDSTACKSIZE)
  1455. X        {
  1456. X        Log ("ParseBuffer: Abort: Stack Full !\n");
  1457. X        return (0);
  1458. X        }
  1459. X    }
  1460. X    while (*ptr && !isspace (*ptr))
  1461. X    {
  1462. X        ptr++;
  1463. X    }
  1464. X
  1465. X    if (*ptr)
  1466. X    {
  1467. X        *(ptr++) = '\0';
  1468. X    }
  1469. X    }
  1470. X
  1471. X    words[wordcount] = (char *) 0;
  1472. X
  1473. X    /* try all the words individually */
  1474. X    if (verbose_bool)
  1475. X    {
  1476. X    Log ("Trying individual words\n");
  1477. X    }
  1478. X    for (i = 0; i < wordcount; i++)
  1479. X    {
  1480. X    if (WordTry (entry_ptr, words[i]))
  1481. X    {
  1482. X        return (1);
  1483. X    }
  1484. X    }
  1485. X
  1486. X    if (!advanced)
  1487. X    {
  1488. X    return (0);
  1489. X    }
  1490. X    /* try pairings of words */
  1491. X    if (verbose_bool)
  1492. X    {
  1493. X    Log ("Trying paired words\n");
  1494. X    }
  1495. X    for (j = 1; j < wordcount; j++)
  1496. X    {
  1497. X    for (i = 0; i < j; i++)
  1498. X    {
  1499. X        /* Skip initials for next pass */
  1500. X        if (!words[i][1] || !words[j][1])
  1501. X        {
  1502. X        continue;
  1503. X        }
  1504. X        strcpy (junk, words[i]);
  1505. X        strcat (junk, words[j]);
  1506. X
  1507. X        if (WordTry (entry_ptr, junk))
  1508. X        {
  1509. X        return (1);
  1510. X        }
  1511. X        strcpy (junk, words[j]);
  1512. X        strcat (junk, words[i]);
  1513. X
  1514. X        if (WordTry (entry_ptr, junk))
  1515. X        {
  1516. X        return (1);
  1517. X        }
  1518. X    }
  1519. X    }
  1520. X
  1521. X    /* try initials + words */
  1522. X    if (verbose_bool)
  1523. X    {
  1524. X    Log ("Trying initial'ed words\n");
  1525. X    }
  1526. X    for (j = 1; j < wordcount; j++)
  1527. X    {
  1528. X    for (i = 0; i < j; i++)
  1529. X    {
  1530. X        junk[0] = words[i][0];
  1531. X        junk[0] = CRACK_TOUPPER (junk[0]);
  1532. X        strcpy (junk + 1, words[j]);
  1533. X        if (WordTry (entry_ptr, junk))
  1534. X        {
  1535. X        return (1);
  1536. X        }
  1537. X    }
  1538. X    }
  1539. X
  1540. X    return (0);
  1541. X}
  1542. X/* run over password entries looking for passwords */
  1543. X
  1544. Xvoid
  1545. XPass1 ()
  1546. X{
  1547. X    struct USER *head;
  1548. X    char junk[DOTFILESIZE];
  1549. X    register struct USER *this;
  1550. X
  1551. X#ifdef CRACK_DOTFILES
  1552. X#ifdef CRACK_DOTSANE
  1553. X#include <sys/types.h>
  1554. X#include <sys/stat.h>
  1555. X    struct stat sb;
  1556. X#endif    /* CRACK_DOTSANE */
  1557. X    int i;
  1558. X    int j;
  1559. X    FILE *fp;
  1560. X    char filename[STRINGSIZE];
  1561. X    static char *dotfiles[] =
  1562. X    {
  1563. X    ".plan",
  1564. X    ".project",
  1565. X    ".signature",
  1566. X    (char *) 0
  1567. X    };
  1568. X#endif    /* CRACK_DOTFILES */
  1569. X
  1570. X    Log ("Starting pass 1 - password information\n");
  1571. X
  1572. X    for (head = userroot; head; head = head -> next)
  1573. X    {
  1574. X    for (this = head; this; this = this -> across)
  1575. X    {
  1576. X        strcpy (junk, this -> passwd.pw_gecos);
  1577. X
  1578. X        if (WordTry (this, this -> passwd.pw_name) ||
  1579. X        ParseBuffer (this, junk, 1))
  1580. X        {
  1581. X        continue;
  1582. X        }
  1583. X#ifdef CRACK_DOTFILES
  1584. X        for (i = 0; dotfiles[i]; i++)
  1585. X        {
  1586. X        sprintf (filename, "%s/%s", this -> passwd.pw_dir, dotfiles[i]);
  1587. X#ifdef CRACK_DOTSANE
  1588. X        if (stat (filename, &sb) < 0)
  1589. X        {
  1590. X            continue;
  1591. X        }
  1592. X        if ((!(sb.st_mode & S_IFREG))
  1593. X#ifdef S_IFSOCK
  1594. X            || ((sb.st_mode & S_IFSOCK) == S_IFSOCK)
  1595. X#endif    /* S_IFSOCK */
  1596. X            )
  1597. X        {
  1598. X            continue;
  1599. X        }
  1600. X#endif    /* CRACK_DOTSANE */
  1601. X
  1602. X        if (!(fp = fopen (filename, "r")))
  1603. X        {
  1604. X            continue;
  1605. X        }
  1606. X        j = fread (junk, 1, DOTFILESIZE, fp);
  1607. X        fclose (fp);
  1608. X
  1609. X        if (j <= 2)
  1610. X        {
  1611. X            continue;
  1612. X        }
  1613. X        junk[j - 1] = '\0';    /* definite terminator */
  1614. X
  1615. X        if (verbose_bool)
  1616. X        {
  1617. X            Log ("DOTFILES: Checking %d bytes of %s\n", j, filename);
  1618. X        }
  1619. X        if (ParseBuffer (this, junk, 0))
  1620. X        {
  1621. X            continue;
  1622. X        }
  1623. X        }
  1624. X#endif    /* CRACK_DOTFILES */
  1625. X    }
  1626. X    }
  1627. X    return;
  1628. X}
  1629. X
  1630. Xvoid
  1631. XPass2 (dictfile)
  1632. X    char *dictfile;
  1633. X{
  1634. X    int pointuser;
  1635. X    struct USER *headptr;
  1636. X    struct RULE *ruleptr;
  1637. X    struct DICT *dictptr;
  1638. X
  1639. X    Log ("Starting pass 2 - dictionary words\n");
  1640. X    headptr = (struct USER *) 0;
  1641. X    ruleptr = (struct RULE *) 0;
  1642. X
  1643. X    /* check if we are recovering from a crash */
  1644. X    if (recover_bool)
  1645. X    {
  1646. X    recover_bool = 0;    /* switch off */
  1647. X
  1648. X    for (ruleptr = ruleroot;
  1649. X         ruleptr && strcmp (ruleptr -> rule, old_rule);
  1650. X         ruleptr = ruleptr -> next);
  1651. X
  1652. X    if (!ruleptr)
  1653. X    {
  1654. X        Log ("Fatal: Ran off end of list looking for rule '%s'\n",
  1655. X         old_rule);
  1656. X        exit (1);
  1657. X    }
  1658. X    for (headptr = userroot;/* skip right number of users */
  1659. X         headptr && old_usernum--;
  1660. X         headptr = headptr -> next);
  1661. X
  1662. X    if (!headptr)
  1663. X    {
  1664. X        Log ("Fatal: Ran off end of list looking for user '%s'\n",
  1665. X         old_username);
  1666. X        exit (1);
  1667. X    }
  1668. X    }
  1669. X    /* start iterating here */
  1670. X    for (ruleptr = (ruleptr ? ruleptr : ruleroot);
  1671. X     ruleptr;
  1672. X     ruleptr = ruleptr -> next)
  1673. X    {
  1674. X    long int rval;
  1675. X    int continue_dict;
  1676. X
  1677. X    continue_dict = 0;
  1678. X
  1679. X      load_dict:
  1680. X    rval = LoadDict (dictfile, ruleptr -> rule, continue_dict);
  1681. X
  1682. X    if (rval == 0)
  1683. X    {
  1684. X        Log ("Oops! I got an empty dictionary! Skipping rule '%s'!\n",
  1685. X         ruleptr -> rule);
  1686. X        continue;
  1687. X    }
  1688. X    pointuser = 0;
  1689. X
  1690. X    /* iterate all the users */
  1691. X    for (headptr = (headptr ? headptr : userroot);
  1692. X         headptr;
  1693. X         headptr = headptr -> next)
  1694. X    {
  1695. X        SetPoint (dictfile,
  1696. X              ruleptr -> rule,
  1697. X              pointuser++,
  1698. X              headptr -> passwd.pw_name);
  1699. X
  1700. X        /* iterate all the words */
  1701. X        for (dictptr = dictroot;
  1702. X         dictptr;
  1703. X         dictptr = dictptr -> next)
  1704. X        {
  1705. X        /* skip repeated words... */
  1706. X        if (!TryManyUsers (headptr, dictptr -> word))
  1707. X        {
  1708. X            break;
  1709. X        }
  1710. X        }
  1711. X    }
  1712. X
  1713. X    /* free up memory */
  1714. X    DropDict ();
  1715. X
  1716. X    /* write feedback file */
  1717. X    if (!FeedBack (0))
  1718. X    {
  1719. X        Log ("FeedBack: All Users Are Cracked! Bloody Hell!\n");
  1720. X        return;
  1721. X    }
  1722. X    /* on next pass, start from top of user list */
  1723. X    headptr = (struct USER *) 0;
  1724. X
  1725. X    /* did we REALLY finish this dictionary ? */
  1726. X    if (rval < 0)
  1727. X    {
  1728. X        continue_dict = 1;
  1729. X        goto load_dict;
  1730. X    }
  1731. X    }
  1732. X}
  1733. X
  1734. Xint
  1735. Xmain (argc, argv)
  1736. X    int argc;
  1737. X    char *argv[];
  1738. X{
  1739. X    int i;
  1740. X    long t;
  1741. X    int uerr;
  1742. X    int die_bool = 0;
  1743. X    FILE *fp;
  1744. X    char *crack_out;
  1745. X    extern int optind;
  1746. X    extern char *optarg;
  1747. X    static char getopt_string[] = "i:fX:n:r:vml:";
  1748. X
  1749. X    uerr = 0;
  1750. X
  1751. X    if (argc == 1)
  1752. X    {
  1753. X    uerr++;
  1754. X    }
  1755. X    while ((i = getopt (argc, argv, getopt_string)) != EOF)
  1756. X    {
  1757. X    switch (i)
  1758. X    {
  1759. X    case 'i':
  1760. X        strcpy (input_file, optarg);
  1761. X        if (!freopen (input_file, "r", stdin))
  1762. X        {
  1763. X        perror (input_file);
  1764. X        exit (1);
  1765. X        }
  1766. X        if (!strncmp (input_file, "/tmp/pw.", 7))
  1767. X        {
  1768. X        unlink (input_file);
  1769. X        }
  1770. X        break;
  1771. X    case 'm':
  1772. X        mail_bool = 1;
  1773. X        break;
  1774. X    case 'f':
  1775. X        foreground_bool = 1;
  1776. X        break;
  1777. X    case 'X':
  1778. X        remote_bool = 1;
  1779. X        strcpy (supplied_name, optarg);
  1780. X        break;
  1781. X    case 'l':
  1782. X        pwlength = atoi (optarg);
  1783. X        break;
  1784. X    case 'n':
  1785. X        nice_value = atoi (optarg);
  1786. X        nice (nice_value);
  1787. X        break;
  1788. X    case 'r':
  1789. X        recover_bool = 1;
  1790. X        strcpy (recover_file, optarg);
  1791. X        break;
  1792. X    case 'v':
  1793. X        verbose_bool = 1;
  1794. X        break;
  1795. X    default:
  1796. X    case '?':
  1797. X        uerr++;
  1798. X        break;
  1799. X    }
  1800. X    }
  1801. X
  1802. X    if (optind >= argc)
  1803. X    {
  1804. X    uerr++;
  1805. X    }
  1806. X    if (uerr)
  1807. X    {
  1808. X    fprintf (stderr,
  1809. X         "Usage:\t%s -%s dictfile [dictfile...]\n",
  1810. X         argv[0],
  1811. X         getopt_string);
  1812. X    exit (1);
  1813. X    }
  1814. X    pid = getpid ();
  1815. X
  1816. X    if (gethostname (this_hostname, STRINGSIZE))
  1817. X    {
  1818. X    perror ("gethostname");
  1819. X    }
  1820. X    if (!(crack_out = (char *) getenv ("CRACK_OUT")))
  1821. X    {
  1822. X    crack_out = ".";
  1823. X    }
  1824. X    sprintf (opfile, "%s/out.%s%d", crack_out, this_hostname, pid);
  1825. X
  1826. X    if (remote_bool)
  1827. X    {
  1828. X    sprintf (diefile, "%s", supplied_name);
  1829. X    } else
  1830. X    {
  1831. X    sprintf (diefile, "%s/D%s%d", runtime, this_hostname, pid);
  1832. X    }
  1833. X    sprintf (pointfile, "%s/P%s%d", runtime, this_hostname, pid);
  1834. X    sprintf (feedbackfile, "%s/F%s%d", runtime, this_hostname, pid);
  1835. X
  1836. X    if (!foreground_bool)
  1837. X    {
  1838. X    if (!freopen (opfile, "w", stdout))
  1839. X    {
  1840. X        perror ("freopen(stdout)");
  1841. X        exit (1);
  1842. X    }
  1843. X    if (!freopen (opfile, "a", stderr))
  1844. X    {
  1845. X        perror ("freopen(stderr)");
  1846. X        exit (1);
  1847. X    }
  1848. X    }
  1849. X    /*
  1850. X     * don't generate a die file unless we are not 'attached' to a
  1851. X     * terminal...  except when we are remote as well...
  1852. X     */
  1853. X
  1854. X    time (&t);
  1855. X
  1856. X    if (!foreground_bool || (foreground_bool && remote_bool))
  1857. X    {
  1858. X    if (!(fp = fopen (diefile, "w")))
  1859. X    {
  1860. X        perror (diefile);
  1861. X        exit (1);
  1862. X    }
  1863. X    die_bool = 1;
  1864. X    fprintf (fp, "#!/bin/sh\n");
  1865. X    fprintf (fp, "# ID=%s.%d start=%s", this_hostname, pid, ctime (&t));
  1866. X    fprintf (fp, "kill -TERM %d && rm $0", pid);
  1867. X    fclose (fp);
  1868. X    chmod (diefile, 0700);
  1869. X    }
  1870. X    Log ("Crack v%s: The Password Cracker, (c) Alec D.E. Muffett, 1992\n",
  1871. X     version);
  1872. X
  1873. X#ifdef FCRYPT
  1874. X    init_des ();
  1875. X#endif
  1876. X
  1877. X    /* Quick, verify that we are sane ! */
  1878. X
  1879. X    if (strcmp (crypt ("fredfred", "fredfred"), "frxWbx4IRuBBA"))
  1880. X    {
  1881. X    Log ("Version of crypt() being used internally is not compatible with standard.\n");
  1882. X    Log ("This could be due to byte ordering problems - see the comments in Sources/conf.h\n");
  1883. X    Log ("If there is another reason for this, edit the source to remove this assertion.\n");
  1884. X    Log ("Terminating...\n");
  1885. X    exit (0);
  1886. X    }
  1887. X#ifndef AMIGA
  1888. X    signal (SIGTERM, CatchTERM);
  1889. X#endif
  1890. X
  1891. X    Log ("Loading Data, host=%s pid=%d\n", this_hostname, pid);
  1892. X
  1893. X    if (LoadData () <= 0)
  1894. X    {
  1895. X    Log ("Nothing to Crack. Exiting...\n");
  1896. X    exit (0);
  1897. X    }
  1898. X    if (LoadRules (rulefile, &ruleroot) < 0 ||
  1899. X    LoadRules (gecosfile, &gecosroot) < 0)
  1900. X    {
  1901. X    exit (1);
  1902. X    }
  1903. X    if (!recover_bool)
  1904. X    {
  1905. X    /* We are starting afresh ! Ah, the birds in May ! */
  1906. X    Pass1 ();
  1907. X
  1908. X    if (!FeedBack (0))
  1909. X    {
  1910. X        Log ("FeedBack: information: all users are cracked after gecos pass\n");
  1911. X        goto finish_crack;
  1912. X    }
  1913. X    } else
  1914. X    {
  1915. X    int rval;
  1916. X
  1917. X    if (rval = GetPoint (recover_file))
  1918. X    {
  1919. X        Log ("Recovery from file %s not permitted on this host [code %d]\n",
  1920. X         recover_file,
  1921. X         rval);
  1922. X        exit (0);
  1923. X
  1924. X    }
  1925. X    /* Some spodulous creep pulled our plug... */
  1926. X    while ((optind < argc) && strcmp (argv[optind], old_dictname))
  1927. X    {
  1928. X        optind++;
  1929. X    }
  1930. X    }
  1931. X
  1932. X    for (i = optind; i < argc; i++)
  1933. X    {
  1934. X    Pass2 (argv[i]);
  1935. X    }
  1936. X
  1937. X    Log ("Tidying up files...\n");
  1938. X    FeedBack (1);
  1939. X
  1940. X  finish_crack:
  1941. X
  1942. X    if (die_bool)
  1943. X    {
  1944. X    unlink (diefile);
  1945. X    }
  1946. X    unlink (pointfile);
  1947. X
  1948. X    Log ("Done.\n");
  1949. X
  1950. X    return (0);
  1951. X}
  1952. END_OF_FILE
  1953. if test 22280 -ne `wc -c <'Sources/crack-pwc.c'`; then
  1954.     echo shar: \"'Sources/crack-pwc.c'\" unpacked with wrong size!
  1955. fi
  1956. # end of 'Sources/crack-pwc.c'
  1957. fi
  1958. echo shar: End of archive 3 \(of 5\).
  1959. cp /dev/null ark3isdone
  1960. MISSING=""
  1961. for I in 1 2 3 4 5 ; do
  1962.     if test ! -f ark${I}isdone ; then
  1963.     MISSING="${MISSING} ${I}"
  1964.     fi
  1965. done
  1966. if test "${MISSING}" = "" ; then
  1967.     echo You have unpacked all 5 archives.
  1968.     rm -f ark[1-9]isdone
  1969. else
  1970.     echo You still need to unpack the following archives:
  1971.     echo "        " ${MISSING}
  1972. fi
  1973. ##  End of shell archive.
  1974. exit 0
  1975. exit 0 # Just in case...
  1976.