|
|
1.1 ! root 1: #include "authmgr.h" ! 2: ! 3: char admins[128]; ! 4: int max_failures = MAX_FAILURES; ! 5: struct disallow* badlist; ! 6: int pushed_ld; ! 7: int gnotflg = 0; /* set if we shouldn't ask for a new number */ ! 8: int dconflg = 0; /* set if real dest is dcon/mesgdcon */ ! 9: int usepasswd = 0; /* set if we should ignore the key file */ ! 10: ! 11: char dialbuf[128]; ! 12: char* dialstring; /* dialstring from CSOURCE params */ ! 13: char physource[128]; /* the switch.mod.chan stuff from CSOURCE */ ! 14: char srcid[128]=""; /* the first field in CSOURCE */ ! 15: char username[16]=""; /* the user's login name from CSOURCE */ ! 16: char eusername[30]=""; /* effective login name */ ! 17: char nettype[16]; /* shouldn't get bigger than this */ ! 18: char options[16] ; ! 19: char redialbuf[128] ; ! 20: char defsvc[16]=""; /* default service */ ! 21: FILE *log=0; /* log file */ ! 22: ! 23: struct secmap *secidlist; /* list of security ID mappings */ ! 24: ! 25: #define MLIST_SIZE 10 ! 26: regsubexp mlist[MLIST_SIZE]; /* a match list for regexec */ ! 27: ! 28: char* SYNTAX = "authmgr: Syntax error at line %d of control file\n"; ! 29: #define DCON_CHALLENGE "CH" /* the dcon challenge response */ ! 30: ! 31: int init(); /*forward*/ ! 32: extern struct keyinfo* getkeyinfo(); ! 33: char *makesourceid(); /*forward*/ ! 34: char *getenv(); ! 35: char *getpass(); ! 36: ! 37: /* ! 38: * security - an authentication server ! 39: * ! 40: * For a given user, this locates that user's key in the ! 41: * key database, challenges the user to encrypt some data, ! 42: * and compares that user's result with the result of ! 43: * encrypting the data with the user's real key. If the ! 44: * results are the same, the user is authenticated, otherwise, ! 45: * no. ! 46: */ ! 47: main(argc, argv) ! 48: int argc; ! 49: char* argv[]; ! 50: { ! 51: int i, rc; ! 52: char buf[128]; ! 53: char logname[30], logtries[128]; ! 54: char *bp, *dp; ! 55: struct keyinfo *kp; ! 56: unsigned data, l, r; ! 57: ipcinfo info; ! 58: struct tm *tm = localtime(time((long *) 0)); ! 59: long now = tm->tm_mday + 100*(tm->tm_mon) + 10000*(tm->tm_yday); ! 60: ! 61: if(rc=init(argc, argv) != 0) { ! 62: puts("REFUSED"); ! 63: exit(rc); ! 64: } ! 65: ! 66: ! 67: /* main protocol section */ ! 68: for(i=0; i<max_failures; i++) { ! 69: if(dconflg || gnotflg) { ! 70: printf("%s", DCON_CHALLENGE); ! 71: if(safegets(buf, sizeof(buf)) == NULL) ! 72: exit(0); ! 73: logname[8] = '\0'; ! 74: strncpy(logname, buf, 8); ! 75: kp = getkeyinfo(logname, usepasswd); ! 76: bp = (*kp->kt->chal)(kp); ! 77: if(bp) ! 78: printf("%s\n", bp); /* send the challenge */ ! 79: else ! 80: putchar('\n'); ! 81: if(safegets(buf, sizeof(buf)) == NULL) ! 82: exit(0); ! 83: } else { ! 84: if(*eusername != '\0') { ! 85: strcpy(logname, eusername); ! 86: *eusername = '\0'; ! 87: printf("login: %s\n", logname); ! 88: } else { ! 89: printf("login: "); ! 90: if(safegets(logname, sizeof(logname)) == NULL || *logname == '\0') ! 91: exit(0); ! 92: } ! 93: kp = getkeyinfo(logname, usepasswd); ! 94: bp = (*kp->kt->chal)(kp); ! 95: if(bp) { ! 96: printf("Enter response code for %s: ", bp); ! 97: if(safegets(buf, sizeof(buf)) == NULL || buf[0] == '\0') ! 98: exit(0); ! 99: } else { ! 100: printf("Password: "); ! 101: readnoecho(buf, sizeof buf); ! 102: } ! 103: } ! 104: (void) strcat(logtries, logname); ! 105: (void) strcat(logtries, " "); ! 106: strcpy(eusername, logname); ! 107: ! 108: if((kp->expire >= now) && (*kp->kt->comp)(kp, buf) == 0) { ! 109: goto success; ! 110: } ! 111: } ! 112: ! 113: doadmin(logtries); ! 114: puts("REFUSED"); ! 115: exit(1); ! 116: success: ! 117: /* if no dialstring, ask for one */ ! 118: /* if dconflg is set, dialstring isn't 0 */ ! 119: if(dialstring == 0 || *dialstring == 0) { ! 120: i = 0; ! 121: while(i < max_failures) { ! 122: printf("\nDestination please: "); ! 123: fflush(stdout); ! 124: if(safegets(dialbuf, sizeof dialbuf) == NULL) ! 125: exit(0); ! 126: dialstring = dialbuf; ! 127: while(*dialstring == ' ' || *dialstring == '\t') ! 128: *dialstring++; ! 129: for(dp = dialstring; ! 130: *dp != '\0' && *dp != ' ' && *dp != '\t'; dp++) ! 131: ; ! 132: *dp = '\0'; ! 133: if(*dialstring != '\0') ! 134: break; ! 135: i++ ; ! 136: } ! 137: if(i == max_failures) { ! 138: puts("\nNo new dialstring. Goodbye.\n"); ! 139: exit(1); ! 140: } ! 141: } ! 142: ! 143: if (gnotflg) ! 144: options[0] = 'U' ; ! 145: else ! 146: options[0] = '-' ; ! 147: options[1] = 0 ; ! 148: ! 149: /* using "dialstring", send a redial msg to mgr */ ! 150: strcpy(redialbuf, options) ; ! 151: strcat(redialbuf, ">") ; ! 152: strcat(redialbuf, dialstring) ; ! 153: ! 154: info.rfd = -1; ! 155: info.cfd = 0; /* pass back fd 0 */ ! 156: info.myname = NULL; ! 157: info.user = logname; ! 158: info.machine = ""; ! 159: info.uid = info.gid = -1; ! 160: info.name = ipcpath(redialbuf, nettype, defsvc); ! 161: info.param = "light"; /* bogus */ ! 162: info.flags = 0; ! 163: if (log != 0) { ! 164: lognow(); ! 165: fprintf(log, "%s %s (%s) redialing to %s\n", ! 166: srcid, username, eusername, info.name); ! 167: fclose(log); ! 168: } ! 169: if(pushed_ld) ! 170: ioctl(0, FIOPOPLD, (void *)0); ! 171: if(ipcredial(&info) != 0) ! 172: ; /* should complain somehow! */ ! 173: exit(0); ! 174: } ! 175: ! 176: int ! 177: init(ac, av) ! 178: int ac; ! 179: char* av[]; ! 180: { ! 181: FILE* cf; ! 182: char line[128] ; ! 183: #define NFLDS 10 ! 184: char *fld[NFLDS]; ! 185: int l, i, j, errflg = 0; ! 186: struct disallow *d = 0, *dp; ! 187: struct secmap *sp, *slp = 0; ! 188: regexp *prog; ! 189: char *c, *c2 = 0; ! 190: char *cntlfile = CONTROL_FILE; ! 191: int seen_defmap = 0; ! 192: char *malloc(); ! 193: extern char *optarg; ! 194: extern int optind; ! 195: ! 196: while((i = getopt(ac, av, "nf:")) != -1) ! 197: switch(i) { ! 198: case 'n': ! 199: gnotflg++; ! 200: break; ! 201: case 'f': ! 202: cntlfile = optarg; ! 203: break; ! 204: case '?': ! 205: errflg++; ! 206: break; ! 207: } ! 208: if(errflg) { ! 209: fprintf(stderr, "authmgr: bad arglist\n"); ! 210: return 1; ! 211: } ! 212: strcpy(physource, "auth1.1.1.F"); ! 213: chdir("/tmp"); /* in case of core dumps; I wanna find them */ ! 214: c = getenv("CSOURCE"); ! 215: if(c) { ! 216: /* this "knows" the format of a CSOURCE */ ! 217: if(strncmp(c, "source=", 7) == 0) { ! 218: c += 7; ! 219: c2 = nettype; ! 220: while(*c != '!') ! 221: *c2++ = *c++; ! 222: *c2 = '\0'; ! 223: ! 224: c++; ! 225: c2 = srcid; ! 226: while(*c != ' ') ! 227: *c2++ = *c++; ! 228: *c2 = '\0'; ! 229: } else ! 230: strcpy(nettype, "dk"); /* XXX */ ! 231: ! 232: while(c = strchr(c, ' ')) { ! 233: c++; ! 234: if(strncmp(c, "user=", 5) == 0) { ! 235: c += 5; ! 236: c2 = username; ! 237: i = 0; ! 238: while(*c != ' ') { ! 239: if(*c >= '0' && *c <= '9') ! 240: i++; ! 241: *c2++ = *c++; ! 242: } ! 243: *c2 = '\0'; ! 244: c++; ! 245: /* ! 246: * ignore the user name if it's numeric or ! 247: * if it's the magic unknown user ! 248: */ ! 249: if(i == strlen(username) || strcmp(username, "_unknown_") == 0) ! 250: username[0] = '\0'; ! 251: } ! 252: if(strncmp(c, "line=", 5) == 0) { ! 253: strcpy(physource, c+5); ! 254: break; ! 255: } ! 256: } ! 257: } ! 258: strcpy(eusername, username); ! 259: c = getenv("CDEST"); ! 260: if(c) { ! 261: strcpy(line, c); ! 262: c = line; ! 263: setfields("!"); ! 264: i = getfields(c, fld, NFLDS); ! 265: if(i >= 4) { ! 266: /* check if it matches my service; if so, ignore it */ ! 267: j = strlen(fld[2]); ! 268: if((i = strlen(fld[3])) <= j || ! 269: strcmp(&fld[3][i-j], fld[2]) != 0) { ! 270: strcpy(dialbuf, fld[3]); ! 271: dialstring = dialbuf; ! 272: } ! 273: } ! 274: } ! 275: ! 276: if(dialstring != NULL) { ! 277: if((i = strlen(dialstring)) > 4 && ! 278: strcmp(&dialstring[i-4], "dcon") == 0) ! 279: dconflg++; ! 280: } ! 281: if(!dconflg && !gnotflg) ! 282: printf("Security Authentication check\n\n"); ! 283: ! 284: if((cf = fopen(cntlfile, "r")) == NULL) { ! 285: fprintf(stderr, "authmgr: No control file\n"); ! 286: return 2; ! 287: } ! 288: ! 289: setfields(" \t"); ! 290: l = 0; ! 291: while(fgets(line, 128, cf) != NULL) { ! 292: l++; ! 293: for(i=0; line[i] == ' ' || line[i] == '\t'; i++) ! 294: ; ! 295: if(line[i] == '#') /* ignore comments */ ! 296: continue; ! 297: if((c = strchr(&line[i], '\n')) != NULL) /* strip newline */ ! 298: *c = '\0'; ! 299: ! 300: i = getmfields(&line[i], fld, NFLDS); ! 301: if(i == 0) /* blank line */ ! 302: continue; ! 303: ! 304: if(strcmp(fld[0], "admin") == 0) { ! 305: if(i < 2) { ! 306: fprintf(stderr, SYNTAX, l); ! 307: return 3; ! 308: } ! 309: (void) strcpy(admins, fld[1]); ! 310: for(j=2; j<i; j++) { ! 311: strcat(admins, " "); ! 312: strcat(admins, fld[j]); ! 313: } ! 314: } else if(strcmp(fld[0], "failures") == 0) { ! 315: if(i != 2 || (max_failures = atoi(fld[1])) < 3) { ! 316: fprintf(stderr, SYNTAX, l); ! 317: return 4; ! 318: } ! 319: } else if(strcmp(fld[0], "disallow") == 0) { ! 320: if(i != 2) { ! 321: fprintf(stderr, SYNTAX, l); ! 322: return 5; ! 323: } ! 324: dp = (struct disallow*) malloc(sizeof(struct disallow)); ! 325: if(dp == 0) { ! 326: fprintf(stderr, "authmgr: out of memory\n"); ! 327: return 6; ! 328: } ! 329: (void) strncpy(dp->logname, fld[1], 8); ! 330: dp->logname[8] = '\0'; ! 331: dp->next = NULL; ! 332: if(d == 0) { ! 333: badlist = d = dp; ! 334: } else { ! 335: d->next = dp; ! 336: d = dp; ! 337: } ! 338: } else if(strcmp(fld[0], "usepasswd") == 0) { ! 339: if(i != 2) { ! 340: fprintf(stderr, SYNTAX, l); ! 341: return 7; ! 342: } ! 343: if((prog = regcomp(fld[1])) == NULL) { ! 344: fprintf(stderr, SYNTAX, l); ! 345: free((char*)prog); ! 346: return 8; ! 347: } ! 348: if(regexec(prog, srcid, mlist, MLIST_SIZE) != 0) { ! 349: usepasswd++; ! 350: } ! 351: } else if(strcmp(fld[0], "setuser") == 0) { ! 352: if((i < 2) | (i > 3)) { ! 353: fprintf(stderr, SYNTAX, l); ! 354: return 9; ! 355: } ! 356: if((prog = regcomp(fld[1])) == NULL) { ! 357: fprintf(stderr, SYNTAX, l); ! 358: free((char*)prog); ! 359: return 10; ! 360: } ! 361: if(regexec(prog, srcid, mlist, MLIST_SIZE) != 0) { ! 362: if (i == 2) ! 363: eusername[0] = '\0'; ! 364: else { ! 365: strncpy(eusername, fld[2], 8); ! 366: eusername[8] = '\0'; ! 367: } ! 368: } ! 369: } else if(strcmp(fld[0], "setsvc") == 0) { ! 370: if(i != 3) { ! 371: fprintf(stderr, SYNTAX, l); ! 372: return 11; ! 373: } ! 374: if((prog = regcomp(fld[1])) == NULL) { ! 375: fprintf(stderr, SYNTAX, l); ! 376: free((char*)prog); ! 377: return 12; ! 378: } ! 379: if(regexec(prog, srcid, mlist, MLIST_SIZE) == 0) ! 380: continue; ! 381: strncpy(defsvc, fld[2], 16); ! 382: defsvc[16]='\0'; ! 383: } else if(strcmp(fld[0], "setlog") == 0) { ! 384: if(i != 3) { ! 385: fprintf(stderr, SYNTAX, l); ! 386: return 13; ! 387: } ! 388: if((prog = regcomp(fld[1])) == NULL) { ! 389: fprintf(stderr, SYNTAX, l); ! 390: free((char*)prog); ! 391: return 13; ! 392: } ! 393: if(regexec(prog, srcid, mlist, MLIST_SIZE) == 0) ! 394: continue; ! 395: if((log = fopen(fld[2], "a")) == NULL) { ! 396: fprintf(stderr, "Can't open log file %s\n", fld[2]); ! 397: return 20; ! 398: } ! 399: } else if(strcmp(fld[0], "secidmap") == 0) { ! 400: if(i != 3) { ! 401: fprintf(stderr, SYNTAX, l); ! 402: return 14; ! 403: } ! 404: sp = (struct secmap*) malloc(sizeof(struct secmap)); ! 405: if(strcmp(fld[1], ".*") == 0) ! 406: seen_defmap = 1; ! 407: else if(seen_defmap) { ! 408: fprintf(stderr, "authmgr: Warning; default secidmap is not last secidmap at line %d\n", l); ! 409: free((char *)sp); ! 410: continue; ! 411: } ! 412: if((sp->prog = regcomp(fld[1])) == NULL) { ! 413: fprintf(stderr, SYNTAX, l); ! 414: free((char *)sp); ! 415: return 15; ! 416: } ! 417: if(slp == 0) ! 418: slp = secidlist = sp; ! 419: else { ! 420: slp->next = sp; ! 421: slp = sp; ! 422: } ! 423: slp->secid = strdup(fld[2]); ! 424: slp->next = NULL; ! 425: } else { ! 426: fprintf(stderr, SYNTAX, l); ! 427: return 16; ! 428: } ! 429: } ! 430: if(!seen_defmap) { ! 431: fprintf(stderr, "authmgr: No default ID configured. Help!\n"); ! 432: return 17; ! 433: } ! 434: if(!dconflg && !gnotflg) { ! 435: struct tchars tcbuf; ! 436: extern int tty_ld; ! 437: /* make sure interface is usable by humans */ ! 438: if(ioctl(0, TIOCGETC, &tcbuf) < 0) { ! 439: /* no tty ld (of any type) present; push one */ ! 440: if(ioctl(0, FIOPUSHLD, &tty_ld) < 0) ! 441: printf("No tty processing supported; sorry\n"); ! 442: pushed_ld++; ! 443: } ! 444: } ! 445: return 0; ! 446: } ! 447: ! 448: char* ! 449: makesourceid() ! 450: { ! 451: static char sbuf[128]; ! 452: struct secmap *sp = secidlist; ! 453: ! 454: while(sp != NULL) { ! 455: if(regexec(sp->prog, srcid, mlist, MLIST_SIZE) != 0) { ! 456: sprintf(sbuf, "%s.%s", sp->secid, physource); ! 457: return sbuf; ! 458: } ! 459: sp = sp->next; ! 460: } ! 461: } ! 462: ! 463: readnoecho(rbuf, n) ! 464: char *rbuf; ! 465: int n; ! 466: { ! 467: struct sgttyb sg, noecho; ! 468: int failed = 0; ! 469: ! 470: failed = ioctl(0, TIOCGETP, &sg); ! 471: if(failed >= 0) { ! 472: noecho = sg; ! 473: noecho.sg_flags &= ~ECHO; ! 474: ioctl(0, TIOCSETP, &noecho); ! 475: } ! 476: safegets(rbuf, n); ! 477: if(failed >= 0) ! 478: ioctl(0, TIOCSETP, &sg); ! 479: } ! 480: ! 481: void ! 482: regerror(msg) ! 483: char *msg; ! 484: { ! 485: fprintf(stderr, "authmgr: %s\n", msg); ! 486: return; ! 487: } ! 488: ! 489: #include <utsname.h> ! 490: ! 491: /* ! 492: * doadmin - ! 493: * do whatever administrative muck is necessary when a login ! 494: * fails to authenticate itself after max_failures tries. ! 495: */ ! 496: doadmin(logname) ! 497: char* logname; ! 498: { ! 499: char buf[256]; ! 500: FILE* f; ! 501: struct utsname un; ! 502: ! 503: if (log != NULL) { ! 504: lognow(); ! 505: fprintf(log, "%s %s (%s) failed\n", ! 506: srcid, username, eusername); ! 507: fclose(log); ! 508: } ! 509: ! 510: (void) uname(&un); ! 511: sprintf(buf, "/bin/mail %s", admins); ! 512: if((f = popen(buf, "w")) == NULL) ! 513: return; /* XXX */ ! 514: ! 515: fprintf(f, "\ ! 516: Subject: security alert from server %s\n\ ! 517: \n\ ! 518: The login(s) ``%s'' failed to correctly authenticate\n\ ! 519: itself after %d consecutive attempts.\n\ ! 520: The source of the attempts was:\n\ ! 521: %s\n\ ! 522: Recommendation: disable and investigate the login(s).\n", ! 523: un.nodename, logname, max_failures, getenv("CSOURCE")); ! 524: ! 525: (void) pclose(f); ! 526: } ! 527: ! 528: ! 529: /* ! 530: * a safe version of gets ! 531: */ ! 532: safegets(bp, n) ! 533: char *bp; ! 534: int n; ! 535: { ! 536: char *cp; ! 537: ! 538: if(fgets(bp, n, stdin)==NULL) ! 539: return NULL; ! 540: for(cp=bp; *cp; cp++) ! 541: if(*cp=='\r' || *cp =='\n'){ ! 542: *cp = 0; ! 543: break; ! 544: } ! 545: return bp; ! 546: } ! 547: ! 548: lognow() ! 549: { ! 550: struct tm *now; ! 551: long seconds; ! 552: ! 553: (void) time(&seconds); ! 554: now = localtime(&seconds); ! 555: fprintf(log, "%02d/%02d %02d:%02d:%02d ", ! 556: now->tm_mon+1, now->tm_mday, ! 557: now->tm_hour, now->tm_min, now->tm_sec); ! 558: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.