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