/***************************************************************************/ /* Module: $Id: kbauth.c,v 1.5 1999/05/07 04:15:25 maf Exp $ /* Description: KarlBridge authentication system /* Author: maf /* Notes: /***************************************************************************/ /* $Log: */ #include "kbauth.h" #include #include #include #include #include #include #include #include int debugLevel; int debug; /* snmp debug */ main(argc, argv) int argc; char **argv; { struct KbRemAuthDatabase db[MAXAUTHRECORDS]; int serviceNo; u_long ourIP; struct sockaddr_in sin; struct in_addr inaddr, inaddr2; int sval; extern int optind, opterr; extern char *optarg; char c; int loginMode, action; int doLogging; char userName[255]; struct KBridgeAuthenRecord auth; struct hostent *hostptr; char tmpBuf[255]; void AlarmHand(); int ret; /* no exiting or suspending */ signal (SIGQUIT, SIG_IGN); signal (SIGINT, SIG_IGN); signal (SIGTSTP, SIG_IGN); /* limit login time to 2 minutes */ signal (SIGALRM, AlarmHand); alarm(120); doLogging = DEFLOGLEVEL; debugLevel = 0; while ((c = getopt(argc, argv, "ld:h:p")) != -1) switch (c) { case 'd': debugLevel = atoi(optarg); break; case 'l': doLogging = 1; break; case 'h': /* handle numeric form */ if (atoi(optarg)) { ourIP = htonl(inet_addr(optarg)); break; } /* handle actual domainname */ if (!(hostptr = gethostbyname(optarg))) { fprintf(stderr, "IP Address lookup of %s\n failed\n", optarg); exit(1); } if (hostptr->h_addrtype != AF_INET) { fprintf(stderr, "Unknown address type\n"); exit(1); } /* ignore all but the first */ if (!hostptr->h_addr_list[0]) { fprintf(stderr, "Empty address list!\n"); exit(1); } bcopy(hostptr->h_addr, (char*)&inaddr, hostptr->h_length); ourIP = htonl(inaddr.s_addr); break; case 'p': /* dummy flag, it's telnetd saying don't destroy the env */ break; default: exit(1); break; } /* end switch */ openlog("kbauth", LOG_PID, LOG_LOCAL3); inaddr.s_addr = ntohl(ourIP); if (debugLevel) printf("You are %s\n", inet_ntoa(inaddr)); syslog(LOG_INFO, "CONNECT: srcIP=%s", inet_ntoa(inaddr)); /* Present a menu of choices, /* 1..x) login /* D) disconnect /* H) help /* E) exit */ /* read config */ if (ReadConfigFile(db, KBCONFPATHNAME)) { fprintf(stderr, "fatal: ReadConfigFile failed\n"); syslog(LOG_ERR, "fatal: ReadConfigFile failed\n"); exit(1); } action = 0; while (!action) { if ((ret = GetSelection(db, &serviceNo, ourIP))) { if (ret != 2) { /* no services for host */ fprintf(stderr, "fatal: GetSelection failed\n"); syslog (LOG_ERR, "fatal: GetSelection failed\n"); exit (1); } exit (0); } /* serviceNo may be 1000 + 'H' or 1000 + 'E' or 'D' + 1000 */ if (serviceNo > 1000) { if (serviceNo == (1000 + 'H')) { /* help */ DisplayHelp(); continue; } else if (serviceNo == (1000 + 'E')) { /* quit/exit */ printf ("Bye...\n"); sleep (3); exit (0); } else if (serviceNo == (1000 + 'D')) { /* disconnect/logout */ printf("\n"); if (DoLogout(db, ourIP)) fprintf(stderr, "fatal: DoLogout failed\n"); sleep (10); exit (0); } else { fprintf(stderr, "fatal: out of bounds for service\n"); syslog (LOG_ERR, "fatal: out of bounds for service\n"); exit (1); } } /* else, it's a service # to login to */ action = 1; } /* while !action */ printf("\nPlease identify yourself by entering your network username and\n"); printf("password when prompted.\n\n"); /* Authenticate */ if (AuthenticateUser(userName, sizeof(userName))) { fprintf(stderr, "Authentication failed\n"); if (doLogging) syslog(LOG_NOTICE, "Repeated LOGIN failures srcIP=%s", inet_ntoa(inaddr)); exit (1); } /* Make a log of their authentication */ if (doLogging) syslog(LOG_INFO, "LOGIN: userName=%s, service=%s", userName, db[serviceNo].serviceName); printf("\nYou are now authorized for network access. Please make sure to\n"); printf("return to this service and disconnect from network access when you\n"); printf("are finished with your network session. Indicate here that you\n"); printf("agress to disconnect to prevent abuse of network privileges.\n"); printf("\n[enter Yes or No]: "); fflush(stdout); fgets(tmpBuf, sizeof(tmpBuf), stdin); if ((strlen(tmpBuf)) && (tmpBuf[0] != 'y') && (tmpBuf[0] != 'Y')) { printf("\nWe are unable to authorize you for network access. If you need more\n"); printf("information about this service, please contact the UTS Technology\n"); printf("Support Center at 688-HELP.\n\n"); sleep (15); exit (0); } /* don't time out now... */ signal (SIGALRM, SIG_IGN); alarm(0); /* send the authentication record to the bridge */ printf("\nSending authentication request to bridge for service \"%s\".\n", db[serviceNo].serviceName); /* fill in the authentication record */ if (db[serviceNo].srcIP == 0xFFFFFFFF) db[serviceNo].srcIP = ourIP; auth.src_ipaddr[0] = (db[serviceNo].srcIP & 0xFF000000)>>24; auth.src_ipaddr[1] = (db[serviceNo].srcIP & 0x00FF0000)>>16; auth.src_ipaddr[2] = (db[serviceNo].srcIP & 0x0000FF00)>>8; auth.src_ipaddr[3] = (db[serviceNo].srcIP & 0x000000FF); if (db[serviceNo].dstIP == 0xFFFFFFFF) db[serviceNo].dstIP = ourIP; auth.dst_ipaddr[0] = (db[serviceNo].dstIP & 0xFF000000)>>24; auth.dst_ipaddr[1] = (db[serviceNo].dstIP & 0x00FF0000)>>16; auth.dst_ipaddr[2] = (db[serviceNo].dstIP & 0x0000FF00)>>8; auth.dst_ipaddr[3] = (db[serviceNo].dstIP & 0x000000FF); auth.mask[0] = (db[serviceNo].dstIPMask & 0xFF000000)>>24; auth.mask[1] = (db[serviceNo].dstIPMask & 0x00FF0000)>>16; auth.mask[2] = (db[serviceNo].dstIPMask & 0x0000FF00)>>8; auth.mask[3] = (db[serviceNo].dstIPMask & 0x000000FF); auth.timout = db[serviceNo].timeOut; inaddr2.s_addr = ntohl(db[serviceNo].bridgeIP); if (DoKBRemoteAuth(inet_ntoa(inaddr2), db[serviceNo].bridgeCommunity, auth)) { fprintf(stderr, "Unable to communicate with bridge.\n"); fprintf(stderr, "Service not enabled.\n"); syslog(LOG_ERR, "Bridge Auth Error, bridgeIP=%s", inet_ntoa(inaddr2)); sleep(5); exit(1); } /* Make a log of what service they select */ if (doLogging) syslog(LOG_INFO, "ADD: bridgeIP=%s", inet_ntoa(inaddr2)); printf("Connection will close after %lu seconds of inactivity\n\n", (u_long)db[serviceNo].timeOut); printf("\nThank you. You may start your network session now.\n"); sleep (5); return 0; } /* main */ void AlarmHand(sig, code, scp, addr) int sig, code; struct sigcontext *scp; char *addr; { printf("\nTimeout.\n"); /* TODO - prints's don'g belong in handlers */ sleep(3); exit (1); } /*********************************************************************/ /* Function: DisplayHelp /* /* Returns: 0 for good (displayed help mesage) /* !0 for bad (couldn't display help message) /* /*********************************************************************/ DisplayHelp() { printf("\n"); printf(" This service provides you access to the SONNET campus network and\n"); printf(" to the Internet, of which SONNET is a part. To avoid abuse of\n"); printf(" network privileges, it is necessary that you authenticate yourself\n"); printf(" and be authorized for network access.\n\n"); printf(" To begin, choose item number 1 and answer the prompts. Please\n"); printf(" enter the same username and password you use for Postbox or\n"); printf(" pop.service e-mail service.\n\n"); printf(" When you agree to disconnect from network access to end your\n"); printf(" network session, you are ready to begin by opening a network\n"); printf(" program for e-mail, newsreading, world wide web, file transfer\n"); printf(" or remote login. If you need further information about this\n"); printf(" service or about accessing network resources, please call the\n"); printf(" UTS Technology Support Center at 688-HELP or ask a lab assistant\n"); printf(" in your public computing site for help.\n"); printf("\nPress RETURN to return to the menu selections:\n"); if (EatLine()) return 1; return 0; } /*********************************************************************/ /* Function: EatLine /* /* Returns: 0 for good (ate up to a \n) /* !0 for bad (encountered EOF) /* /*********************************************************************/ EatLine() { int tmp; while (1) { if ((tmp = getchar()) == EOF) return 1; if (tmp == '\n') return 0; } } /*********************************************************************/ /* Function: DoLogout /* /* Returns: 0 for good (logout of all services was successful) /* 1 for bad (logout of 1 or more services failed) /* /* logouts are logged via syslog, as are failed connections to /* for logout requests to the bridge /* /*********************************************************************/ DoLogout(db, ourIP) struct KbRemAuthDatabase *db; u_long ourIP; { int x; int good = 1; /* assume the best */ struct KBridgeAuthenRecord auth; struct in_addr inaddr, inaddr2; char ipname[32]; inaddr.s_addr = ntohl(ourIP); /* for each bridge they could of loggged into, send that bridge a logout for ourIP address */ for (x = 0; db[x].ipLow != 0xFFFFFFFF; ++x) { if ((ourIP >= db[x].ipLow) && (ourIP <= db[x].ipHigh)) { /* fill in the authentication record */ auth.src_ipaddr[0] = (ourIP & 0xFF000000)>>24; auth.src_ipaddr[1] = (ourIP & 0x00FF0000)>>16; auth.src_ipaddr[2] = (ourIP & 0x0000FF00)>>8; auth.src_ipaddr[3] = (ourIP & 0x000000FF); auth.dst_ipaddr[0] = 0; auth.dst_ipaddr[1] = 0; auth.dst_ipaddr[2] = 0; auth.dst_ipaddr[3] = 0; auth.mask[0] = 0; auth.mask[1] = 0; auth.mask[2] = 0; auth.mask[3] = 0; auth.timout = 0; /* 0 to delete */ inaddr2.s_addr = ntohl(db[x].bridgeIP); strncpy(ipname, inet_ntoa(inaddr2), 31); ipname[31] = 0; fflush(stdout); if (DoKBRemoteAuth(inet_ntoa(inaddr2), db[x].bridgeCommunity, auth)) { printf("NOT Logged out of \"%s\"", db[x].serviceName); syslog(LOG_ERR, "ERROR_DEL: srcIP=%s, bridgeIP=%s", inet_ntoa(inaddr), ipname); good = 0; } else printf("Logged out of \"%s\"", db[x].serviceName); syslog(LOG_INFO, "DEL: bridgeIP=%s", inet_ntoa(inaddr2)); } /* if in range */ } /* foreach record in db */ DoLogoutout: if (good) { printf( "\n\nYou have successfully logged out of all network services. Thank\n"); printf( "you for helping us keep the network secure. Have a nice day.\n"); return 0; /* good */ } else return 1; /* bad */ }